动画的原理

1、动画的概念

动画:在一段时间内,从当前位置运动到目标位置

总距离:结束位置-起始位置 ->结束位置:target起始位置:current

总时间:多长时间完成我们的动画 ->duration

步长:每一步走多远 ->step

步长=(总距离/总时间)*多长时间执行一次(定时器中的时间因子)

速度: 多长时间走一步 ->interval-时间因子

callBack:动画完成后的回调

运动的方式:linear匀速 ease-in加速 ease-out减速 ease-in-out先加速后减速...

1、起始和结束位置定了,步长也确定了,总时间不定

2、起始和结束位置定了,归定了总时间,也知道了速度->步长不定(需要求出步长)

加速/减速动画:

我们可以让步长逐步的增大

也可以让定时器的时间因子逐步的减少

我们一般在项目中都使用setTimeout,因为这个控制起来更加的灵活一些

回调函数的原理:把fn1当做一个参数传递给我们的fn2,在fn2执行的时候,我们可以在fn2函数体中的任何位置来执行我们的fn1

functionfn1(num1, num2) {

console.log("fn1");

//this->window

}

functionfn2(callBack) {

console.log("fn2");

callBack(100,200);//callBack->fn1

}

fn2(fn1);

2、js中动画的优化技巧

1、如果使用的是window.setTimeout来实现轮询动画,我们的原理是基于递归思想的->每一次执行完成都重新的设置一个新的定时器来完成下一次的操作->这样的话我们的定时器就会重复的一直累加下去,影响页面的性能

解决办法:在每一次执行move方法的时候,第一步就是把之前创建的定时器清除掉

var timer = null;

function move() {

window.clearTimeout(timer);

timer = window.setTimeout(move, 13);

}

move();

2、我们每一次都把设置的定时器存储到全局变量timer中,但是过多的使用全局变量会造成相互的污染和冲突

解决办法:把timer设置为当前要操作元素的自定义属性,这样就避免了全局变量的冲突

隐形的作用:把timer设置为元素的自定属性,那么当前的元素只能存储一个timer,遇到一个元素多个动画的时候,可以快速的把之前运动的动画都结束,执行当前的这个动画即可

function move() {

window.clearTimeout(oDiv.timer);

oDiv.timer = window.setTimeout(move, 13);

}

move();

3、关于作用累积的问题->当move方法需要传递参数值的时候

function move(target) {

oDiv.timer = window.setTimeout(move, 13);//->这样第二次执行的时候没有办法给move传递参数

oDiv.timer = window.setTimeout(move(target), 13);//->把move执行的返回结果undefined给了我们的定时器,当13ms后执行的是undefined,浏览器报错

oDiv.timer = window.setTimeout(function () , 13);//->可以实现,但是非常的消耗性能(见图"动画作用域问题.png")

}

move(1000);

解决办法:->只有move这个第一次执行的时候形成的私有作用域不销毁

如果我们的move需要传递参数,那么我们就在move中定义一个小的函数_move,每一次都把动画执行的代码放在_move中,设置定时器每一次执行的都是_move即可

function move(target) {

window.clearTimeout(oDiv.timer);//清除的是oDiv之前正在运行的动画

var _move=function(){

window.clearTimeout(oDiv.timer);//清除每一次_move执行产生的定时器的累积

oDiv.timer=window.setTimeout(_move,13);

};

_move();

}

move(1000);

4、边界判断的问题

按照之前我们的写法,会遇到下述的问题:步长是5,但是到边界发现,加5超了边界,不加还不能到边界,这样的话就会出现盒子在边界来回的抖动

var curL = utils.css(_this, "left");

if (curL

if (curL >= target) {

return;

}

utils.css(_this, "left", curL + 5);

} else if (curL > target) {

if (curL

return;

}

utils.css(_this, "left", curL - 5);

}

解决办法:在边界判断的时候,让当前的值和步长相加做边界判断,如果到边界,我们在让元素的样式直接变为边界的值

var curL = utils.css(_this, "left");

if (curL

if (curL+5 >= target) {//1)加步长做临界判断

utils.css(_this, "left", target);//2)到临界后直接等于目标的值

return;

}

utils.css(_this, "left", curL + 5);

} else if (curL > target) {

if (curL-5

utils.css(_this, "left", target);

return;

}

utils.css(_this, "left", curL - 5);

}

3、tween动画原理

1、animate(ele,,1500,['zfLinear','easeIn'],callback)

动画名(运动的元素,,完成此运动的总时间,[动画类型],回调方法)

4、轮播图

1、轮播图中的知识点

1)、a标签

(1)、css方法

javascript:;/javascript:void(0) 这两种方法都可以实现阻止a标签的默认行为

(2)、js方法

varlink=document.getElementById("link");

link.onclick =function(e) {

1、e = e ||window.event;

e.preventDefault? e.preventDefault() : e.returnValue=false;//阻止了默认行为

2、return false;//阻止了默认行为

};

background:url("../img/pre.png")no-repeat0 0;//以图片为背景的时候,图片有多个上级的时候,就在图片的文件夹前面加上 ..,便可以引入图片

2)直线运动方式算法

t是times,当前用的时间,b是begin,开始的位置、c为change,总共要运行的距离,d是duration,为总时间。

zfLinear:functionzfLinear(t, b, c, d) {

returnc * t / d + b;

},

2、轮播图的过程

1)、animate函数方法使用

2)、顺序

(1)、获取所需的元素

(2)、计算当前图片的所在位置和宽度

(3)、进行绑定数据

(4)、图片延迟加载

(5)、焦点对齐

(6)、自动播放(边界判断问题)

(7)、点击底下按钮进行切换

(8)、点击左右键进行切换(边界判断问题)

声明:本文言论系作者本人观点,也不构成任何操作建议,进攻读者参考。引用文章版权归作者所有,如有侵权,请联系我进行删除。

长按可以与我联系哦!

小姐姐等你来哦

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20180806G1LYXE00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

同媒体快讯

扫码关注云+社区

领取腾讯云代金券