美文网首页互联网科技程序员
月薪80k大佬笔记,javascript之运动!网友:“完美”!

月薪80k大佬笔记,javascript之运动!网友:“完美”!

作者: 5709922fdd2c | 来源:发表于2019-03-16 19:22 被阅读1次

网友:少废话上干货!小编:好嘞!

知识点很多,文章偏长,要看完哦!

导语:JavaScript 运动(缓冲运动,多物体运动 ,多物体多值运动+回调机制)

匀速运动(当需要物体做匀速运动直接调用statMove函数)

1 function startMove(dom,targetPosetion){ //dom : 运动对象,targetPosition : 到达目标位置

2   clearInterval(timer); // 防止定时器叠加,先清除定时器。

3   var speed = targetPosetion - dom.offsetLeft > 0 ? 7 : -7;

4 //断物体到移动的目标位置的左边还是右边,左边速度是正的,右边速度是负的。

5   timer = setInterval(function(){   //设置定时器。变量timer要定义在函数外面。

6     if(Math.abs(targetPosetion - dom.offsetLeft ) < Math.abs(speed)){

7       clearInterval(timer);

8      //当目位置减去物体偏移量小于定时器移动的位置(因为在移动就超出了目标位置),清除定时器

9       dom.style.left = targetPosetion + "px";

10    //因为距离目标位置还有一小段距离,直接让物体等于目标位置就行

11     }else{

12       dom.style.left = dom.offsetLeft + speed + "px";

13     }

14   },30);

15 }

缓冲运动(越接近目标,速度越慢)

缓运运动比直线运动视觉性更好,所以很常用

1 function startMove(dom, targetPosetion) {

2   clearInterval(timer);

3   var speed = null;

4   timer = setInterval(function () { //设置定时器。变量timer要定义在函数外面。

5     speed = (targetPosetion - dom.offsetLeft) /10;

6     speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

7     if(dom.offsetLeft == targetPosetion){

8       clearInterval(timer);

9     }else{

10       dom.style.left = dom.offsetLeft + speed + "px";

11     }

12   }, 30)

13 }

5: 目标位置 - 物体偏移量(因为目标位置固定的,但是物体偏移量越来越大,所以会越来越慢)第10行的dom.offsetLeft和第5行负的dom.offsetLeft互相抵消掉了,dom.style.left直接等于目标位置(速度太大),所以要除以一个小数。

6:当目标位置 - 物体偏移量小于除数时,speed就等于小数了, 但是偏移量都是整数,就会自动的取舍值,例如:dom.style.left = 35.6px 实际会转换成dom.style.left = 36px;所以只要有小数就向上取整(Math.ceil()),加上1。当是负值的时候就下取整(Math.floor()).因为当speed是小数时,就会被取整。所以最后是一个像素一个像素加上去的,所以物体的偏移量正好等于目标位置时就清除定时器。

颜色渐变的缓冲运动

因为让当前的颜色渐变需要让当前的opacity增加或减少,获取当前的透明度opacity可以用计算样式window.getComputedStyle。

计算样式只读,返回的都是绝对值,没有相对单位

1 function getStyle(dom,attr){

2   if(window.getComputedStyle){

3     return window.getComputedStyle(dom,null)[attr];

4   }

5   else{

6     return dom.currentStyle[attr]; //IE8不兼容,IE独有属性currentStyle

7   }

8 }

让物体透明度缓冲变化

1 startMove(div,25);

2 function startMove(dom, targetPosetion) {

3   clearInterval(timer);

4   var speed = null,current = null;

5   timer = setInterval(function () {

6     current = parseFloat(getStyle(div,'opacity')) * 100;

7     console.log(current);

8     speed = (targetPosetion - current) / 10;

9     speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

10     if (current == targetPosetion) {

11       clearInterval(timer);

12     } else {

13     dom.style.opacity = (current + speed) / 100;

14     }

15   }, 30)

16 }

因为透明度的取值范围是0-1,把缓冲范围变大,调用函数时和获取当前透明度值时扩大100倍,增大缓冲区间,当给opacity赋值的时候缩小100倍。

多物体运动

4个div,移入到那个div,宽度做缓冲运动移动到400;移除宽度变为100。

下面的代码。橙色的部分有timer变为dom自己的属性dom.timer,

在上面定义timer的时候,定义的timer是在函数外面的,4个div共用一个timer定时器,

