【前端优化】动画几种完成体式格局总结和机能剖析

备注:没整顿花样,抱歉

动画完成的几种体式格局:机能排序
js < requestAnimationFrame <css3< Canvas
js完成体式格局:
1.setTimeout 本身挪用 eg1
2.setInterval 挪用 eg2
setTimeout的定时器值引荐最小运用16.7ms的缘由(16.7 = 1000 / 60, 即每秒60帧)
为何倒计时动画肯定要用setTimeout而防止运用setInterval——-二者辨别及setTimeout激发的js线程议论
1.js线程议论
1.1 为何:单线程是JavaScript的一大特征。
JavaScript是阅读器用来与用户举行交互、举行DOM操纵的,这也使得了它必须是单线程这一特征。比方你去修正一个元素的DOM,同时又去删除这个元素,那末阅读器应当听谁的?
1.2 js单线程事情机制是:当线程中没有实行任何同步代码的前提下才会实行异步代码

var t = true;
window.setTimeout(function (){
    t = false;},1000);
while (t){}
alert('end')

JavaScript引擎是单线程运转的,阅读器只要一个线程在运转JavaScript递次
1.3 阅读器事情基本道理
一、阅读器的内核是多线程的,内核制控下坚持同步,
最少完成三个常驻线程:javascript引擎线程,GUI衬着线程,阅读器事宜触发线程(http要求线程等)

  1. javascript引擎是基于事宜驱动单线程实行的,JS引擎一向守候着使命行列中使命的到来,然后加以处置惩罚,阅读器不管什么时刻都只要一个JS线程在运转JS递次。
  2. GUI衬着线程担任衬着阅读器界面,当界面须要重绘(Repaint)或因为某种操纵激发回流(reflow)时,该线程就会实行。

但须要注重 GUI衬着线程与JS引擎是互斥的,当JS引擎实行时GUI线程会被挂起,GUI更新会被保存在一个行列中比及JS引擎余暇时立时被实行。

  1. 事宜触发线程,当一个事宜被触发时该线程会把事宜增加到待处置惩罚行列的队尾,守候JS引擎的处置惩罚。异步事宜:如setTimeOut、阅读器内核的其他线程如鼠标点击、AJAX异步要求等,(当线程中没有实行任何同步代码的前提下才会实行异步代码)

也就是说纵然setTimeout为0,他也是等js引擎的代码实行完以后才会插进去到js引擎线程的末了实行。
1.4 JavaScript中使命,一种是同步使命,一种是异步使命。
同步使命:各个使命依据文档定义的递次逐一推入”实行栈”中,当前一个使命实行终了,才会最先实行下一个使命。
异步使命:各个使命推入”使命行列”中,只要在当前的一切同步使命实行终了,才会将行列中的使命”出队”实行。(注:这里的异步使命并不肯定是依据文档定义的递次推入行列中)
//只要用户触发点击事宜才会被推入行列中(假如点击时刻小于定时器指定的时刻,则先于定时器推入,不然反之)
1.5 “使命行列是什么?异步使命平常包含哪些?”
使命行列(event loop):你可明白为用于寄存事宜的行列,当实行一个异步使命时,就相称于实行使命的回调函数。
平常io(ajax猎取服务器数据)、用户/阅读器自实行事宜(onclick、onload、onkeyup等等)以及定时器(setTimeout、setInterval)都能够算作异步操纵。

先来看一段代码来明白一下

console.log("1");
setTimeout(function(){
console.log("2");
},1000);
console.log("3");
setTimeout(function(){
console.log("4");
},0);
输出结果: 1->3->4->2.

那末在来看你这段代码。

var t = true;
window.setTimeout(function (){
t = false
},1000);
while (t){}
alert('end');
1.6 setTimeOut的议论


参数
形貌
code
必须。要挪用的函数后要实行的 JavaScript 代码串。
millisec
必须。在实行代码前需守候的毫秒数。

提醒:setTimeout() 只实行 code 一次。假如要屡次挪用,请运用 setInterval() 或许让 code 本身再次
道理:setTimeout挪用的时刻,JavaScript引擎会启动定时器timer,当定时器时刻到,就把该事宜放到主事宜行列守候处置惩罚。
注重:阅读器JavaScript线程余暇的时刻才会真正实行 ep3
millisec参数有什么用?
那末题目来了。setTimeout(handler,0)和setTimeout(handler,100)在零丁运用时,彷佛并没有辨别。(中心实行的代码处置惩罚时刻凌驾100ms时)
millisec平常在多个setTimeout一同运用的时,须要辨别哪一个先到场到行列的时刻才有效,不然都能够设置成setTimeout(handler,0)
1.7 SetTimeout 与 setInterval的辨别

