006-小程序圖片滑動(dòng)次伶、縮放加canvas打印

一:這段時(shí)間一直在學(xué)習(xí)微信小程序柱彻,近期也多有遇到小程序有關(guān)于圖片與canvas的坑骂澄,

二:說(shuō)明一下需求吧:首先要有兩張圖片,其中一張中間部分是透明的圖片A,另一張是完整的圖片B统刮;現(xiàn)在圖片A在上面匀奏,圖片B在下面,當(dāng)手指在圖片A上移動(dòng)時(shí),圖片B要跟著移動(dòng),同時(shí)還要做到可以雙指縮放;在調(diào)整好位置之后,還要用canvas把完成的結(jié)果圖片打印出來(lái);

三:解決問(wèn)題:

1:頁(yè)面布局

//移動(dòng)的事件最好還是用catch來(lái)
//因?yàn)樾〕绦蚧卣{(diào)的參數(shù)是用px來(lái)計(jì)算的,所以這里就不用rpx了,如果一定要用,請(qǐng)做好不同手機(jī)的適配
<view class='img' catchtouchstart='touchstart' catchtouchmove='touchmove' catchtouchend='touchend'>
  <image mode='aspectFill' class='img zIndex' src='{{圖片A}}'></image>
//這里想用margin用margin,想用top饼记、left就用top、left,感覺(jué)是一樣的,transform應(yīng)該也可以,
  <image style='margin-left:{{marginLeft}}px;margin-top:{{marginTop}}px;height:{{imgHeight}}px;width:{{imgWidth}}px' src='{{圖片B}}' class='img'></image>
</view>
.img{
  height: 100vh;
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  box-sizing: border-box
}
.zIndex{
  z-index: 5
}

2:移動(dòng),縮放的方法