当移入一个div时,开启一个定时器,移出div时,又把上一个定时器给清除了,重新开启了一个定时器。

当从上一个div快速移入一个新的div时,还没等回到100,开启的那个新的div。就把上一个div给清除了。

所以解决这个问题,就是在每个div上都加一个定时器。

当清理定时器的时候也是清理自己的定时器,不会影响其他的,就在每个元素上加上timer属性。

function startMove(dom, targetPosetion) {

clearInterval(dom.timer);

var speed = null;

dom.timer = setInterval(function () {

current = parseFloat(getStyle(dom, 'width')); //用计算样式获取当前宽度值。

speed = (targetPosetion - current) / 10;

speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

console.log(speed, current);

if (current == targetPosetion) {

clearInterval(dom.timer);

} else {

dom.style.width = current + speed + "px";

}

}, 30)

}

var div = document.getElementsByTagName('div');

for (var i = 0; i < div.length; i++) {

div[i].onmouseenter = function () {

startMove(this, 400)

}

div[i].onmouseleave = function(){

startMove(this,100);

}

}

多物体不同属性运动

1 function startMove(dom , attr , target){

2   clearInterval(dom.timer);

3   dom.timer = setInterval(function(){

4     var current = null,speed = null;

5     if(attr == 'opacity'){

6       current = parseFloat(getStyle(dom,attr)) * 100;

7     }else{

8       current = parseFloat(getStyle(dom,attr));

9     }

10     speed = (target - current) / 10;

11     speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

12     if(current == target){

13       clearInterval(dom.timer);

14     }

15     if(attr == 'opacity'){

16       dom.style.opacity = (current + speed) / 100;

17     }else{

18       dom.style[attr] = (current + speed) + "px";

19     }

20   },30)

21 }

22

23 var div = document.getElementsByTagName('div');

24 div[0].onmouseenter = function(){

25   startMove(this,'width',400);

26 };

27 div[1].onmouseenter = function(){

28   startMove(this,'height',400);

29 };

30 div[2].onmouseenter = function(){

31   startMove(this,'borderWidth',20);

32 };

33 div[3].onmouseenter = function(){

34   startMove(this,'opacity',50);

35 };

多物体多值运动 + 回调机制

function startMove(dom, targetObj, callback) {

clearInterval(dom.timer);

dom.timer = setInterval(function () {

var stop = true;

var speed = null, current = null;

for (var prop in targetObj) {

if (prop == 'opacity') {

current = parseFloat(getStyle(dom, prop))*100;

} else {

current = parseFloat(getStyle(dom, prop));

}

speed = (targetObj[prop] - current) / 10;

speed = speed>0?Math.ceil(speed):Math.floor(speed);

if (prop == 'opacity') {

dom.style.opacity = (current + speed) / 100;

} else {

dom.style[prop] = (current + speed) + "px";

}

if (targetObj[prop] != current) {

stop = false;

}

}

if (stop == true) {

clearInterval(dom.timer);

typeof callback == 'function' && callback();

}

}, 30);

}

//让多物体多值运动,由于多值就可以用对象来装。

startMove(dom, targetObj, callback)接收3个参数,运动对象,想要改变的多值属性对象,回调函数

跟上面一样一地步清除定时器,然后设置定时器,用for in 循环传过来的对象属性,

如果传过来的是opacity 就要扩大100倍,不是就正常调用上面getStyle()方法,返回一个计算属性。

设置一个锁,每次定时器执行时定义一个变量stop = true 可以停止,

当for in 循环时,判断如果有一个当前值不等于目标值的时候,就让stop = false。不可以停止

for in 结束,stop == true 的时候就代表所有的值都到达目标值,这时候就可以清空定时器。这个运动过程结束,调用回调函数

1      var divOne = document.getElementById('one');

2 var divTwo = document.getElementById('two');

3 divOne.onclick = function () {

4 startMove(this, { width: 400,height: 400,left: 200,top: 300,opacity: 50}, function () {

5 startMove(divTwo, { width: 400, height: 400, left: 200, top: 300, opacity: 50 }, function () {

6 alert(555);

7 })

8 })

9 }

最后,想学习web前端的小伙伴们!

对web前端感兴趣的小伙伴也可以加 小编q 裙:

相关文章

网友评论

    本文标题:月薪80k大佬笔记,javascript之运动!网友:“完美”!

    本文链接:https://www.haomeiwen.com/subject/psndmqtx.html