前言:2.9.0 起支持一套新 Canvas 2D 接口(需指定 type 属性),同时支持同层渲染,原有接口不再维护

参考文档:https://developers.weixin.qq.com/miniprogram/dev/component/canvas.html

 

<!-- 海报 -->
<view catchtouchmove="preventTouchMove" class="canvasMain" hidden="{{!posterDatas.show}}">
  <canvas type="2d" id="firstCanvas" class="firstCanvas" style="width:{{posterDatas.width}}px;height:{{posterDatas.height}}px;"></canvas>
  <button wx:if="{{posterDatas.buttonType==1}}" class='button' bindtap='onDownloadImges'>点击保存,分享朋友圈</button>
  <button wx:if="{{posterDatas.buttonType==2}}" class='button'>已保存到相册,快去分享吧</button>
  <button wx:if="{{posterDatas.buttonType==3}}" class='button' open-type='openSetting' bindopensetting='onBindOpenSetting'>进入设置页,开启“保存到相册”</button>
  <image bindtap='onIsCanvas' class='x' src='/pages/images/x3.png'></image>
</view>

<view class="canvas2d" catchtap='onBuildPosterSaveAlbum'>立即生成</view>
page {
  background-color: #fff;
}

/* 海报 */
.canvasMain {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  align-content: center;
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.6);
  z-index: 9999;
}

.canvasMain canvas {
  margin-bottom: 40px;
}

.canvas2d {
  width: 300rpx;
  height: 80rpx;
  font-size: 28rpx;
  color: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2rpx solid #000;
  margin: 0 auto;
}
.canvasMain .button {
  height: 80rpx;
  width: 600rpx;
  background-color: rgba(0, 0, 0, 0.3);
  border-radius: 40px;
  color: #fff;
  font-size: 16px;
  line-height: 80rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

.canvasMain .x {
  width: 15px;
  height: 15px;
  margin-top: 10px;
  border: solid 2px #fff;
  border-radius: 50%;
  padding: 10px;
}

// pages/huabu/huabu.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    //海报
    posterDatas: {
      width: 300, //画布宽度
      height: 350, //画布高度
      // 缓冲区,无需手动设定
      pic: null,
      buttonType: 1,
      show: false, // 显示隐藏海报弹窗
      success: false, // 是否成功生成过海报
      canvas: null, // 画布的节点
      ctx: null, // 画布的上下文
      dpr: 1, // 设备的像素比
    },
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    var that = this;
    //生成海报初始化
    var posterDatas = that.data.posterDatas
    const query = wx.createSelectorQuery()
    query.select('#firstCanvas').fields({
        node: true,
        size: true
      },
      function (res) {
        const canvas = res.node
        const ctx = canvas.getContext('2d')
        const dpr = wx.getSystemInfoSync().pixelRatio
        canvas.width = posterDatas.width * dpr
        canvas.height = posterDatas.height * dpr
        ctx.scale(dpr, dpr)
        posterDatas.canvas = canvas
        posterDatas.ctx = ctx
        posterDatas.dpr = dpr
        //存储
        that.setData({
          posterDatas
        })
      }).exec()
  },

  //海报生成
  //画布 生成 海报[海报]
  onBuildPosterSaveAlbum: function () {
    var that = this;
    var posterDatas = that.data.posterDatas
    var canvas = posterDatas.canvas
    var ctx = posterDatas.ctx
    //已生成过海报的直接显示弹窗
    if (posterDatas.success) {
      posterDatas["show"] = true;
      that.setData({
        posterDatas
      })
      return;
    }
    posterDatas.show = true;
    that.setData({
      posterDatas
    })
    wx.showLoading({
      title: '海报生成中',
      mask: true
    });
    //二维码
    var promise1 = new Promise(function (resolve, reject) {
      const photo = canvas.createImage();
      photo.src = "https://img0.baidu.com/it/u=2529320505,1328670466&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=500";
      photo.onload = (e) => {
        resolve(photo);
      }
    });
    //获取图片信息
    Promise.all(
      [promise1]
    ).then(res => {
      // 绘制白色背景
      // util.roundRect(ctx, 0, 0, posterDatas.width, posterDatas.height, 10);
      ctx.fillStyle = "#ffffff";
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      //绘制[商品图片]
      ctx.drawImage(res[0], 0, 0, posterDatas.width, 300);
      //名称
      //底部说明
      ctx.font = "bold 15px Arial"; //字体大小
      ctx.fillStyle = "#000"; //字体颜色
      ctx.textAlign = "center"
      ctx.fillText('海报已生成', 155, 330);
      // 关闭loading
      wx.hideLoading();
      //显示海报
      posterDatas.success = true;
      that.setData({
        posterDatas
      })
    }).catch(err => {
      console.log(err)
      wx.hideLoading();
      wx.showToast({
        icon: 'none',
        title: '海报生成失败,请稍后再试.',
      })
    })
  },

   //画布 转 图片[海报]
   onCanvasBuildImges: function () {
    var that = this;
    var posterDatas = that.data.posterDatas;
    wx.canvasToTempFilePath({
      canvas: posterDatas.canvas,
      width: posterDatas.width,
      height: posterDatas.height,
      destWidth: posterDatas.width * 3,
      destHeight: posterDatas.height * 3,
      success: function success(res) {
        posterDatas["pic"] = res.tempFilePath;
        that.setData({
          posterDatas
        })
        that.onDownloadImges();
      },
      fail: function complete(e) {
        wx.hideLoading();
        wx.showToast({
          icon: 'none',
          title: 'sorry 保存失败,请稍后再试.',
        })
        return;
      }
    });
  },

  //下载图片[海报]
  onDownloadImges: function () {
    wx.showLoading({
      title: '保存中',
      mask: true
    });
    var that = this;
    var posterDatas = that.data.posterDatas;
    if (!posterDatas.pic) {
      that.onCanvasBuildImges();
      return;
    }
    //可写成函数调用 这里不做解释
    wx.saveImageToPhotosAlbum({
      filePath: posterDatas.pic,
      success(res) {
        wx.hideLoading();
        wx.showToast({
          icon: 'none',
          title: '已保存到相册,快去分享吧',
        })
        posterDatas["buttonType"] = 2;
        that.setData({
          posterDatas
        })
      },
      fail: function (res) {
        wx.hideLoading();
        wx.showToast({
          icon: 'none',
          title: '进入设置页,开启“保存到相册”',
        })
        posterDatas["buttonType"] = 3;
        that.setData({
          posterDatas
        })
        return;
      }
    })
  },

  //在打开授权设置页后回调
  onBindOpenSetting: function () {
    var that = this;
    var posterDatas = that.data.posterDatas;
    posterDatas["buttonType"] = 1;
    that.setData({
      posterDatas
    })
  },

  //隐藏海报[海报]
  onIsCanvas: function () {
    var that = this;
    var posterDatas = that.data.posterDatas;
    posterDatas["buttonType"] = 1;
    posterDatas["show"] = false;
    that.setData({
      posterDatas
    })
  },

  //自定义弹窗后禁止屏幕滚动(滚动穿透)[海报]
  preventTouchMove: function () {
    //在蒙层加上 catchtouchmove 事件
    //这里什么都不要放
  },
})

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