setTimeout(function(){
/* 代码块... */
setTimeout(arguments.callee, 10);
}, 10);
setInterval(function(){
/*代码块... */
}, 10);

setTimeout递归实行的代码必须是上一次实行完了并间格肯定时刻才再次实行
比仿说: setTimeout耽误时刻为1秒实行, 要实行的代码须要2秒来实行,那这段代码上一次与下一次的实行时刻为3秒. 而不是我们设想的每1秒实行一次.
setInterval是列队实行的
比仿说: setInterval每次实行时刻为1秒,而实行的代码须要2秒实行, 那它照样每次去实行这段代码, 上次还没实行完的代码会列队, 上一次实行完下一次的就立时实行, 如许现实实行的距离时刻为2秒
如许的话在我看来, 假如setInterval实行的代码时刻长度比每次实行的距离段的话,就没有意义,而且部队越来越长,内存就被吃光了.假如某一次实行被卡住了,那递次就会被堵死
巨坑非常的setInterval
定时器的代码能够在代码还没有实行完成再次被增加到行列,结果致使轮回内的推断前提不正确,代码多实行频频,之间没有停留。
JavaScript已处理这个题目,当运用setInterval()时,仅当没有该定时器的其他代码实例时才将定时器代码插进去行列。如许确保了定时器代码到场到行列的最小时刻距离为指定距离

  1. 某些距离会被跳过

2.多个定时器的代码实行之间的距离能够比预期要小

大前端团队 > 前端动画完成 > image2017-11-28 14:24:25.png
5处,竖立一个定时器
205处,增加一个定时器,然则onclick代码没实行完成,守候
300处,onclick代码实行终了,实行第一个定时器
405处,增加第二个定时器,但前一个定时器没有实行完成,守候
605处,本来是要增加第三个定时器,然则此时发明,行列中有了一个定时器,被跳过
比及第一个定时器代码实行终了,立时实行第二个定时器,所以距离会比预期的小。
二 CSS3动画
1.tansition

transition-property 要活动的款式 (all || [attr] || none)
transition-duration 活动时刻
transition-delay 耽误时刻
transition-timing-function 活动情势
ease:(逐步变慢)默许值
linear:(匀速)
ease-in:(加快)
ease-out:(减速)
ease-in-out:(先加快后减速)
cubic-bezier 贝塞尔曲线( x1, y1, x2, y2 ) http://matthewlein.com/ceaser/

transition的完全写法以下

img { 
   transition: 1s 1s height ease;
}

零丁定义成各个属性。

img{ 
    transition-property: height;
    transition-duration: 1s;
    transition-delay: 1s;
    transition-timing-function: ease;
}

/能够多个动画同时活动/用逗号离隔

transition:1s width,2s height,3s background;

/能够在动画完成时刻以后增加动画耽误实行的时刻/

transition:1s width,2s 1s height,3s 3s background;

过渡完成事宜

// Webkit内核: 
obj.addEventListener('webkitTransitionEnd',function(){},false);
// firefox: 
obj.addEventListener('transitionend',function(){},false);
/*tansition动画发作在款式转变的时刻*/
function addEnd(obj,fn) ---封装适应与各个阅读器的动画完毕
{   
    //动画实行完实行该函数
    obj.addEventListener('WebkitTransitionEnd',fn,false);
    obj.addEventListener('transitionend',fn,false); //规范
}
addEnd(oBox,function(){
    alert("end");   
});
// 面对两个bug:1.tansition中有多个动画时,每一个实行完,都邑有一个完毕弹出
           // 2.发作反复挪用的状况--须要移除
