微信小程序画布canvas的使用
wxml部分:
<view class="container"> <canvas class="canvas1" id="myCanvas" type="2d" disable-scroll="true" bindtouchstart="canvasStart" bindtouchmove="canvasMove" bindtouchend="canvasEnd" touchcancel="canvasEnd"></canvas> </view> <view class="qingchu" bindtap="canvasClear">清除</view> <view class="wancheng" bindtap="finish">完成</view>
wxss部分:
.container{ width: 100%; padding-bottom: 100rpx; } .canvas1{ width: calc(100% - 40rpx); margin: 0 20rpx; height: 400rpx; border: 2rpx solid #7062eb; } .go{ text-align: center; background-color: aqua; padding: 30rpx 0; } .qingchu{ text-align: center; background-color: #ec8f16; padding: 20rpx 0; } .wancheng{ text-align: center; background-color: #44c063; padding: 20rpx 0; }
js部分:
const MAX_V = 1; // 最大书写速度 const MIN_V = 0; // 最小书写速度 const MAX_LINE_WIDTH = 6; // 最大笔画宽度 const MIN_LINE_WIDTH = 2; // 最小笔画宽度 const MAX_LINE_DIFF = .03; // 两点之间笔画宽度最大差异 let context = null; // canvas上下文 let lastPoint = null; // 包含上一点笔画信息的对象 Page({ data: { drawn: false, }, onShow: function (options) { this.canvasInit(); }, canvasInit: function () { wx.createSelectorQuery() .select('#myCanvas') // 在 WXML 中填入的 id .fields({ node: true, size: true }) .exec((res) => { console.log('89',res); res[0].node.width = res[0].width; res[0].node.height = res[0].height; context = res[0].node.getContext("2d") }) }, canvasMove: function (e) { this.setData({ drawn: true }) let currPoint = { x: e.changedTouches[0].x, // X坐标 y: e.changedTouches[0].y, // Y坐标 t: new Date().getTime(), // 当前时间 w: (MAX_LINE_WIDTH + MIN_LINE_WIDTH) / 2 /*默认宽度 */ }; if (lastPoint) { currPoint.w = this.calcLineWidth(currPoint); // 重新赋值宽度,覆盖默认值 context.beginPath(); context.strokeStyle = '#000'; context.lineCap = 'round'; context.lineJoin = 'round'; context.lineWidth = currPoint.w; context.moveTo(lastPoint.x, lastPoint.y); context.lineTo(currPoint.x, currPoint.y); context.stroke(); // context.draw(true); } lastPoint = currPoint; // 结束前保存当前点为上一点 }, // 计算当前点的宽度,书写速度越快,笔画宽度越小,呈现出笔锋的感觉(笑) calcLineWidth: function (currPoint) { let consuming = currPoint.t - lastPoint.t; // 两点之间耗时 if (!consuming) return lastPoint.w; // 如果当前点用时为0,返回上点的宽度。 let maxWidth = Math.min(MAX_LINE_WIDTH, lastPoint.w * (1 + MAX_LINE_DIFF)); // 当前点的最大宽度 let minWidth = Math.max(MIN_LINE_WIDTH, lastPoint.w * (1 - MAX_LINE_DIFF * 3)); // 当前点的最小宽度,变细时速度快所以宽度变化要稍快 let distance = Math.sqrt(Math.pow(currPoint.x - lastPoint.x, 2) + Math.pow(currPoint.y - lastPoint.y, 2)); // 两点之间距离 let speed = Math.max(Math.min(distance / consuming, MAX_V), MIN_V); /*当前点速度*/ let lineWidth = Math.max(Math.min(MAX_LINE_WIDTH * (1 - speed / MAX_V), maxWidth), minWidth); /* 当前点宽度 */ return lineWidth; }, canvasEnd: function (e) { lastPoint = null; // 每笔画完清除缓存 }, canvasClear: function () { this.setData({ drawn: false }) context.clearRect(0, 0, context.canvas.width, context.canvas.height); // context.draw(false); }, // canvasOut: function () { // wx.navigateBack({ // delta: 1, // }) // }, finish: function () { if (!this.data.drawn) { return; } //由于新版的canvas的wx.canvasToTempFilePath方法一直报错,只能通过以下方式来获取签名图片 const res = context.canvas.toDataURL("image/png"); const fsm = wx.getFileSystemManager();const FILE_BASE_NAME = "tmp_base64src_" + new Date().getTime();const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.png`; fsm.writeFile({ filePath, data: res.replace(/^data:image\/\w+;base64,/, ""), encoding: "base64", success: (res) => { console.log('完成',res); // this.getOpenerEventChannel().emit('signature', filePath); //传签名图片的临时路径回上一页 // wx.navigateBack(); }, fail() { wx.showToast({ title: "生成签名失败", icon: "none" }); }, }); }, })
分类:
微信小程序
标签:
微信小程序画布canvas的使用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App