成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

vue-draggable-resizable 可拖拽縮放的組件

springDevBird / 870人閱讀

摘要:類似于吸附效果代碼修改組件之間的沖突檢測(cè)首先是組件之間的沖突檢測(cè),組件與組件的邊界檢測(cè)需要一個(gè)標(biāo)記進(jìn)行判斷。是否開啟元素對(duì)齊當(dāng)調(diào)用對(duì)齊時(shí),用來(lái)設(shè)置組件與組件之間的對(duì)齊距離,以像素為單位。如果發(fā)現(xiàn)什么或者可以將代碼優(yōu)化的地方請(qǐng)勞煩告知我。

Vue 用于可調(diào)整大小和可拖動(dòng)元素的組件并支持組件之間的沖突檢測(cè)與組件對(duì)齊
更新2.0版本
說(shuō)明:組件基于vue-draggable-resizable進(jìn)行二次開發(fā)

距離上1.7版本版本的修改已經(jīng)過(guò)去快一年的時(shí)間了,原版組件在之前已經(jīng)更新到了2.0版本。

雖然之前適配過(guò)舊版組件,但是因?yàn)?.0版本原作者對(duì)代碼進(jìn)行了重構(gòu),原來(lái)修改的代碼照搬是不可能的了。

所以也就一直沒(méi)有將沖突檢測(cè)以及吸附對(duì)齊功能適配到2.0版本,最近正好有時(shí)間就適配一下。

新增特征

沖突檢測(cè)

吸附對(duì)齊

默認(rèn)樣式優(yōu)化

功能預(yù)覽

項(xiàng)目地址

https://github.com/gorkys/vue...

如果喜歡該項(xiàng)目,歡迎Star
前言
17年就應(yīng)用此組件到了項(xiàng)目中,當(dāng)時(shí)正式版的功能不能滿足項(xiàng)目需求,還拉取了dev分支的測(cè)試版進(jìn)行了簡(jiǎn)單的更改。(項(xiàng)目中主要功能之一需要用到此組件)
今年因?yàn)樾枨笞兏?,?xiàng)目重構(gòu)(手動(dòng)淚奔),然后去看了看github,該組件的正式版本更新到了1.7.x,于是把正式版拉下來(lái)根據(jù)自己的需求進(jìn)行了修改并發(fā)布新版到npm上。
特征

沒(méi)有依賴

可拖動(dòng),可調(diào)整大小或者兩者都行

擁有用于調(diào)整大小的控制點(diǎn)

限制組件調(diào)整大小和移動(dòng)超出父元素

自定義網(wǎng)格移動(dòng)

將拖動(dòng)限制為垂直或水平移動(dòng)

新增特征

組件之間的沖突檢測(cè)(不允許組件之間重疊)

組件與組件之間進(jìn)行對(duì)齊(類似于吸附效果)

項(xiàng)目地址

原組件地址:vue-draggable-resizable
新組件地址:vue-draggable-resizable

安裝使用
npm install --save vue-draggable-resizable-gorkys

更多API請(qǐng)?jiān)陧?xiàng)目說(shuō)明文檔中查看

Demo

Demo

修改過(guò)程記錄 提出建議

在原組件的Issues中提出了建議,作者表示不打算讓此組件進(jìn)行跨越組件之外的操作。
好吧,既然作者不打算進(jìn)行這方面的支持,那只好自己動(dòng)手了。
Clone項(xiàng)目

Fork項(xiàng)目到自己的倉(cāng)庫(kù),然后Clone項(xiàng)目到本地進(jìn)行修改。

需求說(shuō)明

1.組件之間的沖突檢測(cè)

兩個(gè)組件不允許重疊,如果重疊,將回到移動(dòng)或縮放前位置

