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 相关文章推荐
发布BlueShow v1.0 图片浏览器(类似lightbox)blueshow.js 打包下载
Jul 21 Javascript
jQuery 使用个人心得
Feb 26 Javascript
javascript获取和判断浏览器窗口、屏幕、网页的高度、宽度等
May 08 Javascript
JavaScript常用的弹出广告及背投广告实现方法
Feb 06 Javascript
JavaScript动态生成二维码图片
Apr 20 Javascript
基于jQuery实现滚动切换效果
Dec 02 Javascript
jQuery实现鼠标滑过预览图片大图效果的方法
Apr 26 jQuery
基于Node.js模板引擎教程-jade速学与实战1
Sep 17 Javascript
vue debug 二种方法
Sep 16 Javascript
浅谈React碰到v-if
Nov 04 Javascript
jQuery实现查看图片功能
Dec 01 jQuery
JS实现数组去重的11种方法总结
Apr 04 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 无法载入mysql扩展
2010/03/12 PHP
分享一下贝贝成长进度的php代码
2012/09/14 PHP
54个提高PHP程序运行效率的方法
2015/07/19 PHP
一个可以显示阴历的JS代码
2007/03/05 Javascript
解决AJAX中跨域访问出现'没有权限'的错误
2008/08/20 Javascript
获取客户端电脑日期时间js代码(jquery)
2012/09/12 Javascript
2014最热门的JavaScript代码高亮插件推荐
2014/11/25 Javascript
js动态切换图片的方法
2015/01/20 Javascript
JS与jQuery遍历Table所有单元格内容的方法
2015/12/07 Javascript
原生js实现无限循环轮播图效果
2017/01/20 Javascript
angularjs2中父子组件的数据传递的实例代码
2017/07/05 Javascript
js核心基础之构造函数constructor用法实例分析
2019/05/11 Javascript
Vuex 模块化使用详解
2019/07/31 Javascript
[55:23]VGJ.T vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
django开发之settings.py中变量的全局引用详解
2017/03/29 Python
Python实现的双色球生成功能示例
2017/12/18 Python
详解python中asyncio模块
2018/03/03 Python
Python pymongo模块用法示例
2018/03/31 Python
python实现textrank关键词提取
2018/06/22 Python
详解Python中is和==的区别
2019/03/21 Python
Linux下远程连接Jupyter+pyspark部署教程
2019/06/21 Python
Python爬取智联招聘数据分析师岗位相关信息的方法
2019/08/13 Python
Python中的相关分析correlation analysis的实现
2019/08/29 Python
Python操作qml对象过程详解
2019/09/26 Python
Django实现auth模块下的登录注册与注销功能
2019/10/10 Python
python 使用pygame工具包实现贪吃蛇游戏(多彩版)
2019/10/30 Python
在Python中通过threshold创建mask方式
2020/02/19 Python
对django 2.x版本中models.ForeignKey()外键说明介绍
2020/03/30 Python
美国网上花店:JustFlowers
2017/02/12 全球购物
美国亚马逊旗下男装网站:East Dane(支持中文)
2019/09/25 全球购物
澳大利亚排名第一的露营和户外设备在线零售商:Outbax
2020/05/06 全球购物
家长会主持词开场白
2014/03/18 职场文书
捐助倡议书范文
2014/04/15 职场文书
乡镇防汛工作汇报
2014/10/28 职场文书
人生哲理妙语30条:淡写流年,笑过人生
2019/09/04 职场文书
python函数的两种嵌套方法使用
2022/04/02 Python