文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php教程>通过实例了解一下小程序中怎么实现canvas拖动功能

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

时间:2022-01-06  来源:互联网

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

创建画布

<canvas type="2d" id="myCanvas" style=" 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()
},

1.png

给画布设3个触控事件

<canvas type="2d" id="myCanvas"
bindtouchstart="handleCanvasStart"  bindtouchmove="handleCanvasMove"  bindtouchend="handleCanvasEnd"
style=" width: 500px;">
</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 -> 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
     })
   }
 }

2.gif

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

以上就是通过实例了解一下小程序中怎么实现canvas拖动功能的详细内容,更多请关注php爱好者其它相关文章!

相关阅读更多 +
最近更新
排行榜 更多 +
元梦之星最新版手游

元梦之星最新版手游

棋牌卡牌 下载
我自为道安卓版

我自为道安卓版

角色扮演 下载
一剑斩仙

一剑斩仙

角色扮演 下载