摘要:類似于吸附效果代碼修改組件之間的沖突檢測首先是組件之間的沖突檢測,組件與組件的邊界檢測需要一個標記進行判斷。是否開啟元素對齊當調用對齊時,用來設置組件與組件之間的對齊距離,以像素為單位。如果發現什么或者可以將代碼優化的地方請勞煩告知我。
Vue 用于可調整大小和可拖動元素的組件并支持組件之間的沖突檢測與組件對齊更新2.0版本
說明:組件基于vue-draggable-resizable進行二次開發
距離上1.7版本版本的修改已經過去快一年的時間了,原版組件在之前已經更新到了2.0版本。
雖然之前適配過舊版組件,但是因為2.0版本原作者對代碼進行了重構,原來修改的代碼照搬是不可能的了。
所以也就一直沒有將沖突檢測以及吸附對齊功能適配到2.0版本,最近正好有時間就適配一下。
新增特征
沖突檢測
吸附對齊
默認樣式優化
功能預覽 項目地址https://github.com/gorkys/vue...
如果喜歡該項目,歡迎Star前言
17年就應用此組件到了項目中,當時正式版的功能不能滿足項目需求,還拉取了dev分支的測試版進行了簡單的更改。(項目中主要功能之一需要用到此組件)特征
今年因為需求變更,項目重構(手動淚奔),然后去看了看github,該組件的正式版本更新到了1.7.x,于是把正式版拉下來根據自己的需求進行了修改并發布新版到npm上。
沒有依賴
可拖動,可調整大小或者兩者都行
擁有用于調整大小的控制點
限制組件調整大小和移動超出父元素
自定義網格移動
將拖動限制為垂直或水平移動
新增特征
組件之間的沖突檢測(不允許組件之間重疊)
組件與組件之間進行對齊(類似于吸附效果)
項目地址原組件地址:vue-draggable-resizable
新組件地址:vue-draggable-resizable
npm install --save vue-draggable-resizable-gorkys
更多API請在項目說明文檔中查看
DemoDemo
修改過程記錄 提出建議在原組件的Issues中提出了建議,作者表示不打算讓此組件進行跨越組件之外的操作。Clone項目
好吧,既然作者不打算進行這方面的支持,那只好自己動手了。
Fork項目到自己的倉庫,然后Clone項目到本地進行修改。
需求說明1.組件之間的沖突檢測
兩個組件不允許重疊,如果重疊,將回到移動或縮放前位置
2.組件與組件之間進行對齊(參照Jquery UI的draggable)
用戶移動一個組件到另一個組件邊緣的時候,進行對齊操作。類似于吸附效果代碼修改 1.組件之間的沖突檢測
首先是組件之間的沖突檢測,組件與組件的邊界檢測需要一個標記進行判斷。
先在props中加入一個isConflictCheck,讓使用者自己選擇是否使用此功能。
props:{ /* 定義組件是否開啟沖突檢測 */ isConflictCheck: { type: Boolean, default: false } ... }
當我們拿到isConflictCheck后,在setConflictCheck方法中給組件的Dom設置一個data-*的屬性。
setConflictCheck: function () { if (this.isConflictCheck) { this.$el.setAttribute("data-is-check", "true") } else { this.$el.setAttribute("data-is-check", "false") } }
然后就是如何去檢測組件之間的沖突,代碼如下,此代碼是在測試版本中使用的,看到這些判斷都可怕,為了頭發,就沒有去優化了(反正能使用)。
conflictCheck: function () { if (this.isConflictCheck) { let p = this.$el.parentNode.childNodes // 獲取當前父節點下所有子節點 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 // 如果沖突,就將回退到移動前的位置 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 } } } } } }, // 沖突檢測
最后就是在停止移動和縮放時調用上面的方法就可以了(代碼精簡過)。
handleUp: function (e) { this.handle = null if (this.resizing) { this.resizing = false this.conflictCheck() // 沖突檢測 } if (this.dragging) { this.dragging = false this.conflictCheck() // 沖突檢測 } } // 鼠標松開2.組件與組件之間進行對齊
與沖突檢測一樣的套路。
先在props中加入一個snap,讓使用者自己選擇是否使用此功能。為了更靈活,這里多添加了一個snapTolerance,當調用對齊時,用來設置組件與組件之間的對齊距離,以像素為單位。
/* 是否開啟元素對齊 */ snap: { type: Boolean, default: false }, /* 當調用對齊時,用來設置組件與組件之間的對齊距離,以像素為單位。 */ snapTolerance: { type: Number, default: 5, validator: function (val) { return typeof val === "number" }
然后就是設置data-*屬性
setSnap: function () { if (this.snap) { this.$el.setAttribute("data-is-snap", "true") } else { this.$el.setAttribute("data-is-snap", "false") } }, // 設置對齊元素
再然后就是主要方法snapCheck的編寫。這里我翻看了一下JQuery UI中的draggable源碼,并近乎copy的借鑒了過來。
snapCheck: function () { if (this.snap) { let p = this.$el.parentNode.childNodes // 獲取當前父節點下所有子節點 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 // 對齊目標的left let r = l + p[i].offsetWidth // 對齊目標右側距離窗口的left let t = p[i].offsetTop// 對齊目標的top let b = t + p[i].offsetHeight // 對齊目標右側距離窗口的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 } } } } } }, // 檢測對齊元素
好了,最后就是在鼠標移動組件時及時調用就可以了。
handleMove: function (e) { ... this.snapCheck() this.$emit("dragging", this.left, this.top) } }, // 鼠標移動總結
這次的修改還算是非常順利,順便還把之前的一些代碼進行了優化。
如果發現什么bug或者可以將代碼優化的地方請勞煩告知我。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97874.html
摘要:注意點在鼠標操作拖放期間,有一些事件可能觸發多次,比如和。可拖拽元素,建議使用,設定可拖拽元素的鼠標游標,提升交互。在中使用拖拽中使用可以直接綁定到組件上。 什么是 Drag and Drop (拖放)? 簡單來說,HTML5 提供了 Drag and Drop API,允許用戶用鼠標選中一個可拖動元素,移動鼠標拖放到一個可放置到元素的過程。 我相信每個人都或多或少接觸過拖放,比如瀏覽...
摘要:哪吒別人的看法都是狗屁,你是誰只有你自己說了才算,這是爹教我的道理。哪吒去他個鳥命我命由我,不由天是魔是仙,我自己決定哪吒白白搭上一條人命,你傻不傻敖丙不傻誰和你做朋友太乙真人人是否能夠改變命運,我不曉得。我只曉得,不認命是哪吒的命。 showImg(https://segmentfault.com/img/bVbwiGL?w=900&h=378); 出處 查看github最新的Vue...
摘要:最近公司新加需求實現彈窗可拖拽還要拖拽寬高變化國際慣例先上圖瀏覽器下作的有幾個點需要注意一下每個彈窗都要有唯一可操作指令可以做到拖拽時要添加可拖拽區塊由于組件在設計時寬度用了百分比這里不同瀏覽器有兼容性問題實現拖拽寬高時獲取邊緣問題定位設 最近公司新加需求, 實現彈窗可拖拽, 還要拖拽寬高變化. 國際慣例先上圖: edge瀏覽器下作的gif http://www.lano...
摘要:利用實現圖片裁剪效果圖實現思路打開圖片并將圖片繪制到中利用的函數來裁剪圖片將轉化為即可。巨坑轉化為圖片確認截圖確認截圖參考文章我是,年輕的前端攻城獅一枚,愛專研,愛技術,愛分享。文章有任何問題歡迎大家指出,也歡迎大家一起交流前端各種問題 利用Canvas實現圖片裁剪 效果圖 showImg(https://segmentfault.com/img/bVburJ2?w=864&h=706...
閱讀 3055·2021-11-25 09:43
閱讀 1033·2021-11-24 10:22
閱讀 1361·2021-09-22 15:26
閱讀 689·2019-08-30 15:44
閱讀 2468·2019-08-29 16:33
閱讀 3702·2019-08-26 18:42
閱讀 915·2019-08-23 18:07
閱讀 1837·2019-08-23 17:55