您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)小程序中如何實(shí)現(xiàn)canvas拖動(dòng)功能的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
<canvas type="2d" id="myCanvas" style="height: 600px; width: 500px;"></canvas>
data數(shù)據(jù)
// 鼠標(biāo)狀態(tài) statusConfig : { idle: 0, //正常狀態(tài) Drag_start: 1, //拖拽開始 Dragging: 2, //拖拽中 }, // canvas 狀態(tài) canvasInfo : { // 圓的狀態(tài) status: 0, // 鼠標(biāo)在在圓圈里位置放里頭 dragTarget: null, // 點(diǎn)擊圓時(shí)的的位置 lastEvtPos: {x: null, y: null}, },
在畫布上畫兩個(gè)圓
onLoad: function (options) { // 設(shè)置畫布,獲得畫布的上下文 ctx this.getCanvas(); }, getCanvas(){ // 根據(jù)id獲取canvas元素,微信小程序無法使用document, 我們需要使用wx.createSelectorQuery()來代替 const query = wx.createSelectorQuery() query.select('#myCanvas') .fields({ node: true, size: true }) .exec((res) => { const canvas = res[0].node // 設(shè)置畫布的比例 canvas.width="500"; canvas.height="600"; const ctx = canvas.getContext('2d') // 在畫布上畫兩個(gè)圓,將ctx傳遞過去繪畫 this.drawCircle(ctx, 100, 100, 20); this.drawCircle(ctx, 200, 200, 10); // 將我們繪畫的信息保存起來,之后移動(dòng)后需要清空畫板重新畫 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>
類型 | 觸發(fā)條件 |
---|---|
touchstart | 手指觸摸動(dòng)作開始 |
touchmove | 手指觸摸后移動(dòng) |
touchcancel | 手指觸摸動(dòng)作被打斷,如來電提醒,彈窗 |
touchend | 手指觸摸動(dòng)作結(jié)束 |
tap | 手指觸摸后馬上離開 |
觸摸動(dòng)作開始,若點(diǎn)擊點(diǎn)在圓中,改變canvasInfo中的信息
handleCanvasStart(e){ // 獲取點(diǎn)擊點(diǎn)的位置 const canvasPosition = this.getCanvasPosition(e); // 判斷點(diǎn)擊點(diǎn)的位置在不在圈里,如果不在返回false, 在返回圓的信息 const circleRef = this.ifInCircle(canvasPosition); const {canvasInfo, statusConfig} = this.data; // 在圓里的話,改變圓此時(shí)的狀態(tài)信息 if(circleRef){ canvasInfo.dragTarget = circleRef; //改變拖動(dòng)狀態(tài) idle -> Drag_start canvasInfo.status = statusConfig.Drag_start; canvasInfo.lastEvtPos = canvasPosition; } this.setData({ canvasInfo }) }, // 獲取點(diǎn)擊點(diǎn)的位置 getCanvasPosition(e){ return{ x: e.changedTouches[0].x, y: e.changedTouches[0].y } }, // 看點(diǎn)擊點(diǎn)擊點(diǎn)是不是在圈里 ifInCircle(pos){ const {circles} = this.data; for( let i = 0 ; i < circles.length; i++ ){ // 判斷點(diǎn)擊點(diǎn)到圓心是不是小于半徑 if( this.getDistance(circles[i], pos) < circles[i].r ){ return circles[i] } } return false }, // 獲取兩點(diǎn)之間的距離(數(shù)學(xué)公式) getDistance(p1, p2){ return Math.sqrt((p1.x-p2.x) ** 2 + (p1.y-p2.y) ** 2) }
手指觸摸后移動(dòng) , 重新繪制圓
handleCanvasMove(e){ const canvasPosition = this.getCanvasPosition(e); const {canvasInfo, statusConfig, circles} = this.data; // 是拖拽開始狀態(tài),滑動(dòng)的大小大于5(防抖) if( canvasInfo.status === statusConfig.Drag_start && this.getDistance(canvasPosition, canvasInfo.lastEvtPos) > 5){ // 改變拖動(dòng)狀態(tài) 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, }) }
手指觸摸動(dòng)作結(jié)束 ,改變 canvasInfo在狀態(tài)重新變成idle
handleCanvasEnd(e){ const {canvasInfo, statusConfig} = this.data; if( canvasInfo.status === statusConfig.Dragging ){ // 改變拖動(dòng)狀態(tài) Dragging -> idle canvasInfo.status = statusConfig.idle; this.setData({ canvasInfo }) } }
感謝各位的閱讀!關(guān)于“小程序中如何實(shí)現(xiàn)canvas拖動(dòng)功能”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。