运动课笔记2

来源渡一笔记

匀加速运动

function move (dom,attr) {
                var speed = 0;
                var a = 3;
                clearInterval(dom.timer);
                dom.timer = setInterval(function () {
                    speed += a;
                    dom.style[attr] = parseInt(getStyle(dom,attr)) + speed + 'px';
                },30);
move (div,'left')
getStyle 函数在运动课笔记1

弹性运动(匀加速)

function move (dom,attr,target) {
                var speed = 0;
                var a = 3;
                clearInterval(dom.timer);
                dom.timer = setInterval(function () {
                  var iCur = parseInt(getStyle(dom,attr));
                  if(target < iCur) {
                    speed -= a;
                  }else {
                    speed += a;
                  }
                    dom.style[attr] = iCur + speed + 'px';
                },30);
            }

move(div,'left',300);

加速度为常量,跟target距离不成正比,非弹簧运动。

弹性运动(理想弹簧运动)

 function move (dom,attr,target) {
                var speed = 0;
                var a = 0;
                clearInterval(dom.timer);
                dom.timer = setInterval(function () {
                  var iCur = parseInt(getStyle(dom,attr));
                  a = (target - iCur) / 20;
                  speed += a;
                    dom.style[attr] = iCur + speed + 'px';
                },30);
            }
move(div,'left',100);


a = (target - iCur) / 20;
speed = (target - iCur) / 7;(缓冲运动中)
这两个很类似。表示的都是与距离成正比。

弹簧运动(模拟现实)
版本1.0

function move (dom,attr,target) {
                var speed = 0;
                var a = 0;
                var u = 0.8;
                clearInterval(dom.timer);
                dom.timer = setInterval(function () {
                  var iCur = parseInt(getStyle(dom,attr));
                  a = (target - iCur) / 20;
                  speed += a;
                  speed *= u;
                    dom.style[attr] = iCur + speed + 'px';
                    console.log(speed,target - iCur);
                    if(Math.abs(speed) < 1 && Math.abs(target - iCur) < 1){//此处为条件1
                      clearInterval(dom.timer);
                    }
                    
                },30);
            }

其实有很多细节我也不太理解。
比如条件1 在缓冲运动中,Math.abs(target-iCur) 有时会卡死在>1的时候。
可在这里似乎不存在>1卡死的情况。

结果发现这也是有可能会卡死的。
如果把上面的u 改成0.8 就会卡死,永远都无法执行 清除计时器操作。
如果我们放入一个回调函数,那么回调函数就不会执行了。

其实这就很尴尬。我们最好找到一个合适的条件,可以保证能够会被执行,
然后停止的足够自然。

版本1.1

首先想到的就是缓冲运动中的取整
function move (dom,attr,target) {
                var speed = 0;
                var a = 0;
                var u = 0.8;
                clearInterval(dom.timer);
                dom.timer = setInterval(function () {
                  var iCur = parseInt(getStyle(dom,attr));
                  a = (target - iCur) / 20;
                  speed += a;
                  speed *= u;
                  speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);//首先联想到这个
                    dom.style[attr] = iCur + speed + 'px';
                    console.log(speed,target - iCur);
                    if(Math.abs(speed) <= 1 && Math.abs(target - iCur) < 1){
                      clearInterval(dom.timer);
                    }
                    
                },30);
            }

不行,他会不停摇摆。

版本1.2

function move (dom,attr,target) {
                var speed = 0;
                var a = 0;
                var u = 0.8;
                var last = 'a';
                var count = {};
                clearInterval(dom.timer);
                dom.timer = setInterval(function () {
                  var iCur = parseInt(getStyle(dom,attr));
                  a = (target - iCur) / 20;
                  speed += a;
                  speed *= u;
                    dom.style[attr] = iCur + speed + 'px';
                    console.log(speed,target - iCur);
                    if(last == (target - iCur) && count[last] >=5 && Math.abs(speed) < 1){
                      clearInterval(dom.timer);
                      dom.style[attr] = target + 'px';
                    }else{
                      last = target - iCur;
                      if(!count[last]){
                        count[last] = 1;
                      }
                      count[last]++;
                    }
                },30);
            }
写得比较丑,
思路是,最后卡死时,位置必然是不动的,我们记录最后的位置一样的次数超过好几次,
并且speed < 0
那么基本就可以判定运动已经卡死,可以停止。

多值多属性链式运动
根据版本1.0

