亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

圖形編輯器中JS實(shí)現(xiàn)防誤操作之拖拽阻塞

 更新時(shí)間:2023年03月06日 16:13:59   作者:前端西瓜哥  
這篇文章主要為大家介紹了圖形編輯器中JS實(shí)現(xiàn)防誤操作之拖拽阻塞實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jì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)工具的邏輯。

下面為我們要實(shí)現(xiàn)的效果。此處為了更好地演示效果,將閾值設(shè)置得很大。通常設(shè)置個(gè) 4px 就夠了。

可以看到,按下鼠標(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)。

結(jié)尾

拖拽阻塞是開(kāi)發(fā)圖形編輯器的一點(diǎn)小細(xì)節(jié),并不復(fù)雜,但能帶來(lái)很好的用戶體驗(yàn)。

以上就是圖形編輯器中JS實(shí)現(xiàn)防誤操作之拖拽阻塞的詳細(xì)內(nèi)容,更多關(guān)于JS 拖拽阻塞的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • js中substring使用示例詳解

    js中substring使用示例詳解

    substring是從中截取一段字符串,在組成一個(gè)新的字符串,這篇文章主要介紹了js中substring使用示例小結(jié),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • JavaScript判斷字符長(zhǎng)度、數(shù)字、Email、電話等常用判斷函數(shù)分享

    JavaScript判斷字符長(zhǎng)度、數(shù)字、Email、電話等常用判斷函數(shù)分享

    這篇文章主要介紹了JavaScript判斷字符長(zhǎng)度、數(shù)字、Email、電話等常用判斷函數(shù)分享,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2015-04-04
  • 基于JavaScript實(shí)現(xiàn)全選、不選和反選效果

    基于JavaScript實(shí)現(xiàn)全選、不選和反選效果

    這篇文章主要為大家詳細(xì)介紹了基于JavaScript實(shí)現(xiàn)全選、不選和反選效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • easyUI實(shí)現(xiàn)(alert)提示框自動(dòng)關(guān)閉的實(shí)例代碼

    easyUI實(shí)現(xiàn)(alert)提示框自動(dòng)關(guān)閉的實(shí)例代碼

    下面小編就為大家?guī)?lái)一篇easyUI實(shí)現(xiàn)(alert)提示框自動(dòng)關(guān)閉的實(shí)例代碼。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-11-11
  • el-table el-table-column表頭嵌套循環(huán)數(shù)據(jù)的示例代碼

    el-table el-table-column表頭嵌套循環(huán)數(shù)據(jù)的示例代碼

    本文介紹了使用兩個(gè)數(shù)組來(lái)實(shí)現(xiàn)el-table中表頭的嵌套循環(huán),一個(gè)數(shù)組用于循環(huán)表格數(shù)據(jù),另一個(gè)用于循環(huán)表頭,幫助讀者更好地理解和應(yīng)用表頭嵌套功能,感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • JavaScript獲取當(dāng)前網(wǎng)頁(yè)最后修改時(shí)間的方法

    JavaScript獲取當(dāng)前網(wǎng)頁(yè)最后修改時(shí)間的方法

    這篇文章主要介紹了JavaScript獲取當(dāng)前網(wǎng)頁(yè)最后修改時(shí)間的方法,涉及javascript中document.lastModified屬性的使用技巧,需要的朋友可以參考下
    2015-04-04
  • js確定對(duì)象類型方法

    js確定對(duì)象類型方法

    再讀《JavaScript權(quán)威指南》(犀牛書)9.7確定對(duì)象類型 之摘錄
    2012-03-03
  • 詳解JS內(nèi)存空間

    詳解JS內(nèi)存空間

    因?yàn)镴avaScript具有自動(dòng)垃圾回收機(jī)制,所以對(duì)于前端開(kāi)發(fā)來(lái)說(shuō),內(nèi)存空間并不是一個(gè)經(jīng)常被提及的概念。特別是很多不是計(jì)算機(jī)專業(yè)的朋友在進(jìn)入到前端之后,會(huì)對(duì)內(nèi)存空間的認(rèn)知比較模糊,甚至有些人干脆就是一無(wú)所知。為了解決大家的疑惑,本文將詳細(xì)介紹JS內(nèi)存空間
    2021-06-06
  • JavaScript訪問(wèn)樣式表代碼

    JavaScript訪問(wèn)樣式表代碼

    在web頁(yè)面中,我們經(jīng)常需要通過(guò)修改樣式(style)來(lái)達(dá)到更好的用戶體驗(yàn),需要的朋友可以參考下。
    2010-10-10
  • JS 參數(shù)傳遞的實(shí)際應(yīng)用代碼分析

    JS 參數(shù)傳遞的實(shí)際應(yīng)用代碼分析

    在項(xiàng)目中,有一個(gè)Ajax加載的區(qū)域,是一個(gè)Div標(biāo)簽,id為msg_box,這個(gè)控制鏈接包含在一個(gè)左側(cè)的導(dǎo)航中,當(dāng)從其他頁(yè)面鏈接到這個(gè)頁(yè)面時(shí),該JS代碼就失效了。
    2009-09-09

最新評(píng)論