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中的$(document).ready()与window.onload的区别
Nov 18 Javascript
基于jquery的气泡提示效果
May 31 Javascript
js中top/parent/frame概述及案例应用
Feb 06 Javascript
使用控制台破解百小度一个月只准改一次名字
Aug 13 Javascript
jQuery获取父元素及父节点的方法小结
Apr 14 Javascript
JavaScript的Vue.js库入门学习教程
May 23 Javascript
AngularJS深入探讨scope,继承结构,事件系统和生命周期
Nov 02 Javascript
JavaScript箭头函数中的this详解
Jun 19 Javascript
使用layui实现的左侧菜单栏以及动态操作tab项方法
Sep 10 Javascript
vue中使用element ui的弹窗与echarts之间的问题详解
Oct 25 Javascript
Vue Router 实现动态路由和常见问题及解决方法
Mar 06 Javascript
vue实现在进行增删改操作后刷新页面
Aug 05 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
YB217、YB235、YB400浅听
2021/03/02 无线电
用ASP将SQL搜索出来的内容导出为TXT的代码
2007/07/27 Javascript
用js实现计算代码行数的简单方法附代码
2007/08/13 Javascript
select 控制网页内容隐藏于显示的实现代码
2010/05/25 Javascript
基于jQuery的可用于选项卡及幻灯的切换插件
2011/03/28 Javascript
javascript加号&quot;+&quot;的二义性说明
2013/03/04 Javascript
父元素与子iframe相互获取变量和元素对象的具体实现
2013/10/15 Javascript
纯javascript实现分页(两种方法)
2015/08/26 Javascript
浅析jQuery 3.0中的Data
2016/06/14 Javascript
js css+html实现简单的日历
2016/07/14 Javascript
angularjs ui-router中路由的二级嵌套
2017/03/10 Javascript
详解nodejs中express搭建权限管理系统
2017/09/15 NodeJs
面包屑导航详解
2017/12/07 Javascript
vue源码入口文件分析(推荐)
2018/01/30 Javascript
webpack4的迁移的使用方法
2018/05/25 Javascript
layui中table表头样式修改方法
2018/08/15 Javascript
vue-cli3脚手架的配置及使用教程
2018/08/28 Javascript
解决vuecli3.0热更新失效的问题
2018/09/19 Javascript
javascript中floor使用方法总结
2019/02/02 Javascript
移动端自适应flexible.js的使用方法(不用三大框架,仅写一个单html页面使用)推荐
2019/04/02 Javascript
vue-cli history模式实现tomcat部署报404的解决方式
2019/09/06 Javascript
微信小程序后端(java)开发流程的详细步骤
2019/11/13 Javascript
[01:51]2014DOTA2西雅图邀请赛 MVP 外卡赛black场间采访
2014/07/09 DOTA
python使用wxpython开发简单记事本的方法
2015/05/20 Python
浅谈python多线程和队列管理shell程序
2015/08/04 Python
python脚本实现xls(xlsx)转成csv
2016/04/10 Python
浅析AST抽象语法树及Python代码实现
2016/06/06 Python
Python中强大的命令行库click入门教程
2016/12/26 Python
python中异常捕获方法详解
2017/03/03 Python
Python基于回溯法子集树模板解决数字组合问题实例
2017/09/02 Python
python @classmethod 的使用场合详解
2019/08/23 Python
阿里云:Aliyun.com
2017/02/15 全球购物
介绍一下javax.servlet.Servlet接口及其主要方法
2015/11/30 面试题
詹天佑教学反思
2014/04/30 职场文书
九九重阳节致辞
2015/07/31 职场文书
Mysql开启外网访问
2022/05/15 MySQL