javascript動(dòng)畫之磁性吸附效果篇
前面的話
上一篇,我們介紹了javascript動(dòng)畫之模擬拖拽效果篇。但在實(shí)際應(yīng)用中,常常需要為拖拽的元素限定范圍。而通過(guò)限定范圍,再增加一些輔助的措施,就可以實(shí)現(xiàn)磁性吸附的效果
范圍限定
如果我們限定元素只可以在可視范圍內(nèi)移動(dòng),那么就需要對(duì)其進(jìn)行范圍限定
首先,先要搞清楚是可視區(qū)域限定被拖拽元素
左側(cè)范圍L0 = 0
右側(cè)范圍R0 = document.documentElement.clientWidth
上側(cè)范圍T0 = 0
下側(cè)范圍B0 = document.documentElement.clientHeight
元素的上下左右四邊分別為
左側(cè)邊 L = offsetLeft
右側(cè)邊 R = offsetLeft + offsetWidth
上側(cè)邊 T = offsetTop
下側(cè)邊 B = offsetTop + offsetHeight
function limitedRange(obj,fn){ var L0 = 0; var R0 = document.documentElement.clientWidth; var T0 = 0; var B0 = document.documentElement.clientHeight; var L = obj.offsetLeft; var R = obj.offsetLeft + obj.offsetWidth; var T = obj.offsetTop; var B = obj.offsetTop + obj.offsetHeight; if(L >= L0 && R <= R0 && T >= T0 && B <= B0){ fn(obj); } }
拖拽范圍
如果將范圍限定用在拖拽元素上,則需要一些改變
首先,限定條件并不是在范圍內(nèi)執(zhí)行什么,而是不在范圍內(nèi)時(shí),應(yīng)該執(zhí)行什么
由于在拖拽實(shí)現(xiàn)中,已經(jīng)獲取了元素距離可視區(qū)域左上角的X軸和Y軸的距離,所以不需要再通過(guò)offsetLeft和offsetTop進(jìn)行重新獲取
<div id="test" style="height: 100px;width: 100px;background:pink;position:absolute;top:0;left:0;">測(cè)試文字</div> <script> function drag(obj){ obj.onmousedown = function(e){ e = e || event; //獲取元素距離定位父級(jí)的x軸及y軸距離 var x0 = this.offsetLeft; var y0 = this.offsetTop; //獲取此時(shí)鼠標(biāo)距離視口左上角的x軸及y軸距離 var x1 = e.clientX; var y1 = e.clientY; //鼠標(biāo)按下時(shí),獲得此時(shí)的頁(yè)面區(qū)域 var L0 = 0; var R0 = document.documentElement.clientWidth; var T0 = 0; var B0 = document.documentElement.clientHeight; //鼠標(biāo)按下時(shí),獲得此時(shí)的元素寬高 var EH = obj.offsetHeight; var EW = obj.offsetWidth; document.onmousemove = function(e){ e = e || event; //獲取此時(shí)鼠標(biāo)距離視口左上角的x軸及y軸距離 x2 = e.clientX; y2 = e.clientY; //計(jì)算此時(shí)元素應(yīng)該距離視口左上角的x軸及y軸距離 var X = x0 + (x2 - x1); var Y = y0 + (y2 - y1); /******范圍限定*******/ //獲取鼠標(biāo)移動(dòng)時(shí)元素四邊的瞬時(shí)值 var L = X; var R = X + EW; var T = Y; var B = Y + EH; //在將X和Y賦值給left和top之前,進(jìn)行范圍限定 //只有在范圍內(nèi)時(shí),才進(jìn)行相應(yīng)的移動(dòng) //如果脫離左側(cè)范圍,則left置L0 if(L < L0){X = L0;} //如果脫離右側(cè)范圍,則left置為R0 if(R > R0){X = R0 - EW;} //如果脫離上側(cè)范圍,則top置T0 if(T < T0){Y = T0;} //如果脫離下側(cè)范圍,則top置為B0 if(B > B0){Y = B0 - EH;} obj.style.left = X + 'px'; obj.style.top = Y + 'px'; } document.onmouseup = function(e){ //當(dāng)鼠標(biāo)抬起時(shí),拖拽結(jié)束,則將onmousemove賦值為null即可 document.onmousemove = null; //釋放全局捕獲 if(obj.releaseCapture){ obj.releaseCapture(); } } //阻止默認(rèn)行為 return false; //IE8-瀏覽器阻止默認(rèn)行為 if(obj.setCapture){ obj.setCapture(); } } } drag(test); </script>
磁性吸附
磁性吸附只需要在范圍限定的基礎(chǔ)上,做一些修改即可
下列代碼中,只要元素的四邊,距離可視區(qū)域范圍的四邊小于50px,則元素將直接吸附對(duì)應(yīng)的邊上
<div id="test" style="height: 100px;width: 100px;background:pink;position:absolute;top:0;left:0;">測(cè)試文字</div> <script> function drag(obj){ obj.onmousedown = function(e){ e = e || event; //獲取元素距離定位父級(jí)的x軸及y軸距離 var x0 = this.offsetLeft; var y0 = this.offsetTop; //獲取此時(shí)鼠標(biāo)距離視口左上角的x軸及y軸距離 var x1 = e.clientX; var y1 = e.clientY; //鼠標(biāo)按下時(shí),獲得此時(shí)的頁(yè)面區(qū)域 var L0 = 0; var R0 = document.documentElement.clientWidth; var T0 = 0; var B0 = document.documentElement.clientHeight; //鼠標(biāo)按下時(shí),獲得此時(shí)的元素寬高 var EH = obj.offsetHeight; var EW = obj.offsetWidth; document.onmousemove = function(e){ e = e || event; //獲取此時(shí)鼠標(biāo)距離視口左上角的x軸及y軸距離 x2 = e.clientX; y2 = e.clientY; //計(jì)算此時(shí)元素應(yīng)該距離視口左上角的x軸及y軸距離 var X = x0 + (x2 - x1); var Y = y0 + (y2 - y1); /******磁性吸附*******/ //獲取鼠標(biāo)移動(dòng)時(shí)元素四邊的瞬時(shí)值 var L = X; var R = X + EW; var T = Y; var B = Y + EH; //在將X和Y賦值給left和top之前,進(jìn)行范圍限定 //只有在范圍內(nèi)時(shí),才進(jìn)行相應(yīng)的移動(dòng) //如果到達(dá)左側(cè)的吸附范圍,則left置L0 if(L - L0 < 50){X = L0;} //如果到達(dá)右側(cè)的吸附范圍,則left置為R0 if(R0 - R < 50){X = R0 - EW;} //如果到達(dá)上側(cè)的吸附范圍,則top置T0 if(T - T0 < 50){Y = T0;} //如果到達(dá)右側(cè)的吸附范圍,則top置為B0 if(B0 - B < 50){Y = B0 - EH;} obj.style.left = X + 'px'; obj.style.top = Y + 'px'; } document.onmouseup = function(e){ //當(dāng)鼠標(biāo)抬起時(shí),拖拽結(jié)束,則將onmousemove賦值為null即可 document.onmousemove = null; //釋放全局捕獲 if(obj.releaseCapture){ obj.releaseCapture(); } } //阻止默認(rèn)行為 return false; //IE8-瀏覽器阻止默認(rèn)行為 if(obj.setCapture){ obj.setCapture(); } } } drag(test); </script>
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
最全的JavaScript開發(fā)工具列表 總有一款適合你
最全的JavaScript開發(fā)工具列表分享給你,總有一款適合你!2017-06-06js實(shí)現(xiàn)的點(diǎn)擊超鏈顯示隱藏層
js實(shí)現(xiàn)的點(diǎn)擊超鏈顯示隱藏層...2007-05-05詳解微信小程序用定時(shí)器實(shí)現(xiàn)倒計(jì)時(shí)效果
這篇文章主要介紹了微信小程序用定時(shí)器實(shí)現(xiàn)倒計(jì)時(shí)效果,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04利用javascript實(shí)現(xiàn)一些常用軟件的下載導(dǎo)航
利用javascript實(shí)現(xiàn)一些常用軟件的下載導(dǎo)航,非常不錯(cuò)的應(yīng)用,思路值得借鑒,沒看過(guò)的朋友可以看下。2009-08-08js+html實(shí)現(xiàn)周歲年齡計(jì)算器
這篇文章主要為大家詳細(xì)介紹了js+html實(shí)現(xiàn)周歲年齡計(jì)算器的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06