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 相关文章推荐
关于Aptana Studio生成自动备份文件的解决办法
Dec 23 Javascript
解析URI与URL之间的区别与联系
Nov 22 Javascript
jQuery往textarea中光标所在位置插入文本的方法
Jun 26 Javascript
jQuery仿淘宝网产品品牌隐藏与显示效果
Sep 01 Javascript
浅析JavaScript作用域链、执行上下文与闭包
Feb 01 Javascript
详解Angular中的自定义服务Service、Provider以及Factory
Apr 22 Javascript
XMLHttpRequest对象_Ajax异步请求重点(推荐)
Sep 28 Javascript
vue项目中jsonp跨域获取qq音乐首页推荐问题
May 30 Javascript
JS精确判断数据类型代码实例
Dec 18 Javascript
原生JS实现烟花效果
Mar 10 Javascript
详解JavaScript之Array.reduce源码解读
Nov 01 Javascript
vue3.0实现点击切换验证码(组件)及校验
Nov 18 Vue.js
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的博客ping服务代码
2012/02/04 PHP
php curl post 时出现的问题解决
2014/01/30 PHP
jquery创建一个新的节点对象(自定义结构/内容)的好方法
2013/01/21 Javascript
jquery中ajax函数执行顺序问题之如何设置同步
2014/02/28 Javascript
js从Cookies里面取值的简单实现
2014/06/30 Javascript
Node.js实现在目录中查找某个字符串及所在文件
2014/09/03 Javascript
js使用split函数按照多个字符对字符串进行分割的方法
2015/03/20 Javascript
jQuery控制li上下循环滚动插件用法实例(附demo源码下载)
2016/05/28 Javascript
Angular的Bootstrap(引导)和Compiler(编译)机制
2016/06/20 Javascript
vue router-link传参以及参数的使用实例
2017/11/10 Javascript
vue 实现边输入边搜索功能的实例讲解
2018/09/16 Javascript
详解如何制作并发布一个vue的组件的npm包
2018/11/10 Javascript
vue在路由中验证token是否存在的简单实现
2019/11/11 Javascript
在vue中使用Echarts画曲线图的示例
2020/10/03 Javascript
[00:43]拉比克至宝魔导师密钥展示
2018/12/20 DOTA
在Python中使用元类的教程
2015/04/28 Python
利用Python实现颜色色值转换的小工具
2016/10/27 Python
django使用图片延时加载引起后台404错误
2017/04/18 Python
终端命令查看TensorFlow版本号及路径的方法
2018/06/13 Python
Python实例方法、类方法、静态方法的区别与作用详解
2019/03/25 Python
在django-xadmin中APScheduler的启动初始化实例
2019/11/15 Python
TensorFlow实现自定义Op方式
2020/02/04 Python
jupyter实现重新加载模块
2020/04/16 Python
使用keras和tensorflow保存为可部署的pb格式
2020/05/25 Python
Pycharm常用快捷键总结及配置方法
2020/11/14 Python
用python爬虫批量下载pdf的实现
2020/12/01 Python
CSS3 选择器 基本选择器介绍
2012/01/21 HTML / CSS
俄罗斯在线购买飞机票、火车票、巴士票网站:Tutu.ru
2020/03/16 全球购物
小学三年级数学教学反思
2014/01/31 职场文书
员工生日会策划方案
2014/06/14 职场文书
法制宣传标语集锦
2014/06/25 职场文书
幼儿园开学通知
2015/04/24 职场文书
环保建议书范文
2015/09/14 职场文书
2016年圣诞节义工活动总结
2016/04/01 职场文书
HTML速写之Emmet语法规则的实现
2021/04/07 HTML / CSS
idea编译器vue缩进报错问题场景分析
2021/07/04 Vue.js