// 開(kāi)始點(diǎn)擊
    touchstart(e) {
      this.setData({
        lastTouchPoint: { x: 0, y: 0 },
        oldDist: 0
      })
    },
    /**
     * 計(jì)算x軸上的雙指中心點(diǎn)比例
     */
    _calcXRatio: function (event) {
      let xRatio = ((event.touches[0].clientX + event.touches[1].clientX) / 2 - this.data.marginLeft) / this.data.imgWidth
      return xRatio
    },
    /**
     * 計(jì)算y軸上的雙指中心點(diǎn)比例
     */
    _calcYRatio: function (event) {
      let yRatio = ((event.touches[0].clientY + event.touches[1].clientY) / 2 - this.data.marginTop) / this.data.imgHeight
      return yRatio
    },
    //移動(dòng)和放大
    _zoom: function (f, event) {
      let xRatio = this._calcXRatio(event)
      let yRatio = this._calcYRatio(event)
      let maxMultiple = this.data.maxMultiple
      let minMultiple = this.data.minMultiple
      //minMultiple是最小倍數(shù),可以自己設(shè)置
      if (this.data.imgWidth <= this.data.windowWidth * minMultiple && f < 1) {
        let ratio = this.data.windowWidth / this.data.imgWidth
        this.setData({
          imgWidth: this.data.imgWidth * ratio * minMultiple,
          imgHeight: this.data.imgHeight * ratio * minMultiple
        })
        return;
      }
      if (this.data.imgHeight <= this.data.view_height * minMultiple && f < 1) {
        let ratio = this.data.view_height / this.data.imgHeight
        this.setData({
          imgWidth: this.data.imgWidth * ratio * minMultiple,
          imgHeight: this.data.imgHeight * ratio * minMultiple
        })
        return;
      }
      //maxMultiple是最大倍數(shù)薛窥,可以自己設(shè)置
      if (this.data.imgWidth >= this.data.windowWidth * maxMultiple && f > 1) {
        let ratio = this.data.windowWidth / this.data.imgWidth
        this.setData({
          imgWidth: this.data.imgWidth * ratio * maxMultiple,
          imgHeight: this.data.imgHeight * ratio * maxMultiple,
        })
        return;
      }
      if (this.data.imgHeight >= this.data.windowHeight * maxMultiple && f > 1) {
        let ratio = this.data.windowHeight / this.data.imgHeight
        this.setData({
          imgWidth: this.data.imgWidth * ratio * maxMultiple,
          imgHeight: this.data.imgHeight * ratio * maxMultiple,
        })
        return;
      }
      this.setData({
        //此處的ratio為雙指中心點(diǎn)在圖片的百分比
        marginLeft: this.data.marginLeft + xRatio * this.data.imgWidth * (1 - f),
        marginTop: this.data.marginTop + yRatio * this.data.imgHeight * (1 - f),
        imgWidth: this.data.imgWidth * f,
        imgHeight: this.data.imgHeight * f,
      })
    },

    _spacing: function (event) {
      let x = event.touches[0].clientX - event.touches[1].clientX;
      let y = event.touches[0].clientY - event.touches[1].clientY;
      return Math.sqrt(x * x + y * y);
    },
    //移動(dòng)距離
    touchmove(e) {
      let moveX = e.changedTouches[0].clientX
      let moveY = e.changedTouches[0].clientY
      let oldDist = this.data.oldDist;
      let newDist = this.data.newDist;
      let lastTouchPoint = this.data.lastTouchPoint
      //單指移動(dòng)事件
      if (e.touches.length == 1) {
        if (lastTouchPoint.x == 0 && lastTouchPoint.y == 0) {
          lastTouchPoint.x = e.touches[0].clientX
          lastTouchPoint.y = e.touches[0].clientY
          this.setData({
            lastTouchPoint,
          })
        } else {
          let xOffset = e.touches[0].clientX - lastTouchPoint.x
          let yOffset = e.touches[0].clientY - lastTouchPoint.y
          lastTouchPoint.x = e.touches[0].clientX
          lastTouchPoint.y = e.touches[0].clientY
          this.setData({
            marginTop: this.data.marginTop + yOffset,
            marginLeft: this.data.marginLeft + xOffset,
            lastTouchPoint
          })
        }
      } else if (e.touches.length == 2) {
        if (oldDist == 0) {
          oldDist = this._spacing(e);
          this.setData({
            oldDist
          })
        } else {
          newDist = this._spacing(e);
          if (newDist > oldDist + 1) {
            this._zoom(newDist / oldDist, e);
            oldDist = newDist;
            this.setData({
              oldDist,
              newDist
            })
          }
          if (newDist < oldDist - 1) {
            this._zoom(newDist / oldDist, e);
            oldDist = newDist;
            this.setData({
              oldDist,
              newDist
            })
          }
        }
      }

    },
    //移動(dòng)結(jié)束
    touchend(e) {
    //移動(dòng)結(jié)束這個(gè)方法可以根據(jù)自己的需求來(lái)做,不是必要的
    },

