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实现unicode和字符的互相转换
Jul 18 Javascript
用jquery实现下拉菜单效果的代码
Jul 25 Javascript
初窥JQuery-Jquery简介 入门了解篇
Nov 25 Javascript
jquery 学习之二 属性(html()与html(val))
Nov 25 Javascript
jQuery拖拽 &amp; 弹出层 介绍与示例
Dec 27 Javascript
Jquery EasyUI中弹出确认对话框以及加载效果示例代码
Feb 13 Javascript
js 动态给元素添加、移除事件的实现方法
Jul 19 Javascript
基于JavaScript实现购物车功能
Feb 07 Javascript
AngularJS表单提交实例详解
Feb 18 Javascript
利用JS hash制作单页Web应用的方法详解
Oct 10 Javascript
JavaScript设计模式之装饰者模式定义与应用示例
Jul 25 Javascript
keep-alive不能缓存多层级路由菜单问题解决
Mar 10 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 session 预定义数组
2009/03/16 PHP
PHP中实现Bloom Filter算法
2015/03/30 PHP
joomla数据库操作示例代码
2016/01/06 PHP
PHP环形链表实现方法示例
2017/09/15 PHP
PHP实现QQ、微信和支付宝三合一收款码实例代码
2018/02/19 PHP
jquery的Tooltip插件 qtip使用详细说明
2010/09/08 Javascript
jquery 无限级联菜单案例分享
2013/03/26 Javascript
JavaScript等比例缩放图片控制超出范围的图片
2013/08/06 Javascript
JSON序列化与解析原生JS方法且IE6和chrome测试通过
2013/09/05 Javascript
网页防止tab键的使用快速解决方法
2013/11/07 Javascript
js弹窗返回值详解(window.open方式)
2014/01/11 Javascript
JavaScript中使用Math.floor()方法对数字取整
2015/06/15 Javascript
jquery+css实现绚丽的横向二级下拉菜单-附源码下载
2015/08/23 Javascript
jqGrid 学习笔记整理——进阶篇(一 )
2016/04/17 Javascript
jquery获取点击控件的绝对位置简单实例
2016/10/13 Javascript
JavaScript常用数学函数用法示例
2018/05/14 Javascript
微信小程序实现蒙版弹窗效果
2018/11/01 Javascript
js设计模式之单例模式原理与用法详解
2019/08/15 Javascript
详解vue-video-player使用心得(兼容m3u8)
2019/08/23 Javascript
小程序中设置缓存过期的实现方法
2020/01/14 Javascript
举例讲解Python中is和id的用法
2015/04/03 Python
Python 中 Meta Classes详解
2016/02/13 Python
Python中几种属性访问的区别与用法详解
2018/10/10 Python
详解Python中的编码问题(encoding与decode、str与bytes)
2020/09/30 Python
canvas实现俄罗斯方块的方法示例
2018/12/13 HTML / CSS
HTML5进阶段内联标签汇总(小篇)
2016/07/13 HTML / CSS
柏林通行证:Berlin Pass
2018/04/11 全球购物
美津浓巴西官方网站:Mizuno巴西
2019/07/24 全球购物
经理秘书岗位职责
2013/11/14 职场文书
大学运动会入场词
2014/02/22 职场文书
项目经理助理岗位职责
2015/04/13 职场文书
公司表扬信格式
2015/05/04 职场文书
离婚起诉书范文2015
2015/05/19 职场文书
优秀范文:《但愿人长久》教学反思3篇
2019/10/24 职场文书
JS新手入门数组处理的实用方法汇总
2021/04/07 Javascript
Redis 配置文件重要属性的具体使用
2021/05/20 Redis