Loading
nsplknsplk
This is a live streamed presentation. You will automatically follow the presenter and see the slide they're currently on.
分享人:蔺凯
| 属性 | 描述 |
|---|---|
| transition | 简写属性,在一个属性中设置四个过渡属性 |
| transition-property | 规定应用过渡的CSS属性名称 |
| transition-duration | 规定过渡效果持续时间。默认是0 |
| transition-timing-function | 规定过渡效果时间曲线。默认是"ease" |
| transition-delay | 规定过渡效果何时开始。默认是0 |
一、Transition 过渡
1. Transition 过渡触发方式
伪类触发::hover : focus :checked :active
js触发:toggleClass
2. 以下情况下,属性值改变不能产生过渡效果
(1)transition需要事件触发,所以没法在网页加载时自动发生。
(2)transition是一次性的,不能重复发生,除非一再触发。
(3)transition只能定义开始状态和结束状态,不能定义中间状态,也就是说只有两个状态。
(4)一条transition规则,只能定义一个属性的变化,不能涉及多个属性。
CSS Animation就是为了解决这些问题而提出的。
贝塞尔曲线定义:
Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线。 曲线定义:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。
它是 animation-timing-function 和transition-timing-function 中一个重要的内容。
贝塞尔曲线原理
满足AE/AB = BF/BE = CG/CD = EH/EF = FI/FG = HJ/HI条件的所有J点所形成的轨迹就是三阶贝塞尔曲线
css3定义规则:cubic-bezier (p0,p1,p2,p3)
css中贝塞尔曲线常见的值
ease:cubic-bezier(.25, .1, .25, 1)
liner:cubic-bezier(0, 0, 1, 1) / cubic-bezier(1, 1, 0, 0)
ease-in:cubic-bezier(.42, 0, 1, 1)
ease-out:cubic-bezier(0, 0, .58, 1)
ease-in-out:cubic-bezier(.42, 0, .58, 1)
In Out . Back(来回的缓冲效果):cubic-bezier(0.68, -0.55, 0.27, 1.55)
@keyframes dropdown {
0% { top: 0; left:0px;}
30% { top: 300px; left:0px;}
50% { top: 150px; left:0px;}
70% { top: 300px; left:0px;}
80% { top: 0px; left:-200px;}
100% { top: 0px; left:0px;}
}二、Animation
animation-name:用来调用@keyframes定义好的动画,与@keyframes定义的动画名称一致
animation-duration :指定元素播放动画所持续的时间
animatino-timing-function : 和transition中的transition-timing-function 中的值一样。根据上面@keframes中分析的animation中可能存在多个小动画,因此这里的值设置是针对每一个小动画所在时间范围内的属性变换速率。
animation-delay:定义在浏览器开始执行动画之前等待的时间。
animation-iteration-count:定义动画的播放次数,其通常为整数,默认是1,;取值为infinite,动画将无限次的播放。
animation-direction:主要用来设置动画播放方向,其主要有两个值:
animation-fill-mode 这个 CSS 属性用来指定在动画执行之前和之后如何给动画的目标应用样式。
none(回到动画没开始时的状态),
forwards(动画结束后动画停留在结束状态),
backwords(动画回到第一帧的状态),
both(根据animation-direction轮流应用forwards和backwards规则),注意与iteration-count不要冲突(动画执行无限次)
animtion-play-state:属性是用来控制元素动画的播放状态。其主要有两个值:
running,可以通过该值将暂停的动画重新播放,这里的重新播放不是从元素动画的开始播放,而是从暂停的那个位置开始播放。
paused,暂停播放
animation-iteration-count
infinite | <number>[,infinite | <number>]
animation-direction
<single-animation-direction> = normal | reverse | alternate | alternate-reverse
animation-fill-mode
<single-animation-fill-mode> = none | forwards | backwards | both
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; }
div:hover { animation: 1s 1s rainbow linear 3 forwards normal; }
序列进入
漂浮的白云主要通过远景白云和近景白云来实现立体漂浮效果。远景和近景分别使用两张背景图片,通过改变其背景定位来实现白云移动效果,通过设置不同的动画持续时间来实现交错漂浮的效果
正方体
一般情况下,主线程负责:
合成线程负责:
渲染一个网页需要两个重要的线程来共同完成
三、简单动画的性能
图中橘黄色部分代表操作相对较慢,消耗较大;
蓝色部分代表操作相对较快,消耗较小
<style>
#foo {
height: 100px;
width: 100px;
background: red;
transition: height 1s linear;
}
#foo:hover {
height: 200px;
}
</style>
<body>
<div id="foo"></div>
</body>从上图我们可以看到,浏览器的两个线程在来回地切换工作,而且橘黄色出现次数较多,这意味着浏览器需要处理相当多的工作。
对于浏览器而言,由于元素的高度一直在变化,因此这个动画的每一帧中,都需要重新布局 ——> 绘制页面 ——> 将新的位图加载到 GPU 中 ——> 显示。而其中加载到 GPU 是一个相对缓慢的操作。
height
<style>
#bar {
height: 100px;
width: 100px;
background: red;
transition: transform 1s linear;
}
#bar:hover {
transform: scale(2);
}
</style>
<body>
<div id="bar"></div>
</body>由此我们可以看到,两个线程来回切换的情况并不多,橘黄色部分出现的次数也较少,蓝色部分居绝大部分,这意味着这个动画效果相较于上面的要流畅很多。
在定义中,transform 是不会使浏览器产生重新排版的,因此 transform 不会影响原本的布局,以及周围的元素。它会将定义的元素作为一个整体进行缩放、移动或旋转等。
基于 transform 这类的特性,浏览器在渲染页面时可以节省很多不必要的开支,例如重新布局和将位图传给 GPU 等工作,这样就使得动画更有效率。
translate
优化 CSS 动画,先给出最后的一个优化步骤方案:
Text
height
transform
transform
height
在需要写动画时,我们需要选择合适的方案,最好是选择 scale()、rotate()、transalte() 等,因为他们具有更好的性能。
通过这个按钮,可以开启页面实时 Frame Rate (帧率) 观测及页面 GPU 使用率。
chorme开发工具
四、动画FPS简单测试
Frame Timing API 是 Web Performance Timing API 标准中的其中一位成员。
Web Performance Timing API 是 W3C 推出的一套性能 API 标准,用于帮助开发者对网站各方面的性能进行精确的分析与控制,提升 Web 网站性能。
它包含许多子类 API,完成不同的功能,大致如下(摘自使用性能API快速分析web前端性能,当然你也可以看英文原版介绍:Web Performance Timing API ):
requestAnimationFrame 方法告诉浏览器您希望执行动画并请求浏览器调用指定的函数在下一次重绘之前更新动画。
当你准备好更新屏幕画面时你就应用此方法。这会要求你的动画函数在浏览器下次重绘前执行。回调的次数常是每秒 60 次,大多数浏览器通常匹配 W3C 所建议的刷新率。
三、
var rAF = function () {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
}
);
}();
var frame = 0;
var allFrameCount = 0;
var lastTime = Date.now();
var lastFameTime = Date.now();
var loop = function () {
var now = Date.now();
var fs = (now - lastFameTime);
var fps = Math.round(1000 / fs);
lastFameTime = now;
// 不置 0,在动画的开头及结尾记录此值的差值算出 FPS
allFrameCount++;
frame++;
if (now > 1000 + lastTime) {
var fps = Math.round((frame * 1000) / (now - lastTime));
console.log(`${new Date()} 1S内 FPS:`, fps);
frame = 0;
lastTime = now;
};
rAF(loop);
}
loop();正常而言 requestAnimationFrame 这个方法在一秒内会执行 60 次,也就是不掉帧的情况下。假设动画在时间 A 开始执行,在时间 B 结束,耗时 x ms。而中间 requestAnimationFrame 一共执行了 n 次,则此段动画的帧率大致为:n / (B – A)。
测试页面,Solar System
浏览器硬件加速
将浏览器的渲染过程交给GPU处理,而不是使用自带的比较慢的渲染器。这样就可以使得animation与transition更加顺畅。
.cube {
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
/* Other transform properties here */
}
transform: translate3d(0, 0, 0);只对我们需要实现动画效果的元素应用以上方法,如果仅仅为了开启硬件加速而随便乱用,那是不明智的。
小心使用这些方法,如果通过你的测试,结果确是提高了性能,你才可以使用这些方法。使用GPU可能会导致严重的性能问题,因为它增加了内存的使用,而且它会减少移动端设备的电池寿命。
第一帧
电影第一帧
游戏动画第二帧
电影《星际穿越》画面,可以看到很明显的动态模糊。
电影里面一米一米移动的时候,每帧的画面是清晰,十米十米移动的时候,动作就会出现拖影,给人以动感的效果,连贯而不卡。
加入动作模糊等特效, 对画面中高速运动的物体加上人为模糊,从而实现和电影画面相似的质感。 在打开动态模糊的情况下,30帧和60帧的视觉流畅度差异极小。
游戏的卡顿分很多原因。RTS游戏中单位出现过多,CPU计算能力不够,会卡,游戏特效变好,显卡算不过来,会卡,切换地图读硬盘,会卡,场景太大内存放不下,会卡。例如切换地图读取硬盘时候的卡,就和显卡性能(帧数)无关,这时候即便帧数再高,硬盘性能不够了,还是会卡,这点用机械硬盘玩游戏的会有体会。
第三个原因,就是电影只需要看,只要画面流畅就行了,而游戏是涉及到操作的,如果FPS过低,或者帧生成时间过长,就会使得操作更加不流畅。先是人眼看到一帧画面,然后才能进行对应的操作,再体现到下一帧的画面上,一个操作需要数帧才能完成。这样一来,当FPS降低一半,也就是帧生成时间增加一倍,一个操作所需的时间会增加数倍,带给玩家的直观感受就是,操作不跟手了,卡了。特别是当帧生成时间不稳定的时候,不跟手的情况就越发明显了。
所以当帧数提高的时候,不简简单单的是画面变流畅了,而是能明显感受到,整个游戏的操作都变得更加的流畅了。