let penType = 'drawPen'; Page({ /** * 页面的初始数据 */ data: { scale: 1, imageList: [], showBars: false, selectSize: wx.getStorageSync('selectSize') || 5, selectColor: wx.getStorageSync('selectColor') || '#FFFFFF', colors: ["#FFFFFF", "#000000", "#ff0000", "#ffff00", "#00CC00", "#99CCFF", "#0000ff", "#ff00ff"], }, /** * 生命周期函数--监听页面加载 */ onLoad(options) { this.setData({ cover: options["cover"] || "https://cn.bing.com//th?id=OHR.GlastonburyScenic_ZH-CN9162571249_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp" }) this.initCanvas(); }, // 页面卸载 把字号选择的颜色和透明度保存 onUnload() { const This = this.data; penType = 'drawPen'; wx.setStorageSync('selectSize', This.selectSize); wx.setStorageSync('selectColor', This.selectColor); }, colorChange(e) { const color = e.currentTarget.dataset.color; this.setData({ selectColor: color }) penType = 'drawPen'; }, sizeHandler(e) { const size = e.detail.value; this.setData({ selectSize: size }) }, // 使用橡皮檫 rubberHandler() { penType = 'clearPen'; this.setData({ selectColor: "" }) }, //初始化画布 initCanvas() { const This = this.data; const query = wx.createSelectorQuery("#myCanvas"); query.select('#myCanvas').fields({ node: true, size: true, context: true }).exec(res => { const canvas = res[0].node; const context = canvas.getContext('2d'); // 获取设备像素比 const dpr = wx.getSystemInfoSync().pixelRatio; const width = res[0].width * dpr; const height = res[0].height * dpr; canvas.width = width; canvas.height = height; // 填充背景颜色 context.fillStyle = "transparent"; context.fillRect(0, 0, width, height); // 缩放 context.scale(dpr, dpr); // 设置默认属性 context.strokeStyle = This.selectColor; context.lineWidth = This.selectSize; this.setData({ canvasElement: canvas, canvasContext: context, }) }) }, // 开始 startTouchClick(e) { var that = this; const x = e.touches[0].x; const y = e.touches[0].y; that.setData({ oldPosition: { x: x, y: y }, }, () => { that.setData({ isDraw: true, }) }) }, // 移动 moveClick(e) { if (this.data.isDraw) { let positionItem = e.touches[0] if (this.data.canvasContext) { this.drawCanvas(positionItem, true) } else { this.initCanvas(() => { this.drawCanvas(positionItem, true) }) } } }, // 描绘canvas drawCanvas(position) { const ctx = this.data.canvasContext; const size = this.data.selectSize; const color = this.data.selectColor; const This = this.data; if (ctx) { ctx.beginPath(); ctx.lineWidth = size; ctx.strokeStyle = color; ctx.lineCap = 'round'; if (penType == 'clearPen') { const radius = size + 1; ctx.clearRect(position.x - (radius / 2), position.y - (radius / 2), radius, radius); } else { ctx.moveTo(This.oldPosition.x, This.oldPosition.y); ctx.lineTo(position.x, position.y); ctx.stroke() }; ctx.closePath(); this.setData({ oldPosition: { x: position.x, y: position.y, } }) } }, //触摸结束 endTouchClick(e) { this.setData({ isDraw: false }) this.saveImage(); }, //误触事件 errorClick(e) { console.log("误触事件:", e); }, // 是否展示 操作栏 showBarsHandler() { this.setData({ showBars: !this.data.showBars }) }, hideBarsHandler() { this.setData({ showBars: false }) }, // 回退一步 || 重绘 restore() { // 实际上的回退就是取存储的最后一张图片 渲染出来 // 所以会有抖动 暂未想到其他方案解决 const ctx = this.data.canvasContext; const canvas = this.data.canvasElement; const dpr = wx.getSystemInfoSync().pixelRatio; let imgs = this.data.imageList; if (!imgs || imgs.length == 0) return false; if (imgs.length == 1) return this.clearRect(); ctx.clearRect(0, 0, canvas.width, canvas.height); // -2 是因为当前的也储存了 const cover = imgs[imgs.length - 2]; imgs.splice(imgs.length - 1, 1); let bg = canvas.createImage(); bg.src = cover; bg.onload = () => { // 缩放【放大还原】 ctx.scale(1 / dpr, 1 / dpr); ctx.drawImage(bg, 0, 0, canvas.width, canvas.height); // 再缩放 ctx.scale(dpr, dpr); } }, // 清空画布 clearRect() { const ctx = this.data.canvasContext; const canvas = this.data.canvasElement; ctx.clearRect(0, 0, canvas.width, canvas.height); this.setData({ imageList: [] }) }, // 保存图片 saveImage() { const that = this; wx.canvasToTempFilePath({ canvasId: 'myCanvas', canvas: this.data.canvasElement, success: function (res) { that.data.imageList.push(res.tempFilePath); }, fail: function (err) {} }) }, // 图片预览 这边的思路是 首先将背景图片画上去 再将最后的涂鸦展示上去 preview() { const that = this; wx.showLoading({ title: '打包中...', }) const images = that.data.imageList; //if (images.length == 0) return false; const img = images[images.length - 1]; // 将背景图片画上去 const ctx = this.data.canvasContext; const canvas = this.data.canvasElement; ctx.clearRect(0, 0, canvas.width, canvas.height); const cover = this.data.cover; wx.getImageInfo({ src: cover, success: e => { let realWidth = canvas.width; let realHeight = canvas.height; // 动态计算图片宽高 if (e.width > e.height) { const ratio = canvas.height / e.height; realWidth = e.width * ratio; } else { const ratio = canvas.width / e.width; realHeight = e.height * ratio; } let bg = canvas.createImage(); bg.src = cover; bg.onload = () => { const dpr = wx.getSystemInfoSync().pixelRatio; ctx.scale(1 / dpr, 1 / dpr); ctx.drawImage(bg, 0, (canvas.height - realHeight) / 2, realWidth, realHeight); let trajectory = canvas.createImage(); trajectory.src = img; trajectory.onload = _ => { ctx.drawImage(trajectory, 0, 0, canvas.width, canvas.height); wx.canvasToTempFilePath({ canvasId: 'myCanvas', canvas: that.data.canvasElement, success: function (res) { wx.previewImage({ urls: [res.tempFilePath], showmenu: true, current: res.tempFilePath, complete: _ => { wx.hideLoading(); ctx.scale(dpr, dpr); } }) }, fail: function (err) {} }) } } } }) }, })