源码网,源码论坛,源码之家,商业源码,游戏源码下载,discuz插件,棋牌源码下载,精品源码论坛

 找回密码
 立即注册
查看: 51|回复: 25

[JavaScript] js弹性势能动画之抛物线运动实例详解

[复制链接]

7万

主题

861

回帖

32万

积分

论坛元老

Rank: 8Rank: 8

积分
329525
发表于 2017-7-27 16:46:07 | 显示全部楼层 |阅读模式
这篇文章主要为大家详细介绍了js弹性势能动画之抛物线运动的制作方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

抛物线运动就是:当拖拽结束的时候,我们让当前的元素同时水平运动+垂直运动

在同样的移动距离下,我们鼠标移动的速度快,move方法触发的次数少,相反移动的速度慢,move方法触发的次数就多->浏览器对于每一次的move行为的触发都是由一个最小时间的。

通过观察,我们发现一个事情:水平方向我们盒子在结束拖拽的时候移动的速度和移动的距离没有必然的联系,和开始拖拽的速度也没有必然的联系,只和最后一次即将松开的那一瞬间鼠标的速度是有关系的,最后瞬间鼠标如果移动的快,我们水平运动的距离和速度也是比较大的。->获取鼠标最后一次即将松开时候的速度。

在JS盒子模型中,offsetLeft是获取当前元素的左偏移,获取到的值永远不会出现小数,  他会把真实的left值按照小数点的四舍五入进行计算

具体代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <style>
  *{
   margin:0;
   padding:0;
  }
  html,body{
   width:100%;
   height:100%;
  }
  #box{
   position:absolute;
   top:50%;
   left:50%;
   width:200px;
   height:200px;
   background:#ff6600;
   margin:-100px 0 0 -100px;
   cursor:move;
   /*
    不知道宽高的情况下的居中
   position:absolute;
   top:0;
   left:0;
   right:0;
   bottom:0;
   margin:auto;
   */ 
  }
 </style>
</head>
<body>
 <div id='box'>
  
 </div>
 <script>
  //JS实现让当前的元素在屏幕居中的位置
  var box = document.getElementById('box');
  // box.style.top = ((document.documentElement.clientHeight || document.body.clientHeight)-box.offsetHeight)/2 + "px";

  // box.style.left = ((document.documentElement.clientWidth || document.body.clientWidth)-box.offsetWidth)/2 + "px";
  //拖拽的原理
  /*
   当鼠标在盒子上按下的时候,我们开始拖拽(给盒子绑定onmousemove和onmouseup),当鼠标移动的时候,我们计算盒子的最新位置
   当鼠标抬起的时候说明拖拽结束了,我们的move和up就没用了,我们再把这两个方法移除
  */
  box.onmousedown = down;
  function down(e){
   e = e || window.event;
   //记录开始位置的信息
   this["strX"] = e.clientX;
   this["strY"] = e.clientY;
   this["strL"] = parseFloat(this.style.left);
   this["strT"] = parseFloat(this.style.top);
   //给元素绑定移动和抬起的事件
   if(this.setCapture){
    this.setCapture()//把当前的鼠标和this绑定在一起
    this.onmousemove = move;
    this.onmouseup= up;
   }else{
    var _this = this;
    document.onmousemove = function(e){
     // move(e)//这个里面的this是window
     move.call(_this,e);
    }
     ;
    document.onmouseup= function(e){
     up.call(_this,e);
    };
   }
   //当盒子运动中我们想要执行下一次拖拽,我们按下鼠标,但是由于盒子还是运动着呢,导致鼠标抓不住盒子->在按下的同时我们应该停止盒子的运动
   window.clearInterval(this.flyTimer);
   window.clearInterval(this.dropTimer);
   
  }
  function move(e){
   e = e || window.event;
   var curL = (e.clientX-this["strX"])+this["strL"];
   var curT = (e.clientY-this["strY"])+this["strT"];
   //边界判断
   var minL = 0,minT = 0,maxL = (document.documentElement.clientWidth || document.body.clientWidth) - this.offsetWidth,maxT = (document.documentElement.clientHeight || document.body.clientHeight) - this.offsetHeight;
   curL = curL < minL ? minL :(curL > maxL ? maxL : curL);
   curT = curT < minT ? minT :(curT > maxT ? maxT : curT)
   this.style.left = curL + "px";
   this.style.top = curT + "px";

   //计算我们水平方向移动的速度
   /*
    在浏览器最小反应时间内触发一次move,我们都记录一下当前盒子的位置,让当前的位置-上一次记录的位置=当前最后一次的偏移
   */
   if(!this.pre){
    this.pre = this.offsetLeft;
   }else{
    this.speedFly = this.offsetLeft - this.pre;
    this.pre = this.offsetLeft;
   }
  }
  function up(e){
   if(this.releaseCapture){
    this.releaseCapture();//把当前的鼠标和盒子解除绑定
    this.onmousemove = null;
    this.onmouseup= null;
   }else{
    document.onmousemove = null;
    document.onmouseup= null;
    //这样绑定的话,move和up绑定的this都是document
   }
   //当鼠标离开结束拖拽的时候,我们开始进行水平方向的动画运动
   fly.call(this);
   //当鼠标离开结束拖拽的时候,我们开始进行垂直方向的动画运动
   drop.call(this);
   
  }
  //当鼠标移动过快的时候,我们的鼠标会脱离盒子,导致盒子的mousemove和mouseup事件都移除不到->"鼠标焦点丢失"
  //在IE和火狐浏览器中,我们用一个方法把盒子和鼠标绑定在一起即可。
  //鼠标再快也跑不出去文档:我们把mousemove和mouseup绑定给document
  
  
  function fly(){
   //this->当前要操作的盒子
   var _this = this;
   _this.flyTimer = window.setInterval(function(){
    //我们运动的速度是一直在减慢的,一直到停止("指数衰减运动")
    //this->window
    //盒子停止运动,清除定时器:利用offsetLeft获取的值不会出现小数,对小数部分进行了四舍五入,所以我们加上或者减去一个小于0.5的速度值,其实对于盒子本身的位置并没有发生实质的改变,我们认为此阶段的盒子就停止运动了。

    if(Math.abs(_this.speedFly)<0.5){
     window.clearInterval(_this.flyTimer);
     return;
    }
    _this.speedFly*=0.98;
    var curL = _this.offsetLeft + _this.speedFly;
    var minL = 0,maxL = (document.documentElement.clientWidth || document.body.clientWidth) - _this.offsetWidth;
    if(curL>=maxL){
     _this.style.left = maxL + "px";
     _this.speedFly*=-1;
    }else if(curL<=minL){
     _this.style.left = minL + "px";
     _this.speedFly*=-1;
    }else{
     _this.style.left = curL;
    }
   },10)
   

  }

  function drop(){
   var _this = this;
   _this.dragFlag = 0;
   _this.dropTimer = window.setInterval(function(){
    if(_this.dragFlag>1){//到底的时候dragFlag就大于1了
     window.clearInterval(_this.dropTimer);
     return;
    }
    _this.dropSpeed = !_this.dropSpeed ? 9.8 : _this.dropSpeed + 9.8;
    //衰减
    _this.dropSpeed*=0.98;
    var curT = _this.offsetTop + _this.dropSpeed;
    var maxT = (document.documentElement.clientHeight || document.body.clientHeight) - _this.offsetHeight;
    if(curT >= maxT){// 到底了
     _this.style.top = maxT + "px";
     _this.dropSpeed*=-1;
     _this.dragFlag++;
    }else{
     _this.style.top = curT + "px";
     _this.dragFlag = 0;
    }
   })
   
  }
 </script>
