### [通过实例了解一下小程序中怎么实现canvas拖动功能](https://www.prosaas.cn/article/16345) **Published:** 2021-11-29T11:23:40 **Author:** 5201314 **Excerpt:** 本篇文章给大家通过代码实例来讲解一下微信小程序canvas拖动元素功能的实现方法,希望对大家有所帮助!创建画布… 本篇文章给大家通过代码实例来讲解一下微信小程序canvas拖动元素功能的实现方法,希望对大家有所帮助! ![](https://img.php.cn/upload/article/000/000/024/61a4b818bfb60218.jpg) # 创建画布 data数据 // 鼠标状态 statusConfig : { idle: 0, //正常状态 Drag\_start: 1, //拖拽开始 Dragging: 2, //拖拽中 }, // canvas 状态 canvasInfo : { // 圆的状态 status: 0, // 鼠标在在圆圈里位置放里头 dragTarget: null, // 点击圆时的的位置 lastEvtPos: {x: null, y: null}, }, 在画布上画两个圆 onLoad: function (options) { // 设置画布,获得画布的上下文 ctx this.getCanvas(); }, getCanvas(){ // 根据id获取canvas元素,微信小程序无法使用document, 我们需要使用wx.createSelectorQuery()来代替 const query = wx.createSelectorQuery() query.select('#myCanvas') .fields({ node: true, size: true }) .exec((res) => { const canvas = res\[0\].node // 设置画布的比例 canvas.width="500"; canvas.height="600"; const ctx = canvas.getContext('2d') // 在画布上画两个圆,将ctx传递过去绘画 this.drawCircle(ctx, 100, 100, 20); this.drawCircle(ctx, 200, 200, 10); // 将我们绘画的信息保存起来,之后移动后需要清空画板重新画 var circles = \[\] circles.push({x: 100, y: 100, r: 20}); circles.push({x: 200, y: 200, r: 10}); // 不要忘记保存哦 this.setData({ circles }) }) }, // 画圆 drawCircle(ctx, cx, cy, r){ ctx.save() ctx.beginPath() ctx.strokeStyle = 'yellow' ctx.lineWidth = 3 ctx.arc(cx, cy, r, 0, 2 \* Math.PI) ctx.stroke() ctx.closePath() ctx.restore() }, ![](https://img.php.cn/upload/image/825/269/406/1638184882594923.png) ## 给画布设3个触控事件 | 类型 | 触发条件 | | --- | --- | | touchstart | 手指触摸动作开始 | | touchmove | 手指触摸后移动 | | touchcancel | 手指触摸动作被打断,如来电提醒,弹窗 | | touchend | 手指触摸动作结束 | | tap | 手指触摸后马上离开 | 触摸动作开始,若点击点在圆中,改变canvasInfo中的信息 handleCanvasStart(e){ // 获取点击点的位置 const canvasPosition = this.getCanvasPosition(e); // 判断点击点的位置在不在圈里,如果不在返回false, 在返回圆的信息 const circleRef = this.ifInCircle(canvasPosition); const {canvasInfo, statusConfig} = this.data; // 在圆里的话,改变圆此时的状态信息 if(circleRef){ canvasInfo.dragTarget = circleRef; //改变拖动状态 idle -> Drag\_start canvasInfo.status = statusConfig.Drag\_start; canvasInfo.lastEvtPos = canvasPosition; } this.setData({ canvasInfo }) }, // 获取点击点的位置 getCanvasPosition(e){ return{ x: e.changedTouches\[0\].x, y: e.changedTouches\[0\].y } }, // 看点击点击点是不是在圈里 ifInCircle(pos){ const {circles} = this.data; for( let i = 0 ; i < circles.length; i++ ){ // 判断点击点到圆心是不是小于半径 if( this.getDistance(circles\[i\], pos) < circles\[i\].r ){ return circles\[i\] } } return false }, // 获取两点之间的距离(数学公式) getDistance(p1, p2){ return Math.sqrt((p1.x-p2.x) \*\* 2 + (p1.y-p2.y) \*\* 2) } 手指触摸后移动 , 重新绘制圆 handleCanvasMove(e){ const canvasPosition = this.getCanvasPosition(e); const {canvasInfo, statusConfig, circles} = this.data; // 是拖拽开始状态,滑动的大小大于5(防抖) if( canvasInfo.status === statusConfig.Drag\_start && this.getDistance(canvasPosition, canvasInfo.lastEvtPos) > 5){ // 改变拖动状态 Drag\_start -> Dragging canvasInfo.status = statusConfig.Dragging; }else if( canvasInfo.status === statusConfig.Dragging ){ canvasInfo.dragTarget.x = canvasPosition.x; canvasInfo.dragTarget.y = canvasPosition.y; // 重新绘制 const query = wx.createSelectorQuery() query.select('#myCanvas') .fields({ node: true, size: true }) .exec((res) => { const canvas = res\[0\].node canvas.width="500"; canvas.height="600"; const ctx = canvas.getContext('2d') // 遍历circles,把圆重新画一遍 circles.forEach(c => this.drawCircle(ctx, c.x, c.y, c.r)) }) } this.setData({ canvasInfo, }) } 手指触摸动作结束 ,改变 canvasInfo在状态重新变成idle handleCanvasEnd(e){ const {canvasInfo, statusConfig} = this.data; if( canvasInfo.status === statusConfig.Dragging ){ // 改变拖动状态 Dragging -> idle canvasInfo.status = statusConfig.idle; this.setData({ canvasInfo }) } } ![](https://img.php.cn/upload/image/923/261/190/1638184876208027.gif) 跟着B站大佬一起学,不过微信小程序和html canvas的差距也已经把我整抑郁了 【相关学习推荐:小程序开发教程】 以上就是通过实例了解一下小程序中怎么实现canvas拖动功能的详细内容,更多请关注知企PROSAAS其它相关文章! **Tags:** canvas, html, 事件, 微信小程序 **Categories:** 后端开发 ---