广告:宝塔Linux面板高效运维的服务器管理软件 点击【 https://www.bt.cn/p/uNLv1L 】立即购买
本篇文章给大家通过代码实例来讲解一下微信小程序canvas拖动元素功能的实现方法,希望对大家有所帮助!
创建画布<canvas type="2d" id="myCanvas" style="height: 600px; width: 500px;"></canvas>登录后复制
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()},登录后复制给画布设3个触控事件
<canvas type="2d" id="myCanvas" bindtouchstart="handleCanvasStart" bindtouchmove="handleCanvasMove" bindtouchend="handleCanvasEnd" style="height: 600px; width: 500px;"></canvas>登录后复制
触摸动作开始,若点击点在圆中,改变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 }) } }登录后复制
跟着B站大佬一起学,不过微信小程序和html canvas的差距也已经把我整抑郁了
【相关学习推荐:小程序开发教程】
以上就是通过实例了解一下小程序中怎么实现canvas拖动功能的详细内容,更多请关注9543建站博客其它相关文章!
发表评论