3:重頭戲來(lái)了,圖片的canvas打印,有些人會(huì)說(shuō)如果想用canvas打印你干嘛前面不用canvas來(lái)寫(xiě)呢;這里有個(gè)問(wèn)題,canvas上面如果想加?xùn)|西只能加cover-view,但是cover-view有各種限制和不足,所以當(dāng)你加的東西不影響到最后生成的圖的時(shí)候可以用用這個(gè),其他的確實(shí)直接canvas簡(jiǎn)單方便

    //  因?yàn)閏anvas用的也是px镇防,如果前面用其他單位的話(huà),記得換算
    let backImgWidth = this.data.backImgWidth//圖片A的寬度
    let backImgHeight = this.data.backImgHeight//圖片A的高度
    let imgWidth = this.data.imgWidth//圖片B的寬度
    let imgHeight = this.data.imgHeight//圖片B的高度
    let windowWidth = this.data.windowWidth//手機(jī)屏的寬度
    let windowHeight = this.data.windowHeight//手機(jī)屏的高度
    let marginTop = this.data.marginTop
    let marginLeft = this.data.marginLeft
    let that = this
    //因?yàn)槠聊坏拈L(zhǎng)寬比實(shí)在是太多了胃榕,而且為了圖片不變形,一般都會(huì)用裁剪的功能,所以,我們要知道這里圖片A到底被裁了多少
    let distance = backImgHeight * windowWidth / backImgWidth - windowHeight 
    //現(xiàn)在基本就是繪圖了
   const ctx = wx.createCanvasContext('img')
    //花型圖片因?yàn)榈讏D片裁剪,所以還有一段裁剪掉的對(duì)上距離要加上
    ctx.drawImage(圖片B, marginLeft, marginTop + distance/2, imgWidth, imgHeight)
    //底圖片高度應(yīng)為會(huì)自定義縮放换淆,所以必須在這里就將圖片按比例算好大小
    ctx.drawImage('圖片A', 0, 0 , windowWidth, backImgHeight * e.windowWidth / backImgWidth)
    //生成圖片是要把裁剪掉的距離給去掉的同時(shí),高度也要和前面的一樣
    //這里要用false,用true會(huì)保留原來(lái)的圖片樣式,那就有的玩了
    ctx.draw(false, (e) => {
      wx.canvasToTempFilePath({
        x: 0,
        y: distance / 2,
        width: windowWidth,
        height: windowHeight ,
        destWidth: windowWidth,
        destHeight: windowHeight,
        canvasId: 'img',
        success: (res) => {
          //圖片生成成功了
          console.log(res)
        },
        fail:(res)=>{
          console.log(res)
        }
      }, that)
    })
   //對(duì)了還留了一個(gè)坑梆砸,小程序你想要canvas正常使用狮暑,你就必須在布局的時(shí)候給它位置;
   //還有canvas的canvas-id一定要和打印的一樣
   <canvas class='canvas' canvas-id='img'></canvas>

這樣以來(lái)算可以正常使用

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贰剥,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)迟赃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事茵臭∮酰” “怎么了宜岛?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)麦萤。 經(jīng)常有香客問(wèn)我涝滴,道長(zhǎng)韩脏,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮报辱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逐工。我一直安慰自己哈扮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布须床。 她就那樣靜靜地躺著膝捞,像睡著了一般混坞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宇植,一...
    開(kāi)封第一講書(shū)人閱讀 51,274評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音腰懂,去河邊找鬼绣溜。 笑死底哗,一個(gè)胖子當(dāng)著我的面吹牛前标,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼镊讼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起平夜,我...
    開(kāi)封第一講書(shū)人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蝶棋,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后忽妒,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體玩裙,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年锰扶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寝受。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡坷牛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出很澄,到底是詐尸還是另有隱情京闰,我是刑警寧澤颜及,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站蹂楣,受9級(jí)特大地震影響俏站,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜痊土,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一肄扎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赁酝,春花似錦犯祠、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至隙袁,卻和暖如春痰娱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背菩收。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工梨睁, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坛梁。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓而姐,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親划咐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拴念,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,095評(píng)論 25 707
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線(xiàn)程,因...
    小菜c閱讀 6,404評(píng)論 0 17
  • 專(zhuān)業(yè)考題類(lèi)型管理運(yùn)行工作負(fù)責(zé)人一般作業(yè)考題內(nèi)容選項(xiàng)A選項(xiàng)B選項(xiàng)C選項(xiàng)D選項(xiàng)E選項(xiàng)F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚(yú)閱讀 8,988評(píng)論 0 13
  • 這一篇是接著自己造輪子--一款實(shí)用的Android廣告欄實(shí)現(xiàn)過(guò)程(一)寫(xiě)的褐缠,沒(méi)看過(guò)的先看上一篇政鼠,在上一篇中我提到對(duì)...
    dongjunkun閱讀 4,506評(píng)論 20 48
  • 酒店組織的春游,該在了4.1队魏。這是個(gè)特別的日子公般,愚人節(jié),復(fù)活節(jié)胡桨,張國(guó)榮逝世紀(jì)念日官帘,林微因逝世紀(jì)念日。 8點(diǎn)前吃過(guò)早...
    Summe_Chen閱讀 504評(píng)論 0 1