动画原理
动画定义
由许多静止画面(帧)以一定速度(如每秒30张)连续播放时,肉眼因视觉残像产生的错觉而以为是活动的画面
概念
帧:每个静止的画面叫做帧
播放速度:每秒以24帧(影视)或30帧(游戏)
简单demo:将div从左往右移动
原理:
每过一段时间用(setInterval做到)
将div移动一小段距离
直到移动到目标地点
注意性能:绿色表示重新绘制(repaint)
CSS渲染机制,一次包含布局,绘制,合成
其中布局和绘制可能会被省略
绘制闪烁
代码
打开开发者工具,在任意tab标签里面按esc键
点击左边控制台处…的按钮
选择rendering
勾选paint flashing 刷新后你会发现绿色闪区域,就在这里重新渲染,绿色表示在过程中重新渲染
前端高手不用left做动画
用transform变形
原理tranform:translateX(0=>300px;)
直接修改会被合成需要等一会修改
transition过渡属性可以自动脑补中间帧
注意性能:并没有repaint(重新绘制)比改left性能好
代码:
浏览器渲染机制
google团队文章
渲染树构建:布局及绘制
渲染性能
使用transform来实先动画
查看CSS属性触发什么
http://CSStriggers.com
步骤过程:
根据HTML构建一个HTML树(DOM)
根据CSS构建一个CSSOM树
将2棵树合并成一颗渲染树render tree.render tree是用户看到的树
layout布局(文档流、盒模型、计算大小和位置)
paint绘制(把边框颜色、文字颜色、阴影等画出来)
composite合成(根据层叠关系展示画面)
如何更新样式
一般用JS更新样式
比如div.style.background=”red”让内联元素边红色
div.style.display=”none” 让元素消失
div.classlist.add(‘red’) div拥有新的类,加样式不如加类
div.remove()直接删除节点.删掉节点
那么这些方方有什么不同吗?
有三种渲染方式
浏览器渲染机制
三种更新方式
JS/CSS>样式>布局>绘制>合成 全部都会经历
当你用JS更改了样式时,并且触发了当前元素位置变化,其他元素就需要重新布局relayout
JS/CSS>样式>绘制>合成
当你改变背景色,你并没有更改元素位置与大小。就会跳过layout(
JS/CSS>样式>绘制>合成
当你没有改变颜色与大小,你只改了transform,这就就会跳过layout布局和paint绘制
注意必须全屏查看效果,在iframe里面查看会有问题
如何知道自己会触发什么流程
一般只能自己一个个试
但是www.csstriggers.com可以查看对应流程
不同浏览器不同渲染过程
CSS动画优化
JS优化:使用requestAnimationFrame代替SetTimeout或setInterval
CSS优化:缩小样式计算的范围并降低其复杂性:使用will-change或translate:优化合成器的属性和管理层计数
避免大型、复杂的布局和布局抖动
只能死记硬背
transform全解
四个常用功能
translate
translateX() 横向移动
translateY() 竖向移动
translateZ() 垂直视点往四周移动 近大远小
在建立三维图面时,必须知道视点在哪里,视点为XYZ交点,代码为perspective:1000px;(意思是容器往正中心1000px;处)同时perspective必须写在父容器上。
缩写
transform:translate(50px,50px)左边是X轴,右边是Y轴
常用写法
translateX(<length-percentage>)
translateY(<length-percentage>)
translate(<length-percentage>,<length-percentage>?)[?表示可以省略] translateZ(<length>)且父容器需要添加perspective translate3d(x,y,z)
经验
需要看懂MDN语法示例 translate(-50%,-50%)可以做绝对定位居中
transform.scale 缩放
transform:scale(1.5); 会放大原来的1.5倍
transform:scaleX(1.5);变胖1.5倍,border不受影响
transform:scaleY(1.5);变高1.5倍,同时border也会变粗
transform:scale(1.5,0.5);变胖变矮
常用写法
transform:scale(<number>,<number>)
transform:scaleX(<number>)
transform:scaleY(<number>)
经验,用的比较少,因为容易出现模糊
transform:rotate()旋转
常用写法
transform:rotate([<angle>|<zero>]) transform:rotateX([<angle>|<zero>]) 沿横轴顺时针旋转 transform:rotateY([<angle>|<zero>]) 沿竖轴顺时针旋转 transform:rotateZ([<angle>|<zero>]) 垂直屏幕方向顺时针旋转(默认) transform:rotate3d()
经验
一般用于360旋转制作loading 需要用时可以搜索rotate MDN查看文档
transform:skew倾斜
常用写法
transform:skewX([<angle>|<zero>]) 5deg往左倾斜5度 -5deg往右倾斜5度 transform:skewY([<angle>|<zero>]) transform:skew([<angle>|<zero>],[<angle>|<zero>]?)
经验
用的比较少 用时可以查MDN
transform多重效果缩写
组合使用 transform:scale(0.5) transform(-100%,-100%);
transform:none;取消所有
transition过渡
transition过渡
作用:补充中间帧
语法
transition:属性名字|时长|过渡方式|延迟
transition:width 1s;( width表示宽度发生变化,过渡时间是1s)
transition:all 1s;(all表示指不管写什么改变都会有过渡,过渡时间是1s)
可用逗号分隔两个不同属性 transition:left 200s,top 400ms;
可用all表示代表所有属性:transition:all 200ms
过渡方式:
linear(匀速)|ease(缓动)|ease-in(先慢后快)|ease-out(淡出)|ease-in-out
延迟
指过渡方式要经过多少时间后才开始过渡
PS:并不是所有属性都能过渡
display:none→block没法过渡一般改为visibility:hidden→visible
opacity透明度可以过渡,但是不推荐用
过渡必须要有起始
一般只有一次动画或两次,比如hover和非hover状态过渡
当动画有中间点处理方式
用seTimeout或者监听transitionend事件
animation
声明关键帧添加动画
首先确定关键帧:开始中间结束关键帧确定好
代码:
.stat{animation:XXX 1.5s}
@keyframes XXX {
0%{动画样式;}
66%{动画样式;}
100%{动画样式;}
}
上边代码就是声明关键帧
让动画停在最后一帧
只需要在animation后面加一个forward就可以解决
keyframes完整语法
标准写法
一种是写from to
或者是写百分数(逗号表示隔开)
animation缩写写法
animation:时长|过渡方式|延迟|次数|方向|填充模式|是否暂停|动画名
时长:1s/1000ms
过渡方式:跟transition一样比如linear
次数:3或者2.4或infinite
方向:reverse|alternate|alternate-reverse
填充模式:none|forwards|backwards|both
是否暂停:paused|running
以上所有属性都有对应的单独属性可以查看MDN文档