首页 > 代码库 > javascript动画系列第二篇——磁性吸附

javascript动画系列第二篇——磁性吸附

×
目录
[1]范围限定 [2]拖拽范围 [3]磁性吸附

前面的话

  上一篇,我们介绍了元素拖拽的实现。但在实际应用中,常常需要为拖拽的元素限定范围。而通过限定范围,再增加一些辅助的措施,就可以实现磁性吸附的效果

 

范围限定

  如果我们限定元素只可以在可视范围内移动,那么就需要对其进行范围限定

  首先,先要搞清楚是可视区域限定被拖拽元素

  左侧范围L0 = 0

  右侧范围R0 = document.documentElement.clientWidth

  上侧范围T0 = 0

  下侧范围B0 = document.documentElement.clientHeight

  元素的上下左右四边分别为

  左侧边 L = offsetLeft

  右侧边 R = offsetLeft + offsetWidth

  上侧边 T = offsetTop

  下侧边 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);    }}

 

拖拽范围

  如果将范围限定用在拖拽元素上,则需要一些改变

  首先,限定条件并不是在范围内执行什么,而是不在范围内时,应该执行什么

  由于在拖拽实现中,已经获取了元素距离可视区域左上角的X轴和Y轴的距离,所以不需要再通过offsetLeft和offsetTop进行重新获取

