javascript動(dòng)畫(huà)之磁性吸附效果篇
前面的話(huà)
上一篇,我們介紹了javascript動(dòng)畫(huà)之模擬拖拽效果篇。但在實(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)文章
跟我學(xué)習(xí)javascript的this關(guān)鍵字
跟我學(xué)習(xí)javascript的this關(guān)鍵字,this是動(dòng)態(tài)綁定,或稱(chēng)為運(yùn)行期綁定的,這就導(dǎo)致 JavaScript中的this關(guān)鍵字有能力具備多重含義,帶來(lái)靈活性的同時(shí),也為初學(xué)者帶來(lái)不少困惑2015-11-11
javascript中獲取選中對(duì)象的類(lèi)型
javascript中獲取選中對(duì)象的類(lèi)型...2007-04-04
使用 JavaScript 創(chuàng)建并下載文件(模擬點(diǎn)擊)
本文將介紹如何使用 JavaScript 創(chuàng)建文件,并自動(dòng)/手動(dòng)將文件下載,這在導(dǎo)出原始數(shù)據(jù)時(shí)會(huì)比較方便2019-10-10
Javascript中克隆一個(gè)數(shù)組的實(shí)現(xiàn)代碼
這篇文章主要是對(duì)在Javascript中克隆一個(gè)數(shù)組的實(shí)現(xiàn)代碼進(jìn)行了介紹。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-12-12
JS基于FileSaver.js插件實(shí)現(xiàn)文件保存功能示例
這篇文章主要介紹了JS基于FileSaver.js插件實(shí)現(xiàn)文件保存功能,結(jié)合實(shí)例形式演示了FileSaver.js插件的具體使用技巧,需要的朋友可以參考下2016-12-12
再談querySelector和querySelectorAll的區(qū)別與聯(lián)系
先按W3C的規(guī)范來(lái)說(shuō)這兩個(gè)方法應(yīng)該返回的內(nèi)容吧,大家先看下官方的解釋?zhuān)缓蟾鶕?jù)需要選擇使用2012-04-04
JS網(wǎng)絡(luò)游戲-(模擬城市webgame)提供的一些例子下載
JS網(wǎng)絡(luò)游戲-(模擬城市webgame)提供的一些例子下載...2007-10-10
真正好用的js驗(yàn)證上傳文件大小的簡(jiǎn)單方法
下面小編就為大家?guī)?lái)一篇真正好用的js驗(yàn)證上傳文件大小的簡(jiǎn)單方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10

