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 模拟用户点击超链接或者按钮的方法
Oct 25 Javascript
jquery获取一个元素下面相同子元素的个数代码
Jul 31 Javascript
jquery单行文字向上滚动效果的实现代码
Sep 05 Javascript
node.js中的fs.writeFile方法使用说明
Dec 14 Javascript
jQuery实现移动 和 渐变特效的点击事件
Feb 26 Javascript
jQuery删除节点用法示例(remove方法)
Sep 08 Javascript
微信小程序 教程之wxapp 视图容器 view
Oct 19 Javascript
微信小程序 跳转传参数与传对象详解及实例代码
Mar 14 Javascript
ES6中Iterator与for..of..遍历用法分析
Mar 31 Javascript
使用JS和canvas实现gif动图的停止和播放代码
Sep 01 Javascript
vue2.0s中eventBus实现兄弟组件通信的示例代码
Oct 25 Javascript
JS浅拷贝和深拷贝原理与实现方法分析
Feb 28 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实现通用的信用卡验证类
2015/03/24 PHP
简单了解WordPress开发中update_option()函数的用法
2016/01/11 PHP
crontab无法执行php的解决方法
2016/01/25 PHP
PHP使用mysql与mysqli连接Mysql数据库用法示例
2016/07/07 PHP
PHP实现的下载远程文件类定义与用法示例
2017/07/05 PHP
laravel请求参数校验方法
2019/10/10 PHP
js实现动态加载脚本的方法实例汇总
2015/11/02 Javascript
jQuery+CSS实现滑动的标签分栏切换效果
2015/12/17 Javascript
BootstrapValidator不触发校验的实现代码
2016/09/28 Javascript
一步步教你利用Canvas对图片进行处理
2017/09/19 Javascript
Three.js入门之hello world以及如何绘制线
2017/09/25 Javascript
echarts饼图扇区添加点击事件的实例
2017/10/16 Javascript
JS中使用react-tooltip插件实现鼠标悬浮显示框
2019/05/15 Javascript
vue-cli3+ts+webpack实现多入口多出口功能
2019/05/30 Javascript
javascript实现自由编辑图片代码详解
2019/06/21 Javascript
js实现简单音乐播放器
2020/06/30 Javascript
[42:35]2018DOTA2亚洲邀请赛3月30日 小组赛A组 VG VS OpTic
2018/03/31 DOTA
[01:57]2018年度DOTA2最具潜力解说-完美盛典
2018/12/16 DOTA
Python发送Email方法实例
2014/08/21 Python
python引入导入自定义模块和外部文件的实例
2017/07/24 Python
Python2与Python3的区别实例分析
2019/04/11 Python
Python类中方法getitem和getattr详解
2019/08/30 Python
Pytorch Tensor 输出为txt和mat格式方式
2020/01/03 Python
Python如何读写二进制数组数据
2020/08/01 Python
罗兰·穆雷官网:Roland Mouret
2018/09/28 全球购物
皇家阿尔伯特英国官方商店:Royal Albert骨瓷
2019/03/25 全球购物
党员个人思想汇报
2013/12/28 职场文书
大一军训感言
2014/01/09 职场文书
家长评语大全
2014/01/22 职场文书
大学生个人求职口试自我评价
2014/02/16 职场文书
授权委托书公证
2014/09/14 职场文书
2014年营业员工作总结
2014/11/18 职场文书
会议通知
2015/04/15 职场文书
学校运动会通讯稿
2015/07/18 职场文书
大学社团活动总结怎么写
2019/06/21 职场文书
Python实现文本文件拆分写入到多个文本文件的方法
2021/04/18 Python