前言: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.posterDatasconst query = wx.createSelectorQuery()query.select('#firstCanvas').fields({node: true,size: true},function (res) {const canvas = res.nodeconst ctx = canvas.getContext('2d')const dpr = wx.getSystemInfoSync().pixelRatiocanvas.width = posterDatas.width * dprcanvas.height = posterDatas.height * dprctx.scale(dpr, dpr)posterDatas.canvas = canvasposterDatas.ctx = ctxposterDatas.dpr = dpr//存储that.setData({posterDatas})}).exec()},//海报生成//画布 生成 海报[海报]onBuildPosterSaveAlbum: function () {var that = this;var posterDatas = that.data.posterDatasvar canvas = posterDatas.canvasvar 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);// 关闭loadingwx.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 事件//这里什么都不要放},
})



