//移除动画实行完的操纵
function removeEnd(obj,fn)
}
    obj.removeEventListener('transitionend',fn,false);
    obj.removeEventListener('WebkitTransitionEnd',fn,false);
{

运用注重

(1)不是一切的CSS属性都支撑transition
http://oli.jp/2010/css-animatable-properties/
http://leaverou.github.io/animatable/
(2)transition须要明白晓得,最先状况和完毕状况的详细数值,才盘算出中心状况
transition的局限
transition的长处在于简朴易用,然则它有几个很大的局限。
(1)transition须要事宜触发,所以没法在网页加载时自动发作。
(2)transition是一次性的,不能反复发作,除非频频触发。
(3)transition只能定义最先状况和完毕状况,不能定义中心状况,也就是说只要两个状况。
(4)一条transition划定规矩,只能定义一个属性的变化,不能触及多个属性。

CSS Animation就是为了处理这些题目而提出的。
2.transform

rotate() 扭转函数 取值度数 deg 度数 -origin 扭转的基点
skew() 倾斜函数 取值度数
skewX()
skewY()
scale() 缩放函数 取值 正数、负数和小数
scaleX()
scaleY()
translate() 位移函数
translateX()
translateY()

Transform 实行递次题目 — 后写先实行

-webkit-transform:rotate(360deg);
扭转原点能够是关键字+像素位置:相对于左上角作为零点:正为下,右
-webkit-transform-origin:right bottom;
-webkit-transform-origin:200px 200px;
一个transform能够有多个值:
 -webkit-transform:rotate(360deg) scale(0.2);
-webkit-transform:skewX(45deg);
-webkit-transform:skewY(45deg); 
-webkit-transform:skew(15deg,30deg);

3.Animation 关键帧——keyFrames
只需指明两个状况,之间的历程由盘算机自动盘算
关键帧的时刻单元
数字:0%、25%、100%等
字符:from(0%)、to(100%)
花样

@keyframes 动画称号
{
动画状况
}
@keyframes miaov_test
{
from { background:red; }
to { background:green; }
}

能够只要to
必要属性
animation-name 动画称号(关键帧称号)
animation-duration 动画持续时刻
属性:
animation-play-state 播放状况( running 播放 和paused 停息 )
animation-timing-function 动画活动情势
linear 匀速。
ease 缓冲。
ease-in 由慢到快。
ease-out 由快到慢。
ease-in-out 由慢到快再到慢。
cubic-bezier(number, number, number, number): 特定的贝塞尔曲线范例,4个数值需在[0, 1]区间内
animation-delay 动画耽误只是第一次
animation-iteration-count 反复次数/infinite为无限次
animation-direction 播放前重置/动画是不是重置后再最先播放
alternate 动画直接从上一次住手的位置最先实行
normal 动画第二次直接跳到0%的状况最先实行
reverse
alternate-reverse
animation-fill-mode
forwards 让动画坚持在完毕状况
none:默许值,回到动画没最先时的状况。
backwards:让动画回到第一帧的状况。
both: 依据animation-direction(见后)轮番运用forwards和backwards划定规矩。
animation-play-state
paused
running
动画播放历程当中,会倏忽住手。这时候,默许行动是跳回到动画的最先状况,想让动画坚持倏忽停止时的状况,就要运用animation-play-state属性
大前端团队 > 前端动画完成 > image2017-11-28 14:29:8.png
animation也是一个简写情势

div:hover { 
    animation: 1s 1s rainbow linear 3 forwards normal;
}

分解成各个零丁的属性

div:hover { 
    animation-name: rainbow;
    animation-duration: 1s;
    animation-timing-function: linear;
    animation-delay: 1s;
    animation-fill-mode:forwards;
    animation-direction: normal;
    animation-iteration-count: 3;
}

Animation与Js的连系
经由过程class,在class里到场animation的种种属性
直接给元素加-webkit-animation-xxx款式
animation的题目
写起来贫苦
没法动态转变目标点位置
animation的函数:

obj.addEventListener('webkitAnimationEnd', function (){}, false);

实例1:无缝转动
animation的step
eg: http://dabblet.com/gist/1745856
animation-timing-function: steps(30, end)
1.什么时刻运用:
animation默许以ease体式格局过渡,它会在每一个关键帧之间插进去补间动画,所以动画结果是连贯性的,除了ease,linear、cubic-bezier之类的过渡函数都邑为其插进去补间。但有些结果不须要补间,只须要关键帧之间的腾跃,这时候应当运用steps过渡体式格局
大前端团队 > 前端动画完成 > image2017-11-28 14:29:45.png
线性动画: http://sandbox.runjs.cn/show/…
帧动画:http://sandbox.runjs.cn/show/…
2.step运用:
语法:
steps(number[, end | start])
参数申明:
number参数指定了时刻函数中的距离数目(必须是正整数)
第二个参数是可选的,可设值:start和end,示意在每一个距离的出发点或是尽头发作阶跃变化,假如疏忽,默许是end。
大前端团队 > 前端动画完成 > image2017-11-28 14:30:37.png
横轴示意时刻,纵轴示意动画完成度(也就是0%~100%)。
第一个图,steps(1, start)将动画分为1段,腾跃点为start,也就是说动画在每一个周期的出发点发作阶跃(即图中的空心圆 → 实心圆)。因为只要一段,后续就不再发作动画了。
第二个图,steps(1, end)同样是将动画分为1段,但腾跃点是end,也就是动画在每一个周期的尽头发作阶跃,也是图中的空心圆 → 实心圆,但注重时刻,是在尽头才发作动画。
第三个图,steps(3, start)将动画分为三段,腾跃点为start,动画在每一个周期的出发点发作阶跃(即图中的空心圆 → 实心圆)。在这里,因为动画的第一次阶跃是在第一阶段的出发点处(0s),所以我们看到的动画的初始状况实在已是 1/3 的状况,因而我们看到的动画的历程为 1/3 → 2/3 → 1 。
第四个图,steps(3, end)也是将动画分为三段,但腾跃点为end,动画在每一个周期的尽头发作阶跃(即图中的空心圆 → 实心圆)。虽然动画的状况终究会抵达100%,然则动画已完毕,所以100%的状况是看不到的,因而我们终究看到的动画的历程是0 → 1/3 → 2/3。
https://idiotwu.me/study/timi…
steps第一个参数的毛病的明白:
第一个参数 number 为指定的距离数,即把动画分为 n 步阶段性展现,预计大多数人明白就是keyframes写的变化次数
@-webkit-keyframes circle { 0% {background-position-x: 0;} 100%{background-position-x: -400px;} }
@-webkit-keyframes circle { 0% {} 25%{} 50%{} 75%{} 100%{} }
假如有多个帧动画
@-webkit-keyframes circle { 0% {background-position-x: 0;} 50% {background-position-x: -200px;} 100%{background-position-x: -400px;} }
0-25 之间变化5次, 25-50之间 变化5次 ,50-75 之间变化5次,以此类推
运用:
Sprite 精灵动画 2D游戏
https://idiotwu.me/css3-runni…
4.3D转换
父容器:
transform-style(preserve-3d) 竖立3D空间
Perspective 景深
Perspective- origin 景深基点
子元素:
Transform 新增函数
rotateX()
rotateY()
rotateZ()
translateZ()
scaleZ()
实例1:3D盒子
http://beiyuu.com/css3-animation
运用实例:
requestAnimationFrame
是什么
js的一个API
该要领经由过程在体系准备好绘制动画帧时挪用该帧,从而为竖立动画网页供应了一种更腻滑更高效的要领
运用
var handle = setTimeout(renderLoop, PERIOD);
var handle = window.requestAnimationFrame(renderLoop);
window.cancelAnimationFrame(handle);
为何涌现
css:

  1. 一致的向下兼容战略 IE8, IE9之流
  2. CSS3动画不能运用一切属性 scrollTop值。假如我们愿望返回顶部是个腻滑转动结果
  3. CSS3支撑的动画结果有限 CSS3动画的贝塞尔曲线是一个规范3次方曲线

缓动(Tween)学问:
Linear:无缓动结果
Quadratic:二次方的缓动(t^2)
Cubic:三次方的缓动(t^3)
Quartic:四次方的缓动(t^4)
Quintic:五次方的缓动(t^5)
Sinusoidal:正弦曲线的缓动(sin(t))
Exponential:指数曲线的缓动(2^t)
Circular:圆形曲线的缓动(sqrt(1-t^2))
Elastic:指数衰减的正弦曲线缓动
凌驾局限的三次方缓动((s+1)t^3 – st^2)
指数衰减的反弹缓动
js:
1.耽误时刻牢固致使了动画过分绘制,糟蹋 CPU 周期以及斲丧分外的电能等题目
2.纵然看不到网站,特别是当网站运用背景选项卡中的页面或阅读器已最小化时,动画都邑频仍涌现
大前端团队 > 前端动画完成 > image2017-11-28 14:31:6.png
相称一部分的阅读器的显现频次是16.7ms
搞个10ms setTimeout,就会是下面一行的样子容貌——每第三个图形都没法绘制
显现器16.7ms革新距离之前发作了其他绘制要求(setTimeout),致使一切第三帧丧失,继而致使动画断续显现(堵车的觉得),这就是过分绘制带来的题目

requestAnimationFrame 与setTimeout类似,都是耽误实行,不过更智能,随着阅读器的绘制走,假如阅读装备绘制距离是16.7ms,那我就这个距离绘制;假如阅读装备绘制距离是10ms, 我就10ms绘制,阅读器(如页面)每次要重绘,就会关照(requestAnimationFrame)
页面最小化了,或许被Tab切换当前页面不可见。页面不会发作重绘
兼容性
Android装备不支撑,其他装备基本上跟CSS3动画的支撑如出一辙
https://developer.mozilla.org…

    原文作者:Rainie
    原文地址: https://segmentfault.com/a/1190000018357632
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