前面的话

上一篇,我们介绍了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>

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!

标签:
js,动画,磁性吸附

免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
评论“javascript动画之磁性吸附效果篇”
暂无“javascript动画之磁性吸附效果篇”评论...

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。