This article will explain how to implement the canvas drag element function of the WeChat applet through code examples. I hope it will be helpful to everyone!
##Create canvas<canvas type="2d" id="myCanvas" style="max-width:90%"></canvas>
// 鼠标状态 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() },
Set 3 touch events to the canvas
<canvas type="2d" id="myCanvas" bindtouchstart="handleCanvasStart" bindtouchmove="handleCanvasMove" bindtouchend="handleCanvasEnd" style="height: 600px; width: 500px;"> </canvas>
Trigger conditions | |
---|---|
Finger touch action starts | |
Finger moves after touching | |
The finger touch action is interrupted, such as an incoming call reminder, pop-up window | |
The finger touch action ends | |
Leave immediately after touching the finger |
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) }
Move after touching the finger, redraw the circle
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, }) }
The finger touch action ends, change the canvasInfo state to idle again
handleCanvasEnd(e){ const {canvasInfo, statusConfig} = this.data; if( canvasInfo.status === statusConfig.Dragging ){ // 改变拖动状态 Dragging -> idle canvasInfo.status = statusConfig.idle; this.setData({ canvasInfo }) } }
Learn from the bosses of Bilibili, but the gap between WeChat mini program and html canvas has already made me depressed
[Related learning recommendations:
小program development tutorialThe above is the detailed content of Learn how to implement the canvas drag function in the mini program through an example. For more information, please follow other related articles on the PHP Chinese website!