function move (dom,option,callback) {
              var speed = 0;
              var a = 0;
              var u = 0.95;
              var target = {};
              clearInterval(dom.timer);
              dom.timer = setInterval(function () {
                var stop = true;
                for(var attr in option){
                  target[attr] = option[attr] * 100;
                  
                  var iCur = parseFloat(getStyle(dom,attr)) * 100;
                  a = (target[attr] - iCur) / 20;
                  speed += a;
                  speed *= u;
                  console.log(speed,target[attr] - iCur);
                  if(!(Math.abs(speed) < 1 && Math.abs(target[attr] - iCur) < 1)){
                    stop = false;
                    if(attr == 'opacity') {
                      dom.style[attr] = (iCur + speed)/100;
                    }else {
                      dom.style[attr] = iCur/100 + speed/100 + 'px';
                    }
                  }
                  if(stop) {
                    clearInterval(dom.timer);
                    console.log(111);
                    typeof(callback)=="function" ? callback():'';
                  }
                }
              },30);
            }
其实这都需要时不时的写一写,有好处。

模拟边界(匀速运动)(速度反方向问题)

function move (div) {
                var speedx = 10,
                    speedy = 10;
                clearInterval(div.timer);
                div.timer = setInterval(function () {
                    var newLeft = parseInt(getStyle(div,'left')) + speedx; 
                    var newTop = parseInt(getStyle(div,'top')) + speedy; 
                    console.log(document.body.clientHeight);
                    if(newTop >= document.documentElement.clientHeight - div.offsetHeight){
                      speedy *= -1;
                      newTop = document.documentElement.clientHeight - div.offsetHeight;
                    }
                    if(newTop <= 0) {
                      speedy *= -1;
                      newTop = 0;
                    }
                    if(newLeft <= 0) {
                      speedx *= -1;
                      newLeft = 0;
                    }
                    if(newLeft >= document.body.clientWidth - div.offsetWidth){
                      speedx *= -1;
                      newLeft = document.body.clientWidth - div.offsetWidth;
                    }
                    
                    div.style['left'] = newLeft + 'px';
                    div.style['top'] = newTop + 'px';
                },30);
                
            }

模拟重力场(拖拽)

function getStyle (dom,attr) {
                if (dom.currentStyle) {
                    return dom.currentStyle[attr];
                } else{
                    return window.getComputedStyle(dom,null)[attr];
                }
            }
            
            function move (div,speedx,speedy) {
                  var g = 8,
                    u = 0.8;
                clearInterval(div.timer);
                div.timer = setInterval(function () {
                  speedy += g;
                    var newLeft = parseInt(getStyle(div,'left')) + speedx; 
                    var newTop = parseInt(getStyle(div,'top')) + speedy; 
                    if(newTop >= document.documentElement.clientHeight - div.offsetHeight){
                      speedy *= -1;
                      speedx *= u;
                      speedy *= u;
                      console.log(speedy);
                      newTop = document.documentElement.clientHeight - div.offsetHeight;
                    }
                    if(newTop <= 0) {
                      speedy *= -1;
                      speedx *= u;
                      speedy *= u;
                      newTop = 0;
                    }
                    if(newLeft <= 0) {
                      speedx *= -1;
                      speedx *= u;
                      newLeft = 0;
                    }
                    if(newLeft >= document.body.clientWidth - div.offsetWidth){
                      speedx *= -1;
                      speedx *= u;
                      newLeft = document.body.clientWidth - div.offsetWidth;
                    }
                    if(Math.abs(speedx) < g && Math.abs(speedy) < g && newTop == document.documentElement.clientHeight - div.offsetHeight) {// 这个停止条件实际上挺费神的
                      clearInterval(div.timer);
                      console.log(123456);
                    }
                    div.style['left'] = newLeft + 'px';
                    div.style['top'] = newTop + 'px';
                },20);
                
            }
            
            
            div.onmousedown = function (e) {
                var e = e || window.event;
                clearInterval(div.timer);
                var disX = e.clientX - this.offsetLeft;
                var disY = e.clientY - this.offsetTop;
                var speedX,speedY;
                var lastX = 0,lastY = 0;
                var that = this;
                document.onmousemove = function (e) {
                    var newLeft = e.clientX - disX;
                    var newTop = e.clientY - disY;
                    speedX = e.clientX - lastX;
                    speedY = e.clientY - lastY;
                    lastX = e.clientX;
                    lastY = e.clientY;
                    that.style.left = newLeft + 'px';
                    that.style.top = newTop + 'px';
                }
                document.onmouseup = function (e) {
                    document.onmousemove = null;
                    document.onmouseup = null;
                    move(div,speedX,speedY);
                }
            }

你可能感兴趣的:(运动课笔记2)