微信小程序實現九宮格切圖,保存功能!

效果以下圖:canvas

 

代碼以下:app

<view class='sudoku'>
  <scroll-view scroll-x scroll-y class='canvas-box'>
    <canvas canvas-id='canvasIn' id='canvas' class='canvas canvas-in' style='{{canvasWH}}'></canvas>
    <!-- wx:if='{{canvasIn}}' -->
    <!-- <canvas canvas-id='canvasOut' id='canvasOut' class='canvas canvas-out' style='{{canvasWH}}'></canvas> -->
  </scroll-view>
  <cover-view class='imgs'>
    <cover-view class='imgs-box'>
      <cover-image class='img' data-idx='{{index+1}}' src='{{item}}' style='{{maxHeight}}' wx:for='{{imgUrls}}' wx:key='{{index}}' bindtap='saveImg'></cover-image>
    </cover-view>
  </cover-view>
  <cover-view class='btns-box'>
    <button bindtap='uploadImg' class='btn btn-cut'>上傳</button>
    <button bindtap='saveAll' class='btn btn-save'>保存</button>
  </cover-view>
</view>
let _this Page({ /** * 頁面的初始數據 */ data: { canvasWH: '', imgW: 0, imgH: 0, uploadFlag: false, imgUrls: [], maxHeight: '' }, /* 上傳圖片 */ uploadImg() { const query = wx.createSelectorQuery() query.select('#canvas').boundingClientRect(function(res) { wx.chooseImage({ count: 1, sizeType: ['original', 'compressed'], // sizeType: ['compressed'],
        sourceType: ['album', 'camera'], success(res) { // 圖片大小限制爲 最大2M
          const imgSize = res.tempFiles[0].size console.log(res, imgSize, '已選擇圖片大小') if (imgSize > 1000000) { wx.showModal({ title: '舒適提示', content: '圖片最大不能超過1M', showCancel: false }) return } const ctx = wx.createCanvasContext('canvasIn') const canvasW = res.width const canvasH = res.height ctx.fillStyle = '#fff' ctx.fillRect(0, 0, canvasW, canvasH) ctx.draw() // 獲取圖片信息
 wx.getImageInfo({ src: res.tempFilePaths[0], success(imgInfo) { console.log(imgInfo, 'imgInfo') const imgW = imgInfo.width const imgH = imgInfo.height _this.setData({ canvasWH: `width: ${imgW}px;height: ${imgH}px`, imgW, imgH }) // 獲取圖片的大小
              ctx.drawImage(res.tempFilePaths[0], 0, 0, imgW, imgH) ctx.draw() // 展現新圖片
 _this.showMiniImg() }, fail(err) { console.log(err, '圖片信息獲取失敗') wx.showModal({ title: '舒適提示', content: '暫不支持此圖片格式', showCancel: false }) } }) }, fail (err) { console.log(err, '圖片選擇失敗') } }) }) query.exec() }, /* 展現小圖 */ showMiniImg() { let x = 0 let y = 0 let count = 0 let imgUrls = [] const { imgW, imgH } = _this.data const cutW = imgW / 3 const cutH = imgH / 3 const cfgSave = { x: 0, y: 0, width: cutW, height: cutH, destWidth: cutW, destHeight: cutH, canvasId: 'canvasIn' } _this.cutFlag = true const timer = setInterval(() => { if (_this.cutFlag) { _this.cutFlag = false console.log(count, 'cutFlag') switch (count) { case 0: x = 0 y = 0
            break
          case 1: x = 1 y = 0
            break
          case 2: x = 2 y = 0
            break
          case 3: x = 0 y = 1
            break
          case 4: x = 1 y = 1
            break
          case 5: x = 2 y = 1
            break
          case 6: x = 0 y = 2
            break
          case 7: x = 1 y = 2
            break
          case 8: x = 2 y = 2
            break
          default: break } cfgSave.x = cutW * x cfgSave.y = cutH * y wx.canvasToTempFilePath({ ...cfgSave, success(res) { console.log(res, '剪切') _this.cutFlag = true count++ wx.showLoading({ title: `裁剪中 ${count}/9`,
              mask: true }) imgUrls.push(res.tempFilePath) if (count == 9) { if (imgUrls.length < 9) { imgUrls = [] cut() return } wx.hideLoading() _this.setData({ uploadFlag: true, imgUrls }) clearInterval(timer) } }, fail (err) { console.log(err , '剪切圖片失敗') } }) } }, 100) }, /* 保存圖片(單圖 / 全部) */ saveImgHandle(e) { const { imgW, imgH, imgUrls } = _this.data const cutW = imgW / 3 const cutH = imgH / 3 const cfgSave = { x: 0, y: 0, width: cutW, height: cutH, destWidth: cutW, destHeight: cutH, canvasId: 'canvasIn', } if (e) { //保存單張圖片
      switch (e.currentTarget.dataset.idx) { case 1: cfgSave.x = cutW * 0 cfgSave.y = cutH * 0
          break
        case 2: cfgSave.x = cutW * 1 cfgSave.y = cutH * 0
          break
        case 3: cfgSave.x = cutW * 2 cfgSave.y = cutH * 0
          break
        case 4: cfgSave.x = cutW * 0 cfgSave.y = cutH * 1
          break
        case 5: cfgSave.x = cutW * 1 cfgSave.y = cutH * 1
          break
        case 6: cfgSave.x = cutW * 2 cfgSave.y = cutH * 1
          break
        case 7: cfgSave.x = cutW * 0 cfgSave.y = cutH * 2
          break
        case 8: cfgSave.x = cutW * 1 cfgSave.y = cutH * 2
          break
        case 9: cfgSave.x = cutW * 2 cfgSave.y = cutH * 2
          break
        default: break } wx.canvasToTempFilePath({ ...cfgSave, success(res) { wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success(resPhoto) { wx.showToast({ title: '保存成功' }) } }) } }) } else { //保存全部
      let pathArr = [] let x = 0 let y = 0 let count = 0 _this.saveFlag = true const timer = setInterval(() => { if (_this.saveFlag) { _this.saveFlag = false console.log(count, 'saveFlag') switch (count) { case 0: x = 0 y = 0
              break
            case 1: x = 1 y = 0
              break
            case 2: x = 2 y = 0
              break
            case 3: x = 0 y = 1
              break
            case 4: x = 1 y = 1
              break
            case 5: x = 2 y = 1
              break
            case 6: x = 0 y = 2
              break
            case 7: x = 1 y = 2
              break
            case 8: x = 2 y = 2
              break
            default: break } cfgSave.x = cutW * x cfgSave.y = cutH * y wx.canvasToTempFilePath({ ...cfgSave, success(res) { console.log(res, '保存全部') pathArr.push(res.tempFilePath) count++ wx.showLoading({ title: `保存中${count}/9`,
 }) _this.saveFlag = true
              if (count == 9) { clearInterval(timer) console.log(pathArr) // 保存到相冊
                for (let i = 0; i < pathArr.length; i++) { wx.saveImageToPhotosAlbum({ filePath: pathArr[i], success(resPhoto) { _this.saveFlag = true
                      if (i == pathArr.length - 1) { wx.hideLoading() wx.showToast({ title: '保存成功' }) } } }) } } } }) } }, 100) } }, /* 保存單張圖片 */ saveImg(e) { const { uploadFlag } = _this.data // 判斷是否已上傳圖片
    if (uploadFlag) { wx.showModal({ title: '舒適提示', content: '要將該圖片保存到相冊嗎?', success(confirm) { if (confirm.confirm) { _this.photoAuthorization(e) } } }) } else { wx.showModal({ title: '舒適提示', content: '請先上傳圖片', showCancel: false }) } }, /* 一鍵保存 */ saveAll() { const { uploadFlag } = _this.data // 判斷是否已上傳圖片
    if (uploadFlag) { _this.photoAuthorization() } else { wx.showModal({ title: '舒適提示', content: '請先上傳圖片', showCancel: false }) } }, /* 設置顯示圖片的最大高度爲屏幕高 */ setMaxHeight() { wx.getSystemInfo({ success: function(res) { console.log(res) const windowH = res.windowHeight const maxHeight = parseInt(windowH / 3) _this.setData({ maxHeight: `max-height: ${maxHeight}px` }) }, }) }, /* 相冊受權 */ photoAuthorization(event) { wx.getSetting({ success(res) { if (res.authSetting['scope.writePhotosAlbum']) { // 已受權
          if (event) { _this.saveImgHandle(event) } else { _this.saveImgHandle() } } else { wx.authorize({ scope: 'scope.writePhotosAlbum', success() { // 已受權
              if (event) { _this.saveImgHandle(event) } else { _this.saveImgHandle() } }, fail() { // 未受權
 wx.showModal({ title: '舒適提示', content: '須要獲取相冊權限', success(resOpenSetting) { if (resOpenSetting.confirm) { wx.openSetting({ success(res) { if (res.authSetting['scope.writePhotosAlbum']) { // 已受權
                          if (event) { _this.saveImgHandle(event) } else { _this.saveImgHandle() } } else { wx.showModal({ title: '舒適提示', content: '未獲取到受權信息', showCancel: false }) } } }) } } }) } }) } } }) }, /** * 生命週期函數--監聽頁面加載 */ onLoad: function(options) { _this = this _this.setMaxHeight() }, /** * 生命週期函數--監聽頁面初次渲染完成 */ onReady: function() { }, /** * 生命週期函數--監聽頁面顯示 */ onShow: function() { }, /** * 生命週期函數--監聽頁面隱藏 */ onHide: function() { }, /** * 生命週期函數--監聽頁面卸載 */ onUnload: function() { }, /** * 頁面相關事件處理函數--監聽用戶下拉動做 */ onPullDownRefresh: function() { }, /** * 頁面上拉觸底事件的處理函數 */ onReachBottom: function() { }, /** * 用戶點擊右上角分享 */ onShareAppMessage: function() { } })
