javascript动画之磁性吸附效果篇


Posted in Javascript onDecember 09, 2016

前面的话

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

范围限定

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

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

左侧范围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>

磁性吸附

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

下列代码中,只要元素的四边,距离可视区域范围的四边小于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>

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
基于jQuery实现交互体验社会化分享代码附源码下载
Jan 04 Javascript
使用jQuery UI库开发Web界面的简单入门指引
Apr 22 Javascript
利用Angularjs实现幻灯片效果
Sep 07 Javascript
javascript 闭包详解及简单实例应用
Dec 31 Javascript
利用jquery实现实时更新歌词的方法
Jan 06 Javascript
jquery 实现复选框的全选操作实例代码
Jan 24 Javascript
老生常谈javascript的面向对象思想
Aug 22 Javascript
浅谈Node Inspector 代理实现
Oct 19 Javascript
详解webpack + react + react-router 如何实现懒加载
Nov 20 Javascript
JavaScript监听触摸事件代码实例
Dec 30 Javascript
vuex入门最详细整理
Mar 04 Javascript
JS 数组和对象的深拷贝操作示例
Jun 06 Javascript
Canvas 制作动态进度加载水球详解及实例代码
Dec 09 #Javascript
详解自动生成博客目录案例
Dec 09 #Javascript
微信小程序之仿微信漂流瓶实例
Dec 09 #Javascript
JS判断是否手机或pad访问实现方法
Dec 09 #Javascript
js实现一个可以兼容PC端和移动端的div拖动效果实例
Dec 09 #Javascript
利用JS实现页面删除并重新排序功能
Dec 09 #Javascript
Bootstrap table使用方法详细介绍
Dec 09 #Javascript
You might like
PHP Pear 安装及使用
2009/03/19 PHP
PHP类与对象中的private访问控制的疑问
2012/11/01 PHP
php给一组指定关键词添加span标签的方法
2015/03/31 PHP
php eval函数一句话木马代码
2015/05/21 PHP
Symfony2实现从数据库获取数据的方法小结
2016/03/18 PHP
浅析PHP中的 inet_pton 网络函数
2019/12/16 PHP
JavaScript判断访问的来源是手机还是电脑,用的哪种浏览器
2013/12/12 Javascript
innerHTML属性,outerHTML属性,textContent属性,innerText属性区别详解
2015/03/13 Javascript
JS打字效果的动态菜单代码分享
2015/08/21 Javascript
javascript随机抽取0-100之间不重复的10个数
2016/02/25 Javascript
JavaScript闭包实例详解
2016/06/03 Javascript
用Vue.js实现监听属性的变化
2016/11/17 Javascript
遍历json 对象的属性并且动态添加属性的实现
2016/12/02 Javascript
Vue数据驱动模拟实现3
2017/01/11 Javascript
vuex actions传递多参数的处理方法
2018/09/18 Javascript
浅析vue-router原理
2018/10/19 Javascript
微信小程序实现多图上传
2020/06/19 Javascript
[03:04]2018年度DOTA2玩家最喜爱的主播-完美盛典
2018/12/16 DOTA
Python中用startswith()函数判断字符串开头的教程
2015/04/07 Python
状态机的概念和在Python下使用状态机的教程
2015/04/11 Python
在Python的gevent框架下执行异步的Solr查询的教程
2015/04/16 Python
python+matplotlib绘制3D条形图实例代码
2018/01/17 Python
python爬虫之快速对js内容进行破解
2019/07/09 Python
使用Python和Scribus创建一个RGB立方体的方法
2019/07/17 Python
使用python制作游戏下载进度条的代码(程序说明见注释)
2019/10/24 Python
解决Python Matplotlib绘图数据点位置错乱问题
2020/05/16 Python
python实现定时发送邮件
2020/12/23 Python
Oracle性能调优原则
2012/05/03 面试题
2015年食品安全宣传周活动总结
2015/07/09 职场文书
2016春季幼儿园小班开学寄语
2015/12/03 职场文书
2016大学生国家助学贷款承诺书
2016/03/25 职场文书
Spring Boot mybatis-config 和 log4j 输出sql 日志的方式
2021/07/26 Java/Android
logback 实现给变量指定默认值
2021/08/30 Java/Android
Python利用capstone实现反汇编
2022/04/06 Python
Golang原生rpc(rpc服务端源码解读)
2022/04/07 Golang
ssh服务器拒绝了密码 请再试一次已解决(亲测有效)
2022/08/14 Servers