微信小程序之生成海報並保存到本地


項目中遇到需要分享到朋友圈,但是查詢api發現小程序並沒有提供分享到朋友圈的功能,只能實現通過canvas畫一張海報然后保存到本地,讓用戶主動去發朋友圈。
效果圖生成后海報
首先使用微信小程序提供的canvasapi將第二張圖顯示的海報畫出來
然后調用保存本地的接口
wx.saveImageToPhotosAlbum({})將圖片保存在本地相冊中

wxml部分
 <view hidden='{{maskFlag==false}}'>
        <view class='mask'></view>
        <view class='shareWay'>
          <view class='selectWay'>
            <button class='weixin' open-type="share">
              <view class='wechatImg'>
                <image class='wechatIcon' src='../../images/wechat.png'></image>
              </view>
              <view class='sentFriend'>發送給好友</view>
            </button>
            <view class='middleLine'></view>
            <view class='haibao' bindtap='formSubmit'>
              <view class='posterImg'>
                <image class='posterIcon' src='../../images/haibao.png'></image>
              </view>
              <view class='createPoster'>生成海報</view>
            </view>
            <!--生成海報  -->
            <view class='imagePathBox' hidden="{{maskHidden == false}}">
              <view class='poster'>
                <image src="{{imagePath}}" class='shengcheng'></image>
              </view>
              <button class='baocun' bindtap='savePoster'>保存圖片</button>
            </view>

            <view class="canvas-box">
              <canvas style="width: 375px;height: 667px;position:fixed;top:9999px" canvas-id="mycanvas" />
            </view>
          </view>
          <view class='shareEmpty'></view>
          <view class='cancel' bindtap='cancelShare'>取消</view>
        </view>
      </view>
wxss部分
.mask {
  width: 100%;
  height: 100%;
  position: absolute;
  background-color: rgb(0, 0, 0);
  z-index: 1000;
  top: 0;
  left: 0;
  opacity: 0.5;
}

.shareWay {
  width: 750rpx;
  height: 372rpx;
  border-radius: 10rpx 10rpx 0 0;
  /* margin-bottom: 114rpx; */
  position: fixed;
  bottom: 0;
  z-index: 9999;
  background-color: #fff;
}

.selectWay {
  display: flex;
  width: 100%;
  height: 250rpx;
  justify-content: space-between;
}

.middleLine {
  /* width: 1rpx; */
  height: 80rpx;
  background: rgba(216, 216, 216, 1);
  opacity: 0.3;
  border: 1rpx solid rgba(151, 151, 151, 1);
  margin: 68rpx auto 0;
}

.weixin {
  width: 48%;
  background-color: #fff;
}

.wechatImg, .posterImg {
  width: 88rpx;
  height: 88rpx;
  margin: 53rpx auto 0;
}

.wechatIcon, .posterIcon {
  width: 100%;
  height: 100%;
  display: block;
}

.sentFriend, .createPoster {
  width: 100%;
  height: 40rpx;
  font-size: 28rpx;
  font-family: PingFangSC-Regular;
  font-weight: 400;
  color: rgba(51, 51, 51, 1);
  line-height: 40rpx;
  text-align: center;
  margin-top: 24rpx;
}

.haibao {
  width: 48%;
}

.shareEmpty {
  width: 750rpx;
  height: 14rpx;
  background: rgba(245, 247, 250, 1);
}

.cancel {
  width: 100%;
  height: 108rpx;
  font-size: 32rpx;
  font-family: PingFangSC-Regular;
  font-weight: 400;
  color: rgba(51, 51, 51, 1);
  line-height: 108rpx;
  text-align: center;
}

.imagePathBox {
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 1);
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  border-top: 2rpx solid rgba(183, 183, 183, 0.2);
  z-index: 10;
}

.poster {
  width: 670rpx;
  height: 959rpx;
  background: rgba(255, 255, 255, 1);
  position: fixed;
  left: 40rpx;
  top: 43rpx;
  right: 0;
  bottom: 0;
  border-top: 2rpx solid rgba(183, 183, 183, 0.2);
  /* box-shadow: 0px -10px 14px 0px rgba(183,183,183,0.2); */
  z-index: 10;
}

.shengcheng {
  width: 670rpx;
  height: 959rpx;
  border-radius: 12rpx;
  position: fixed;
  left: 40rpx;
  top: 43rpx;
  box-sizing: border-box;
  background-color: #fff;
  z-index: 10;
  box-shadow: 0px 10px 14px 0px rgba(194, 194, 194, 0.5);
  /* padding: 23rpx 21rpx 36rpx; */
}

.baocun {
  width: 670rpx;
  height: 88rpx;
  background: linear-gradient(90deg, rgba(255, 114, 126, 1) 0%, rgba(239, 69, 85, 1) 100%);
  box-shadow: 0px 4px 8px 0px rgba(244, 82, 98, 0.45);
  border-radius: 8rpx;
  display: block;
  padding: 0;
  line-height: 80rpx;
  text-align: center;
  position: fixed;
  bottom: 40rpx;
  left: 40rpx;
  color: #fff;
  font-size: 32rpx;
}

button[class="baocun"]::after {
  border: 0;
}

.cancelFocus {
  width: 308rpx;
  height: 114rpx;
  text-align: center;
  font-size: 32rpx;
  font-family: PingFangSC-Regular;
  font-weight: 400;
  line-height: 114rpx;
  color: #999;
}

