CSS动画和效果原理
动画的定义
- 由许多静止的画面组成(帧)
- 以一定的速度(如每秒30张)连续播放时
- 肉眼因视觉残像产生错觉,而误认为是活动的
动画的概念
- 帧:每个静止的画面都叫帧
- 播放速度:每秒24帧(影视)或每秒30帧(游戏)
动画原理
- 每过一段时间(用setInterval做到)
- 将div移动一小段距离
- 知道移动到目标地点
性能
- 开发者工具打开绘制-闪烁,绿色表示重新绘制了一遍的元素
- CSS渲染过程依次为 布局——绘制——合成
- 其中布局和绘制有可能被省略
浏览器渲染原理
- 步骤
- 根据HTML构建文档树(DOM)
- 根据CSS构建CSS树(CSSOM)
- 将两棵树合并成一颗渲染树(render tree)
- Layout 布局(文档流、盒模型、计算大小和位置)
- Paint 绘制 (把边框颜色、文字颜色、阴影等画出来)
- ComPose 合成(根据层叠关系展示画面)
- 注意:前端老鸟不用left做动画,用transform做,因为节约性能
三种更新方式
- JS/CSS=>样式=>布局=>绘制=>合成 (div.remove)
- JS/CSS=>样式=>绘制=>合成 改变背景颜色之类的
- JS/CSS=>样式=>合成 改变transform就可以做到
如何更新样式
- 一般用JS更新样式
1. 比如 div.style.background='red'
2. 比如 div.style.display='none'
3. 比如 div.classList.add('red')
4. 比如 div.remove() 直接删掉节点
如果不知道什么属性走什么流程
- 用 css流程查询 来查询
CSS动画优化
- 答案都在谷歌的网站里(文章)
JS优化
- 使用requestAnimationFrame代替setTimeout或setInterval
CSS优化
- 使用will-change或translate
动画or过渡or多次动画
transform
transform原理
- transform:translateX(0=>300px)
- 直接修改会被合成,需要等一会修改
- transition过渡属性可以自动脑补中间帧,达到动画的效果
- 注意:此方法动画并没有repaint(重新绘制) 比改left性能好
常用属性
- 位移:translate
- 缩放:scale
- 旋转:rotate
- 倾斜:skew
注意
- 一般都需要配合transition过渡
- inline元素不支持transform,需要先变成block
translate 平移
-
通常属性
transform:translateX() 横轴平移; transform:translateY() 竖轴平移; transform:translateZ() 垂直于屏幕平移(你设置的视的远近); -
缩写
transform:translate(x值,y值) ; 或者是transform:translate3d(x值,y值,z值) ; -
若使用z轴,那么需要在父元素设置视点
perspective:值 -
取值 px、em、百分比
-
学到的经验
- 要学会看懂MDN语法实例
- translate(-50%,-50%)可做绝对定位元素的居中
scale 缩放
-
通常属性
transform:scaleX()以X轴为基准缩小或放大; transform:scaleY()以Y轴为基准缩小或放大; -
缩写
transform:scale(x,y) -
取值:不加单位的数字代表倍数
-
学到的经验
- 一般不会用,容易模糊,变形
rotate 旋转
-
通常属性
transform:rotateX(deg) ; transform:rotateY(deg) ; transform:rotateZ(deg) ; -
缩写
transform:rotate(deg) 默认是以Z轴旋转 -
学到的经验
- 一般用于360度旋转制作loading加载动画
- 用的时候记得查看MDN文档
skew 梯形旋转(方便理解)
-
属性
transform:skewX(deg) ; transform:skewY(deg) ; transform:skew(deg) ; -
需要注意的
- 把方形变成平行四边形一样旋转
- 用的很少,用的时候查skew MDN文档就好了
transform 多重效果
- 组合使用
transform:scala(1.5) translate(-100%,-100%) 注意用空格隔开就好了 - transform:none; 取消所有效果
心得
- 学好CSS需要好的想象力,逻辑在这里不重要
- CSS给的属性比较简单,但可以组合成很复杂的东西
- 多看看,多敲敲代码
transition 过渡
作用
- 补充盒子从a点到b点中间的动画
语法
-
transition:属性名/时长/过渡方式/延迟
例如:transition:left 200ms linear
-
可以用逗号分隔开两个不同属性
例如:transition:left 200ms,top 400ms
-
可以用all 代表所有属性
例如:transition:all 200ms;
-
过渡方式:
- linear:线性过渡
- ease:缓动的
- ease-in:快进缓动
- 如果这里不够用就看MDN
注意:
- 过渡必须要有起始
- 一般只有一次动画或者两次
多次动画animation和@keyframes
animation
- 声明关键帧
- 添加动画
- 属性
- 时长:1s or 100ms
- 过渡方式:默认是easa 和transition取值一样,如linear
- 方向:reverse反向动画、alternate开始后回来
- 填充模式:none、forwards动画结束后停在动画最后的关键帧上、backwards、both(这个待补充,没怎么看明白)
- 是否暂停:poused暂停或者是running不暂停
- 以上所有属性都有对应的单独属性,如果只设置其中一个属性就需要把单独属性写全
@keyframes 定义动画的关键帧
- 语法
@keyframes 动画名称 {
0% {
transform:translateX(100px)
};
50%{
transform:translateX(150px)
};
100%{
transform:translateX(200px)
};
也可以
for {
transform:translateX(100px)
}
to {
transform:translateX(150px)
}
每一次运动后下一个关键帧必须要保留上一次的运动,否则会有问题
}
补充动画的更多实现方法
-
使用多次transform
- .a===transform===> .b
- .b===transform===> .c
-
如何知道中间点
用setTimeout或监听transitonend事件