PHP前端开发

通过实例了解一下小程序中怎么实现canvas拖动功能

百变鹏仔 1周前 (03-12) #前端问答
文章标签 拖动

本篇文章给大家通过代码实例来讲解一下微信小程序canvas拖动元素功能的实现方法,希望对大家有所帮助!

创建画布

<canvas></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) =&gt; {        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></canvas>
类型触发条件
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 -&gt; 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 <p>手指触摸后移动 , 重新绘制圆</p><pre class="brush:js;toolbar:false;">handleCanvasMove(e){    const canvasPosition = this.getCanvasPosition(e);    const {canvasInfo, statusConfig, circles} = this.data;    // 是拖拽开始状态,滑动的大小大于5(防抖)    if( canvasInfo.status === statusConfig.Drag_start &amp;&amp;       this.getDistance(canvasPosition, canvasInfo.lastEvtPos) &gt; 5){        // 改变拖动状态 Drag_start -&gt;  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) =&gt; {            const canvas = res[0].node            canvas.width="500";            canvas.height="600";            const ctx = canvas.getContext('2d')            // 遍历circles,把圆重新画一遍            circles.forEach(c =&gt; 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 -&gt;  idle      canvasInfo.status = statusConfig.idle;      this.setData({        canvasInfo      })    }  }

跟着B站大佬一起学,不过微信小程序和html canvas的差距也已经把我整抑郁了

【相关学习推荐:小程序开发教程】