一、问题场景
1、目标动画的实现:
想实现一个元素A从位置1平移到位置2,并且在移动过程中逐渐缩小、透明度变小
2、原代码实现:
.a{
//分别设置了:动画keyframes名称、单次持续时间、
//timing function、delay时间、iter count
//以及animation-fill-mode(代表的是动画开始前后保持在哪个样式)
animation: move 0.3s linear 1s 3 both;
}
@keyframes move {
0% {
transform: scale(1);
opacity: 1;
top: 16vh;
left: 40vw;
}
100% {
transform: scale(0.5);
opacity: 0.5;
top: 6vh;
left: 10vw;
}
}
3、产生效果:
- 谷歌浏览器按照预期进行
- Safari浏览器,在动画的最后一帧时,回到初始的scale和opacity设置,但并没有移动到相应的偏移位置
二、问题原因
根据在动画的最后一帧时,元素回到初始的scale和opacity设置,但并没有移动到相应的偏移位置这一信息,可以知道并非fill-mode没有生效,而是在渲染初始样式时,偏移位置没有和scale、opacity同步生效。
根据三者属性的差别,transform、opacity是用gpu渲染的属性,gpu的性能高、渲染生效速度更快。而left、top的设置需要对DOM节点进行操作,而非图层计算,因此可能在不同的浏览器性能下造成复杂动画渲染不同步的问题。
三、问题解决
使用translate来进行动画位移!
代码如下:
@keyframes move {
0% {
transform: translate(40vw,16vh) scale(1);
opacity: 1;
}
100% {
transform: translate(10vw,6vh) scale(0.5);
opacity: 0.5;
}
}
transform实现多维度变形时,用空格隔开,
transform的最佳排列顺序是translate、scale、rotate,避免计算偏离预期(当然也要根据变形需要再针对性看)