2.組件與組件之間進(jìn)行對(duì)齊(參照J(rèn)query UI的draggable

用戶移動(dòng)一個(gè)組件到另一個(gè)組件邊緣的時(shí)候,進(jìn)行對(duì)齊操作。類似于吸附效果
代碼修改 1.組件之間的沖突檢測(cè)

首先是組件之間的沖突檢測(cè),組件與組件的邊界檢測(cè)需要一個(gè)標(biāo)記進(jìn)行判斷。

先在props中加入一個(gè)isConflictCheck,讓使用者自己選擇是否使用此功能。
props:{
    /* 定義組件是否開啟沖突檢測(cè) */
    isConflictCheck: {
      type: Boolean, default: false
    }
    ...
}
當(dāng)我們拿到isConflictCheck后,在setConflictCheck方法中給組件的Dom設(shè)置一個(gè)data-*的屬性。
   setConflictCheck: function () {
      if (this.isConflictCheck) {
        this.$el.setAttribute("data-is-check", "true")
      } else {
        this.$el.setAttribute("data-is-check", "false")
      }
    }
然后就是如何去檢測(cè)組件之間的沖突,代碼如下,此代碼是在測(cè)試版本中使用的,看到這些判斷都可怕,為了頭發(fā),就沒(méi)有去優(yōu)化了(反正能使用)。
conflictCheck: function () {
      if (this.isConflictCheck) {
        let p = this.$el.parentNode.childNodes // 獲取當(dāng)前父節(jié)點(diǎn)下所有子節(jié)點(diǎn)
        if (p.length > 1) {
          for (let i = 0; i < p.length; i++) {
            if (p[i] !== this.$el && p[i].className !== undefined && p[i].getAttribute("data-is-check") !== "false") {
              let tw = p[i].offsetWidth
              let th = p[i].offsetHeight
              let tl = p[i].offsetLeft
              let tt = p[i].offsetTop
              // 如果沖突,就將回退到移動(dòng)前的位置
              if (this.top >= tt && this.left >= tl && tt + th > this.top && tl + tw > this.left ||
                this.top <= tt && this.left < tl && this.top + this.height > tt && this.left + this.width > tl) { /* 左上角與右下角重疊 */
                this.top = this.restoreY
                this.left = this.restoreX
                this.width = this.restoreW
                this.height = this.restoreH
              } else if (this.left <= tl && this.top >= tt && this.left + this.width > tl && this.top < tt + th ||
                this.top < tt && this.left > tl && this.top + this.height > tt && this.left < tl + tw) { /* 右上角與左下角重疊 */
                this.top = this.restoreY
                this.left = this.restoreX
                this.width = this.restoreW
                this.height = this.restoreH
              } else if (this.top < tt && this.left <= tl && this.top + this.height > tt && this.left + this.width > tl ||
                this.top > tt && this.left >= tl && this.top < tt + th && this.left < tl + tw) { /* 下邊與上邊重疊 */
                this.top = this.restoreY
                this.left = this.restoreX
                this.width = this.restoreW
                this.height = this.restoreH
              } else if (this.top <= tt && this.left >= tl && this.top + this.height > tt && this.left < tl + tw ||
                this.top >= tt && this.left <= tl && this.top < tt + th && this.left > tl + tw) { /* 上邊與下邊重疊(寬度不一樣) */
                this.top = this.restoreY
                this.left = this.restoreX
                this.width = this.restoreW
                this.height = this.restoreH
              } else if (this.left >= tl && this.top >= tt && this.left < tl + tw && this.top < tt + th ||
                this.top > tt && this.left <= tl && this.left + this.width > tl && this.top < tt + th) { /* 左邊與右邊重疊 */
                this.top = this.restoreY
                this.left = this.restoreX
                this.width = this.restoreW
                this.height = this.restoreH
              } else if (this.top <= tt && this.left >= tl && this.top + this.height > tt && this.left < tl + tw ||
                this.top >= tt && this.left <= tl && this.top < tt + th && this.left + this.width > tl) { /* 左邊與右邊重疊(高度不一樣) */
                this.top = this.restoreY
                this.left = this.restoreX
                this.width = this.restoreW
                this.height = this.restoreH
              }
            }
          }
        }
      }
    }, // 沖突檢測(cè)
最后就是在停止移動(dòng)和縮放時(shí)調(diào)用上面的方法就可以了(代碼精簡(jiǎn)過(guò))。
handleUp: function (e) {
      this.handle = null
      if (this.resizing) {
        this.resizing = false
        this.conflictCheck() // 沖突檢測(cè)
      }
      if (this.dragging) {
        this.dragging = false
        this.conflictCheck() // 沖突檢測(cè)
      }
    } // 鼠標(biāo)松開
2.組件與組件之間進(jìn)行對(duì)齊

與沖突檢測(cè)一樣的套路。

先在props中加入一個(gè)snap,讓使用者自己選擇是否使用此功能。為了更靈活,這里多添加了一個(gè)snapTolerance,當(dāng)調(diào)用對(duì)齊時(shí),用來(lái)設(shè)置組件與組件之間的對(duì)齊距離,以像素為單位。
    /* 是否開啟元素對(duì)齊 */
    snap: {
      type: Boolean, default: false
    },
    /* 當(dāng)調(diào)用對(duì)齊時(shí),用來(lái)設(shè)置組件與組件之間的對(duì)齊距離,以像素為單位。 */
    snapTolerance: {
      type: Number,
      default: 5,
      validator: function (val) {
        return typeof val === "number"
      }
然后就是設(shè)置data-*屬性
setSnap: function () {
      if (this.snap) {
        this.$el.setAttribute("data-is-snap", "true")
      } else {
        this.$el.setAttribute("data-is-snap", "false")
      }
    }, // 設(shè)置對(duì)齊元素
再然后就是主要方法snapCheck的編寫。這里我翻看了一下JQuery UI中的draggable源碼,并近乎copy的借鑒了過(guò)來(lái)。
snapCheck: function () {
      if (this.snap) {
        let p = this.$el.parentNode.childNodes // 獲取當(dāng)前父節(jié)點(diǎn)下所有子節(jié)點(diǎn)
        if (p.length > 1) {
          let x1 = this.left
          let x2 = this.left + this.width
          let y1 = this.top
          let y2 = this.top + this.height
          for (let i = 0; i < p.length; i++) {
            if (p[i] !== this.$el && p[i].className !== undefined && p[i].getAttribute("data-is-snap") !== "false") {
              let l = p[i].offsetLeft // 對(duì)齊目標(biāo)的left
              let r = l + p[i].offsetWidth // 對(duì)齊目標(biāo)右側(cè)距離窗口的left
              let t = p[i].offsetTop// 對(duì)齊目標(biāo)的top
              let b = t + p[i].offsetHeight // 對(duì)齊目標(biāo)右側(cè)距離窗口的top

              let ts = Math.abs(t - y2) <= this.snapTolerance
              let bs = Math.abs(b - y1) <= this.snapTolerance
              let ls = Math.abs(l - x2) <= this.snapTolerance
              let rs = Math.abs(r - x1) <= this.snapTolerance
              if (ts) {
                this.top = t - this.height
              }
              if (bs) {
                this.top = b
              }
              if (ls) {
                this.left = l - this.width
              }
              if (rs) {
                this.left = r
              }
            }
          }
        }
      }
    }, // 檢測(cè)對(duì)齊元素
好了,最后就是在鼠標(biāo)移動(dòng)組件時(shí)及時(shí)調(diào)用就可以了。
handleMove: function (e) {
        ...
        this.snapCheck()
        this.$emit("dragging", this.left, this.top)
      }
    }, // 鼠標(biāo)移動(dòng)
總結(jié)

這次的修改還算是非常順利,順便還把之前的一些代碼進(jìn)行了優(yōu)化。
如果發(fā)現(xiàn)什么bug或者可以將代碼優(yōu)化的地方請(qǐng)勞煩告知我。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97874.html

相關(guān)文章

  • 使用 Drag and Drop 給Web應(yīng)用提升交互體驗(yàn)

    摘要:注意點(diǎn)在鼠標(biāo)操作拖放期間,有一些事件可能觸發(fā)多次,比如和??赏献г?,建議使用,設(shè)定可拖拽元素的鼠標(biāo)游標(biāo),提升交互。在中使用拖拽中使用可以直接綁定到組件上。 什么是 Drag and Drop (拖放)? 簡(jiǎn)單來(lái)說(shuō),HTML5 提供了 Drag and Drop API,允許用戶用鼠標(biāo)選中一個(gè)可拖動(dòng)元素,移動(dòng)鼠標(biāo)拖放到一個(gè)可放置到元素的過(guò)程。 我相信每個(gè)人都或多或少接觸過(guò)拖放,比如瀏覽...

    legendmohe 評(píng)論0 收藏0
  • 前方來(lái)報(bào),八月最新資訊--關(guān)于vue2&3最佳文章推薦

    摘要:哪吒別人的看法都是狗屁,你是誰(shuí)只有你自己說(shuō)了才算,這是爹教我的道理。哪吒去他個(gè)鳥命我命由我,不由天是魔是仙,我自己決定哪吒白白搭上一條人命,你傻不傻敖丙不傻誰(shuí)和你做朋友太乙真人人是否能夠改變命運(yùn),我不曉得。我只曉得,不認(rèn)命是哪吒的命。 showImg(https://segmentfault.com/img/bVbwiGL?w=900&h=378); 出處 查看github最新的Vue...

    izhuhaodev 評(píng)論0 收藏0
  • element-ui dialog組件添加拖拽位置 拖拽寬高

    摘要:最近公司新加需求實(shí)現(xiàn)彈窗可拖拽還要拖拽寬高變化國(guó)際慣例先上圖瀏覽器下作的有幾個(gè)點(diǎn)需要注意一下每個(gè)彈窗都要有唯一可操作指令可以做到拖拽時(shí)要添加可拖拽區(qū)塊由于組件在設(shè)計(jì)時(shí)寬度用了百分比這里不同瀏覽器有兼容性問(wèn)題實(shí)現(xiàn)拖拽寬高時(shí)獲取邊緣問(wèn)題定位設(shè) 最近公司新加需求, 實(shí)現(xiàn)彈窗可拖拽, 還要拖拽寬高變化. 國(guó)際慣例先上圖: edge瀏覽器下作的gif http://www.lano...

    jzman 評(píng)論0 收藏0
  • Canvas裁剪圖片(截選框拖拽

    摘要:利用實(shí)現(xiàn)圖片裁剪效果圖實(shí)現(xiàn)思路打開圖片并將圖片繪制到中利用的函數(shù)來(lái)裁剪圖片將轉(zhuǎn)化為即可。巨坑轉(zhuǎn)化為圖片確認(rèn)截圖確認(rèn)截圖參考文章我是,年輕的前端攻城獅一枚,愛(ài)專研,愛(ài)技術(shù),愛(ài)分享。文章有任何問(wèn)題歡迎大家指出,也歡迎大家一起交流前端各種問(wèn)題 利用Canvas實(shí)現(xiàn)圖片裁剪 效果圖 showImg(https://segmentfault.com/img/bVburJ2?w=864&h=706...

    MAX_zuo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<