所属分类:php教程
程序员必备接口测试调试工具:立即使用
Apipost = Postman + Swagger + Mock + Jmeter
Api设计、调试、文档、自动化测试工具
后端、前端、测试,同时在线协作,内容实时同步
登录后复制
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()
},
登录后复制
登录后复制
类型 | 触发条件 |
---|---|
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
})
}
}
登录后复制
跟着B站大佬一起学,不过微信小程序和html canvas的差距也已经把我整抑郁了
【相关学习推荐:小程序开发教程】
以上就是通过实例了解一下小程序中怎么实现canvas拖动功能的详细内容,更多请关注zzsucai.com其它相关文章!