您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關小程序中如何實現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() },
<canvas type="2d" id="myCanvas" bindtouchstart="handleCanvasStart" bindtouchmove="handleCanvasMove" bindtouchend="handleCanvasEnd" style="height: 600px; 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 }) } }
感謝各位的閱讀!關于“小程序中如何實現canvas拖動功能”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。