<div id="test" style="height: 100px;width: 100px;background:pink;position:absolute;top:0;left:0;">测试文字</div><script>function drag(obj){    obj.onmousedown = function(e){        e = e || event;        //获取元素距离定位父级的x轴及y轴距离        var x0 = this.offsetLeft;        var y0 = this.offsetTop;        //获取此时鼠标距离视口左上角的x轴及y轴距离        var x1 = e.clientX;        var y1 = e.clientY;        //鼠标按下时,获得此时的页面区域        var L0 = 0;        var R0 = document.documentElement.clientWidth;        var T0 = 0;        var B0 = document.documentElement.clientHeight;        //鼠标按下时,获得此时的元素宽高        var EH = obj.offsetHeight;        var EW = obj.offsetWidth;        document.onmousemove = function(e){            e = e || event;            //获取此时鼠标距离视口左上角的x轴及y轴距离            x2 = e.clientX;            y2 = e.clientY;                //计算此时元素应该距离视口左上角的x轴及y轴距离            var X = x0 + (x2 - x1);            var Y = y0 + (y2 - y1);            /******范围限定*******/            //获取鼠标移动时元素四边的瞬时值            var L = X;            var R = X + EW;            var T = Y;            var B = Y + EH;            //在将X和Y赋值给left和top之前,进行范围限定            //只有在范围内时,才进行相应的移动            //如果脱离左侧范围,则left置L0            if(L < L0){X = L0;}            //如果脱离右侧范围,则left置为R0            if(R > R0){X = R0 - EW;}            //如果脱离上侧范围,则top置T0            if(T < T0){Y = T0;}            //如果脱离下侧范围,则top置为B0            if(B > B0){Y = B0 - EH;}            obj.style.left = X + px;            obj.style.top = Y + px;        }        document.onmouseup = function(e){            //当鼠标抬起时,拖拽结束,则将onmousemove赋值为null即可            document.onmousemove = null;            //释放全局捕获            if(obj.releaseCapture){                obj.releaseCapture();            }        }        //阻止默认行为        return false;        //IE8-浏览器阻止默认行为        if(obj.setCapture){            obj.setCapture();        }    }    }drag(test);</script>    

<iframe style="width: 100%; height: 200px;" src="http://sandbox.runjs.cn/show/gmqg0mjl" frameborder="0" width="320" height="240"></iframe>

磁性吸附

  磁性吸附只需要在范围限定的基础上,做一些修改即可

  下列代码中,只要元素的四边,距离可视区域范围的四边小于50px,则元素将直接吸附对应的边上

<div id="test" style="height: 100px;width: 100px;background:pink;position:absolute;top:0;left:0;">测试文字</div><script>function drag(obj){    obj.onmousedown = function(e){        e = e || event;        //获取元素距离定位父级的x轴及y轴距离        var x0 = this.offsetLeft;        var y0 = this.offsetTop;        //获取此时鼠标距离视口左上角的x轴及y轴距离        var x1 = e.clientX;        var y1 = e.clientY;        //鼠标按下时,获得此时的页面区域        var L0 = 0;        var R0 = document.documentElement.clientWidth;        var T0 = 0;        var B0 = document.documentElement.clientHeight;        //鼠标按下时,获得此时的元素宽高        var EH = obj.offsetHeight;        var EW = obj.offsetWidth;        document.onmousemove = function(e){            e = e || event;            //获取此时鼠标距离视口左上角的x轴及y轴距离            x2 = e.clientX;            y2 = e.clientY;                //计算此时元素应该距离视口左上角的x轴及y轴距离            var X = x0 + (x2 - x1);            var Y = y0 + (y2 - y1);            /******磁性吸附*******/            //获取鼠标移动时元素四边的瞬时值            var L = X;            var R = X + EW;            var T = Y;            var B = Y + EH;            //在将X和Y赋值给left和top之前,进行范围限定            //只有在范围内时,才进行相应的移动            //如果到达左侧的吸附范围,则left置L0            if(L - L0 < 50){X = L0;}            //如果到达右侧的吸附范围,则left置为R0            if(R0 - R < 50){X = R0 - EW;}            //如果到达上侧的吸附范围,则top置T0            if(T - T0 < 50){Y = T0;}            //如果到达右侧的吸附范围,则top置为B0            if(B0 - B < 50){Y = B0 - EH;}            obj.style.left = X + px;            obj.style.top = Y + px;        }        document.onmouseup = function(e){            //当鼠标抬起时,拖拽结束,则将onmousemove赋值为null即可            document.onmousemove = null;            //释放全局捕获            if(obj.releaseCapture){                obj.releaseCapture();            }        }        //阻止默认行为        return false;        //IE8-浏览器阻止默认行为        if(obj.setCapture){            obj.setCapture();        }    }    }drag(test);</script>    

<iframe style="width: 100%; height: 300px;" src="http://sandbox.runjs.cn/show/fcpidmk0" frameborder="0" width="320" height="240"></iframe>

<script type="text/javascript">// 0){ return; } if(select[i].getBoundingClientRect().top <= 0 && select[i+1]){ if(select[i+1].getBoundingClientRect().top > 0){ change(oCon.children[i+2]) } }else{ change(oCon.children[select.length+1]) } }}document.body.onmousewheel = wheel;document.body.addEventListener(‘DOMMouseScroll‘,wheel,false);var oCon = document.getElementById("content");var close = oCon.getElementsByTagName(‘span‘)[0];close.onclick = function(){ if(this.innerHTML == ‘显示目录‘){ this.innerHTML = ‘ב; this.style.background = ‘‘; oCon.style.border = ‘2px solid #ccc‘; oCon.style.width = ‘‘; oCon.style.height = ‘‘; oCon.style.overflow = ‘‘; oCon.style.lineHeight = ‘30px‘; }else{ this.innerHTML = ‘显示目录‘; this.style.background = ‘#3399ff‘; oCon.style.border = ‘none‘; oCon.style.width = ‘60px‘; oCon.style.height = ‘30px‘; oCon.style.overflow = ‘hidden‘; oCon.style.lineHeight = ‘‘; }}for(var i = 2; i < oCon.children.length; i++){ oCon.children[i].onmouseover = function(){ this.style.color = ‘#3399ff‘; } oCon.children[i].onmouseout = function(){ this.style.color = ‘inherit‘; if(this.mark){ this.style.color = ‘#3399ff‘; } } oCon.children[i].onclick = function(){ change(this); } }function change(_this){ for(var i = 2; i < oCon.children.length; i++){ oCon.children[i].mark = false; oCon.children[i].style.color = ‘inherit‘; oCon.children[i].style.textDecoration = ‘none‘; oCon.children[i].style.borderColor = ‘transparent‘; } _this.mark = true; _this.style.color = ‘#3399ff‘; _this.style.textDecoration = ‘underline‘; _this.style.borderColor = ‘#2175bc‘; }// ]]></script><script type="text/javascript" src="http://files.cnblogs.com/files/xiaohuochai/contextMenu.js"></script>

javascript动画系列第二篇——磁性吸附