您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“圖形編輯器中JS怎么實(shí)現(xiàn)拖拽阻塞”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“圖形編輯器中JS怎么實(shí)現(xiàn)拖拽阻塞”吧!
在圖形編輯器中,想象這么一個(gè)場(chǎng)景,我們撤銷了一些重要的操作,然后想選中一個(gè)圖形,看看它的屬性。你點(diǎn)了上去,然后你發(fā)現(xiàn)你再也無(wú)法重做了。
你以為你點(diǎn)了一下,但其實(shí)你點(diǎn)擊的時(shí)候,鼠標(biāo)還是小小移動(dòng)了一點(diǎn),飄了一個(gè)像素點(diǎn)。對(duì)編輯器來(lái)說(shuō),它識(shí)別到讓圖形移動(dòng)一個(gè)像素點(diǎn)的操作,就生成了一個(gè)新的版本,然后重做棧(redoStack)被清空了,你退回前的操作就沒(méi)了。
為了解決這類用戶微小操作的問(wèn)題,我們可以巧妙地給拖拽行為加一個(gè) 阻塞閾值。具體就是就是按下鼠標(biāo)后,移動(dòng)鼠標(biāo)的距離要大于某個(gè)值,我們才認(rèn)為發(fā)生了拖拽,并執(zhí)行對(duì)應(yīng)工具的邏輯。
按下鼠標(biāo)然后移動(dòng),如果移動(dòng)的位移太小,矩形是不會(huì)被移動(dòng)的,直到達(dá)到一定位移閾值后,矩形才會(huì)乖乖聽(tīng)話跟隨鼠標(biāo)進(jìn)行移動(dòng)。
閾值表示位移距離,使用的是視口坐標(biāo)系,而不是場(chǎng)景坐標(biāo)系。
原來(lái)的邏輯:
let isPressing = false; let currentTool = null; // 當(dāng)前工具對(duì)象 // 鼠標(biāo)按下 function handleDown(e) { isPressing = true; currentTool.start(e); } // 鼠標(biāo)移動(dòng) function handleMove(e) { if (isPressing) { currentTool.drag(e); } else { // 非拖拽的移動(dòng)事件 // 比如選擇工具停留在圖形上,圖形要高亮,此時(shí)沒(méi)發(fā)生拖拽 currentTool.move(e); } } // 鼠標(biāo)釋放 function handleUp(e) { currentTool.end(e); isPressing = false; }
鼠標(biāo)按下時(shí),isPressing 設(shè)置為 true,表示發(fā)生了鼠標(biāo)按下事件。
此時(shí)鼠標(biāo)再移動(dòng),我們就能知道這是一個(gè) “拖拽” 的行為,即按下鼠標(biāo)不放然后移動(dòng)鼠標(biāo)的行為。此時(shí)調(diào)用工具對(duì)象的 drag 方法。
最后鼠標(biāo)釋放,將狀態(tài) isPressing 重置。
現(xiàn)在我們進(jìn)行改造。
let isPressing = false; let currentTool = null; // 當(dāng)前工具對(duì)象 let isEnableDragging = false; // 是否調(diào)用工具對(duì)象的 drag 方法 let startPos = null; // 保存鼠標(biāo)按下時(shí)的坐標(biāo) const blockStep = 4; // 閾值 function handleDown(e) { isPressing = true; isEnableDragging = false; startPos = { x: e.clientX, y: e.clientY }; currentTool.start(e); } function handleMove(e) { // 判斷位移是否突破閾值,是的話更新?tīng)顟B(tài)為 “可拖拽” if ( !isEnableDragging && (Math.abs(e.clientX - startPos.x) > blockStep || Math.abs(e.clientX - startPos.x) > blockStep) ) { isEnableDragging = true; } if (isPressing) { if (isEnableDragging) { // “可拖拽” 狀態(tài),調(diào)用工具的 drag 方法 currentTool.drag(e); } } else { currentTool.move(e); } } function handleUp(e) { currentTool.end(e); // 初始化狀態(tài) isPressing = false; isEnableDragging = false; startPos = null; }
核心思路是引入 isEnableDragging 狀態(tài),表示鼠標(biāo)移動(dòng)時(shí),是否達(dá)到移動(dòng)的條件。
我們?cè)谑髽?biāo)移動(dòng)事件中,計(jì)算鼠標(biāo)按下和鼠標(biāo)移動(dòng)之間的距離是否超過(guò)某個(gè)值,如果超過(guò)閾值,就將 isEnableDragging 狀態(tài)轉(zhuǎn)換為 true。
然后判斷 isEnableDragging 為 true,就調(diào)用工具對(duì)象的 drag 方法。
需要注意的是,不要只用位移距離來(lái)判斷是否可以拖拽,要配合狀態(tài)。否則突破閾值后,又移動(dòng)回來(lái),你會(huì)發(fā)現(xiàn)你又卡住了,因?yàn)榇藭r(shí)閾值因?yàn)樵俅斡?jì)算,沒(méi)能達(dá)到閾值。
所以加了個(gè) isEnableDragging 狀態(tài),在第一次突破閾值設(shè)置為 true 后,就再也不用計(jì)算位移了,之后一直都是可拖拽狀態(tài),直到鼠標(biāo)釋放重置狀態(tài)。
到此,相信大家對(duì)“圖形編輯器中JS怎么實(shí)現(xiàn)拖拽阻塞”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(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)容。