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)、点击左右键进行切换(边界判断问题)
声明:本文言论系作者本人观点,也不构成任何操作建议,进攻读者参考。引用文章版权归作者所有,如有侵权,请联系我进行删除。
长按可以与我联系哦!
(小姐姐等你来哦)
领取专属 10元无门槛券
私享最新 技术干货