page { height: 100%; background-color: #fff; overflow: hidden; } .sudoku { height: 100%; } .canvas-box { position: relative; width: 100%; height: 100%; overflow: auto; } .canvas { min-width: 100%; height: 100%; position: absolute; top: 0; } .canvas-in { z-index: 0; } .canvas-out { z-index: 99; background-color: #fff; } .imgs{ width: 100%; height: 100%; position: absolute; top: 0; z-index: 999; background-color: #fff; } .imgs-box{ width: 100%; display: flex; justify-content: center; align-items: center; flex-wrap: wrap; padding: 8rpx; box-sizing: border-box; } .img{ flex-shrink: 0; width: 33.3%; padding: 5rpx; box-sizing: border-box; } .btns-box { position: fixed; right: 30rpx; bottom: 120rpx; z-index: 999; display: flex; justify-content: space-evenly; flex-direction: column; height: 300rpx; } .btn { color: #fff; width: 100rpx; height: 100rpx; border: none; border-radius: 50%; } .wx-button-cover-view-wrapper { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; } .wx-button-cover-view-inner { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; } .btn::after { border: none; } .btn-cut { background-color: rgba(44, 42, 165, 0.5); } .btn-save { background-color: rgba(200, 240, 56, 0.5); }
相關文章
相關標籤/搜索