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 相关文章推荐
javascript中常用编程知识
Apr 08 Javascript
有关javascript的性能优化 (repaint和reflow)
Apr 12 Javascript
javascript实现多级联动下拉菜单的方法
Feb 06 Javascript
jQuery实现淡入淡出二级下拉导航菜单的方法
Aug 28 Javascript
详解JavaScript对Date对象的操作问题(生成一个倒数7天的数组)
Oct 01 Javascript
实例解析jQuery中proxy()函数的用法
May 24 Javascript
JS模仿腾讯图片站的图片翻页按钮效果完整实例
Jun 21 Javascript
jQuery悬停文字提示框插件jquery.tooltipster.js用法示例【附demo源码下载】
Jul 19 Javascript
ES6 javascript的异步操作实例详解
Oct 30 Javascript
jQuery简单判断值是否存在于数组中的方法示例
Apr 17 jQuery
Vue常见面试题整理【值得收藏】
Sep 20 Javascript
vue开发环境配置跨域的方法步骤
Jan 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+memcache实现消息队列案例分享
2014/05/21 PHP
php强制用户转向www域名的方法
2015/06/19 PHP
简单概括PHP的字符串中单引号与双引号的区别
2016/05/07 PHP
用PHP写的一个冒泡排序法的函数简单实例
2016/05/26 PHP
深入理解PHP之源码目录结构与功能说明
2016/06/01 PHP
常用参考资料(手册)下载或者链接
2006/07/22 Javascript
Javascript实例教程(19) 使用HoTMetal(1)
2006/12/23 Javascript
基于jQuery试卷自动排版系统
2010/07/18 Javascript
IE之动态添加DOM节点触发window.resize事件
2010/07/27 Javascript
鼠标放在图片上显示大图的JS代码
2013/03/26 Javascript
JS延迟加载加快页面打开速度示例代码
2013/12/30 Javascript
Jquery插件分享之气泡形提示控件grumble.js
2014/05/20 Javascript
AngularJS中的Promise详细介绍及实例代码
2016/12/13 Javascript
JS使用插件cryptojs进行加密解密数据实例
2017/05/11 Javascript
Vue实现侧边菜单栏手风琴效果实例代码
2018/05/31 Javascript
Angular使用cli生成自定义文件、组件的方法
2018/09/04 Javascript
vue-cli3.0如何使用CDN区分开发、生产、预发布环境
2018/11/22 Javascript
Javascript迭代、递推、穷举、递归常用算法实例讲解
2019/02/01 Javascript
详解一个小实例理解js原型和继承
2019/04/24 Javascript
详解为element-ui的Select和Cascader添加弹层底部操作按钮
2020/02/07 Javascript
[05:14]辉夜杯主赛事第二日 RECAP精彩回顾
2015/12/27 DOTA
[01:38:19]夜魇凡尔赛茶话会 第五期
2021/03/11 DOTA
python基于itchat实现微信群消息同步机器人
2017/02/27 Python
Python编程实现的图片识别功能示例
2017/08/03 Python
Python数据可视化实现正态分布(高斯分布)
2019/08/21 Python
使用Python给头像戴上圣诞帽的图像操作过程解析
2019/09/20 Python
python初步实现word2vec操作
2020/06/09 Python
突袭HTML5之Javascript API扩展2—地理信息服务及地理位置API学习
2013/01/31 HTML / CSS
2014学校庆三八妇女节活动总结
2014/03/01 职场文书
第一批党的群众路线教育实践活动工作总结
2014/03/03 职场文书
建筑工程专业大学生求职信
2014/04/23 职场文书
2015年酒店工作总结范文
2015/04/07 职场文书
教学质量月活动总结
2015/05/11 职场文书
校园广播站开场白
2015/06/01 职场文书
推广普通话主题班会
2015/08/17 职场文书
如何开启Apache,Nginx和IIS服务器的GZIP压缩功能
2022/04/29 Servers