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 相关文章推荐
Google Suggest ;-) 基于js的动态下拉菜单
Oct 11 Javascript
利用404错误页面实现UrlRewrite的实现代码
Aug 20 Javascript
img onload事件绑定各浏览器均可执行
Dec 19 Javascript
jquery实现两边飘浮可关闭的对联广告
Nov 27 Javascript
基于JavaScript实现图片点击弹出窗口而不是保存
Feb 06 Javascript
JS克隆,属性,数组,对象,函数实例分析
Nov 26 Javascript
JS中绑定事件顺序(事件冒泡与事件捕获区别)
Jan 24 Javascript
JS实现将二维数组转为json格式字符串操作示例
Jul 12 Javascript
angular 未登录状态拦截路由跳转的方法
Oct 09 Javascript
JS实现带阴历的日历功能详解
Jan 24 Javascript
JavaScript实现左右滚动电影画布
Feb 06 Javascript
详解JavaScript的计时器和按钮效果设置
Feb 18 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使用GIFEncoder类生成的GIF动态图片验证码
2014/07/01 PHP
PHP中设置一个严格30分钟过期Session面试题的4种答案
2014/07/30 PHP
php for 循环使用的简单实例
2016/06/02 PHP
PHP之图片上传类实例代码(加了缩略图)
2016/06/30 PHP
php array_reverse 以相反的顺序返回数组实例代码
2017/04/11 PHP
Jquery阻止事件冒泡 event.stopPropagation
2011/12/11 Javascript
利用谷歌地图API获取点与点的距离的js代码
2012/10/11 Javascript
HTML5之lang属性与dir属性的详解
2013/06/19 Javascript
jQuery on()方法示例及jquery on()方法的优点
2015/08/27 Javascript
JS组件Bootstrap Table使用方法详解
2016/02/02 Javascript
jQuery实现的鼠标经过时变宽的效果(附demo源码)
2016/04/28 Javascript
使用js获取地址栏参数的方法推荐(超级简单)
2016/06/14 Javascript
纯JavaScript 实现flappy bird小游戏实例代码
2016/09/27 Javascript
详解Angular4中路由Router类的跳转navigate
2017/06/09 Javascript
jQuery制作input提示内容(兼容IE8以上)
2017/07/05 jQuery
详解VueJS 数据驱动和依赖追踪分析
2017/07/26 Javascript
JavaScript正则表达式校验与递归函数实际应用实例解析
2017/08/04 Javascript
使用cookie绕过验证码登录的实现代码
2017/10/12 Javascript
解决angularjs前后端分离调用接口传递中文时中文乱码的问题
2018/08/13 Javascript
vue自定义标签和单页面多路由的实现代码
2020/05/03 Javascript
终端命令查看TensorFlow版本号及路径的方法
2018/06/13 Python
使用Filter过滤python中的日志输出的实现方法
2019/07/17 Python
keras训练浅层卷积网络并保存和加载模型实例
2020/07/02 Python
Python 在 VSCode 中使用 IPython Kernel 的方法详解
2020/09/05 Python
python实现学生信息管理系统源码
2021/02/22 Python
H&M美国官网:欧洲最大的服饰零售商
2016/09/07 全球购物
意大利专业化妆品品牌:KIKO MILANO
2017/02/01 全球购物
嘻哈珠宝品牌:KRKC&CO
2020/10/19 全球购物
中医药大学毕业生自荐信
2013/11/08 职场文书
门市房租房协议书
2014/12/04 职场文书
成绩单家长意见
2015/06/03 职场文书
草房子读书笔记
2015/06/29 职场文书
运动员加油词
2015/07/18 职场文书
纯CSS实现酷炫的霓虹灯效果
2021/04/13 HTML / CSS
Python如何利用pandas读取csv数据并绘图
2022/07/07 Python
django项目、vue项目部署云服务器的详细过程
2022/07/23 Servers