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 相关文章推荐
Input 特殊事件onpopertychange和oninput
Jun 17 Javascript
jQuery对象和DOM对象使用说明
Jun 25 Javascript
下拉列表选择项的选中在不同浏览器中的兼容性问题探讨
Sep 18 Javascript
鼠标悬浮显示二级菜单效果的jquery实现
Oct 29 Javascript
JavaScript中的依赖注入详解
Mar 18 Javascript
原生javascript实现自动更新的时间日期
Feb 12 Javascript
AngularJS基础 ng-copy 指令实例代码
Aug 01 Javascript
基于Bootstrap框架实现图片切换
Mar 10 Javascript
vue2.0.js的多级联动选择器实现方法
Feb 09 Javascript
vue修改对象的属性值后页面不重新渲染的实例
Aug 09 Javascript
Vue程序化的事件监听器(实例方案详解)
Jan 07 Javascript
vue数据响应式原理知识点总结
Feb 16 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的cURL库功能简介 抓取网页、POST数据及其他
2011/04/07 PHP
php实现插入数组但不影响原有顺序的方法
2015/03/27 PHP
PHP+apc+ajax实现的ajax_upload上传进度条代码
2016/01/25 PHP
PHP结合Mysql数据库实现留言板功能
2016/03/04 PHP
PHP面向对象程序设计高级特性详解(接口,继承,抽象类,析构,克隆等)
2016/12/02 PHP
浅谈thinkphp5 instance 的简单实现
2017/07/30 PHP
a标签的css样式四个状态
2021/03/09 HTML / CSS
firefox火狐浏览器与与ie兼容的2个问题总结
2010/07/20 Javascript
AJAX异步从优酷专辑中采集所有视频及信息(JavaScript代码)
2010/11/20 Javascript
js汉字转拼音实现代码
2013/02/06 Javascript
js获取class的所有元素
2013/03/28 Javascript
javascript实现仿腾讯游戏选择
2015/05/14 Javascript
jQuery实现鼠标点击弹出渐变层的方法
2015/07/09 Javascript
JS实现太极旋转思路分析
2016/12/09 Javascript
基于bootstrap的文件上传控件bootstrap fileinput
2016/12/23 Javascript
详解微信小程序设置底部导航栏目方法
2017/06/29 Javascript
VUE element-ui 写个复用Table组件的示例代码
2017/11/18 Javascript
javaScript实现鼠标在文字上悬浮时弹出悬浮层效果
2020/04/12 Javascript
利用Dectorator分模块存储Vuex状态的实现
2019/02/05 Javascript
JS绘图Flot应用图形绘制异常解决方案
2020/10/16 Javascript
[02:38]DOTA2超级联赛专访Loda 认为IG世界最强
2013/05/27 DOTA
[52:03]DOTA2-DPC中国联赛 正赛 Ehome vs iG BO3 第三场 1月31日
2021/03/11 DOTA
Python 专题三 字符串的基础知识
2017/03/19 Python
Python实现两款计算器功能示例
2017/12/19 Python
python数字图像处理之骨架提取与分水岭算法
2018/04/27 Python
python操作mysql代码总结
2018/06/01 Python
Python集合操作方法详解
2020/02/09 Python
CSS3制作气泡对话框的实例教程
2016/05/10 HTML / CSS
基于HTML5+tracking.js实现刷脸支付功能
2020/04/16 HTML / CSS
Allen Edmonds官方网站:一家美国优质男士鞋类及配饰制造商
2019/03/12 全球购物
美国在线鞋类零售商:LifeStride
2019/06/09 全球购物
德国家用电器购物网站:Premiumshop24
2019/08/22 全球购物
文明村创建实施方案
2014/03/27 职场文书
2014年酒店工作总结与计划
2014/11/17 职场文书
2014年教育培训工作总结
2014/12/08 职场文书
投诉信范文
2015/07/02 职场文书