</body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

回复

使用道具 举报

0

主题

1万

回帖

68

积分

注册会员

Rank: 2

积分
68
发表于 2022-11-17 16:39:44 | 显示全部楼层
啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦
回复 支持 反对

使用道具 举报

0

主题

2万

回帖

0

积分

中级会员

Rank: 3Rank: 3

积分
0
发表于 2023-6-24 00:04:51 | 显示全部楼层
撒房产税陈飞飞
回复 支持 反对

使用道具 举报

9

主题

2万

回帖

420

积分

中级会员

Rank: 3Rank: 3

积分
420
发表于 2023-8-9 21:05:21 | 显示全部楼层
的沙发水电费水电费
回复 支持 反对

使用道具 举报

0

主题

2万

回帖

0

积分

中级会员

Rank: 3Rank: 3

积分
0
发表于 2023-9-11 05:32:59 | 显示全部楼层
激动人心,无法言表!
回复 支持 反对

使用道具 举报

5

主题

2万

回帖

183

积分

注册会员

Rank: 2

积分
183
发表于 2023-9-30 00:51:21 | 显示全部楼层
不错的源码论坛
回复 支持 反对

使用道具 举报

0

主题

1万

回帖

100

积分

注册会员

Rank: 2

积分
100
发表于 2023-11-8 17:15:28 | 显示全部楼层
还不错啊
回复 支持 反对

使用道具 举报

0

主题

2万

回帖

0

积分

中级会员

Rank: 3Rank: 3

积分
0
发表于 2023-11-10 12:25:18 | 显示全部楼层
谢谢楼主分享
回复 支持 反对

使用道具 举报

4

主题

2万

回帖

58

积分

注册会员

Rank: 2

积分
58
发表于 2023-12-9 15:43:49 | 显示全部楼层
逛逛看看瞧瞧
回复 支持 反对

使用道具 举报

16

主题

2万

回帖

174

积分

注册会员

Rank: 2

积分
174
发表于 2024-4-13 01:52:52 | 显示全部楼层
好东西可以可以可以可以
回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

手机版|小黑屋|网站地图|源码论坛 ( 海外版 )

GMT+8, 2024-11-22 22:33 , Processed in 0.070680 second(s), 24 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表