.qrcode {
  width: 278rpx;
  height: 278rpx;
  display: block;
  margin: 0 auto;
}
js部分
// 生成海報並分享給好友
  //將canvas轉換為圖片保存到本地,然后將圖片路徑傳給image圖片的src
  createNewImg: function() {
    var that = this;
    // console.log(that.data.qrcode)
    var context = wx.createCanvasContext('mycanvas');
    context.setFillStyle("#ffffff")
    context.fillRect(0, 0, 670, 959)
    var path = that.data.MainImages;
    //將模板圖片繪制到canvas,在開發工具中drawImage()函數有問題,不顯示圖片
    context.drawImage(path, 16, 14, 344, 425);
    var path1 = that.data.brandImg;
    //將模板圖片繪制到canvas,在開發工具中drawImage()函數有問題,不顯示圖片
    var path2 = "/images/middle.png";
    var path3 = that.data.brandImg;
    // var path3 = '../../images/poster.png';
    var path4 = that.data.qrcode;
    var path5 = "/images/zhiwen.png";
    //不知道是什么原因,手機環境能正常顯示
    context.save(); // 保存當前context的狀態

    //繪制品牌頭像
    context.drawImage(path3, 20, 507, 70, 80);
    //繪制商品對應的品牌名稱
    context.setFontSize(18);
    context.setFillStyle('#000000');
    context.setTextAlign('left');
    context.fillText(that.data.Name, 92, 525);
    context.stroke();
    //繪制掃碼即可查看商品更多信息
    context.drawImage(path4, 245, 500, 115, 125); //二維碼
    context.setFontSize(14);
    context.setFillStyle('#A0A0A0');
    context.setTextAlign('left');
    context.fillText(that.data.scan, 65, 618);
    context.stroke();
    //繪制商品
    context.drawImage(path5, 25, 600, 26, 24);
    context.stroke();
    context.setFontSize(18);
    context.setFillStyle('#000000');
    context.setTextAlign('left');
    context.fillText(that.data.goodsObj.Name, 92, 570);
    context.stroke();
    //繪制中間分割線
    context.drawImage(path2, -8, 455, 390, 45);
    context.draw(true, setTimeout(function() {
      //將生成好的圖片保存到本地,需要延遲一會,繪制期間耗時
      wx.canvasToTempFilePath({
        x: 0,
        y: 0,
        width: 670,
        height: 959,
        destWidth: 2010,
        destHeight: 2877,
        canvasId: 'mycanvas',
        success: function(res) {
          var tempFilePath = res.tempFilePath;
          that.setData({
            imagePath: tempFilePath,
            canvasHidden: true
          });
        },
        fail: function(res) {
          console.log(res);
        }
      });
    }, 200));
  },

  //點擊保存到相冊
  savePoster: function() {
    var that = this
    console.log(that.data.imagePath)
    wx.saveImageToPhotosAlbum({
      filePath: that.data.imagePath,
      success(res) {
        wx.showModal({
          content: '海報已保存到相冊',
          showCancel: false,
          confirmText: '好的',
          confirmColor: '#333',
          success: function(res) {
            if (res.confirm) {
              console.log('999999')
              console.log('用戶點擊確定');
              /* 該隱藏的隱藏 */
              that.setData({
                maskHidden: false
              })
            }
          },
          fail: function(res) {
            console.log(11111)
          }
        })
      },
      fail(res) {
        // wx.showToast({
        //   title: '保存失敗',
        //   icon: 'none',
        // })
        if (res.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || res.errMsg === "saveImageToPhotosAlbum:fail auth deny") {
          // 這邊微信做過調整,必須要在按鈕中觸發,因此需要在彈框回調中進行調用
          wx.showModal({
            title: '提示',
            content: '需要您授權保存相冊',
            showCancel: false,
            success: modalSuccess => {
              wx.openSetting({
                success(settingdata) {
                  console.log("settingdata", settingdata)
                  if (settingdata.authSetting['scope.writePhotosAlbum']) {
                    wx.showModal({
                      title: '提示',
                      content: '獲取權限成功,再次點擊圖片即可保存',
                      showCancel: false,
                    })
                  } else {
                    wx.showModal({
                      title: '提示',
                      content: '獲取權限失敗,將無法保存到相冊哦~',
                      showCancel: false,
                    })
                  }
                },
                fail(failData) {
                  console.log("failData", failData)
                },
                complete(finishData) {
                  console.log("finishData", finishData)
                }
              })
            }

          })
        }
      }
    })
  },
  //點擊生成
  formSubmit: function(e) {

    var that = this;
    this.setData({
      maskHidden: false
    });
    wx.showToast({
      title: '海報生成中...',
      icon: 'loading',
      duration: 1000
    });
    setTimeout(function() {
      wx.hideToast()
      that.createNewImg();
      that.setData({
        maskHidden: true
      });
    }, 1000)
  },

  //適配不同屏幕大小的canvas
  getQRCodeSize: function() {
    var size = 0;
    try {
      var res = wx.getSystemInfoSync();
      var scale = 750 / 278; //不同屏幕下QRcode的適配比例;設計稿是750寬
      var width = res.windowWidth / scale;
      size = width;

    } catch (e) {
      // Do something when catch error
      // console.log("獲取設備信息失敗"+e);
    }
    return size;
  },
  createQRCode: function(text, size) {
    //調用插件中的draw方法,繪制二維碼圖片

    let that = this

    // console.log('QRcode: ', text, size)
    let _img = QR.createQrCodeImg(text, {
      size: parseInt(size)
    })
    // let qucode = that.data.qucode;
    // qucode=_img
    that.setData({
      'qrcode': _img
    })
    console.log('商品二維碼----->', that.data.qrcode,that.data.qrcode.length)    
    
    // 處理二維碼成本地圖片
   
    base64src(that.data.qrcode, res => {
      console.log(res) // 返回圖片地址,直接賦值到image標簽即可
      that.setData({
        'qrcode': res
      })
    });
   
  },

(二維碼的處理見下一篇)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM