animation和transition的区别

CSS3动画和JS动画的区别

1.JS 实现的是帧动画(使用定时器,每隔一段时间,更改当前的元素)
2.CSS3 实现的是补间动画(过渡(加过渡只要状态发生改变产生动画)动画(多个节点来控制动画)性能会更好)

transition

transition是一个简单的动画属性,可以看作是是animation的简化版本,通常拿来配合事件触发使用,简单易用

transition的属性值:

transition-property:需要过渡的属性,也可以是all,不能用block,none等
transition-duration: 指定从一个属性到另一个属性过渡所要花费的时间。默认值为0,为0时,表示变化是瞬时的,看不到过渡效果
transiton-timing-function:就是过渡的动画类型。可用的类型有liner(匀速)、ease-in(减速)、ease-out(加速)ease-in-out(先加速再减速)、cubic-bezier:三次贝塞尔曲线,可以定制
transition-delay: 指定检测到过渡行为之后延迟一定时间后才开始进行执行

transition的特性:

transition需用事件触发【比如加个hover伪类】,不能在网页加载时自动发生,一次性,不能重复发生,除非一再触发,只有两个状态:开始和结束状态,一条transition规则只能定义一个属性


    
animation

animation-name:用来调用@keyframes定义好的动画,与@keyframes定义的动画名称一致
animation-duration:规定动画完成一个周期所花费的秒或毫秒。默认是 0
animation-timing-function:速度曲线,和transition-timing-function一样,可用的类型有liner(匀速)、ease-in(减速)、ease-out(加速)ease-in-out(先加速再减速)、cubic-bezier:三次贝塞尔曲线,可以定制
animation-delay:规定动画何时开始,默认是 0
animation-iteration-count:规定动画被播放的次数。默认是 1
animation-direction:normal 默认值,如果设置为normal时,动画每次循环都是向前(即按顺序)播放,alternate(轮流),动画播放在第偶数次向前播放,第奇数次向反方向播放(animation-iteration-count取值大于1时设置有效)
animation-play-state:running,可以通过该值将暂停的动画重新播放,这里的重新播放不是从元素动画的开始播放,而是从暂停的那个位置开始播放,paused,暂停播放
animation-fill-mode:默认情况下,动画结束后,元素的样式将回到起始状态,animation-fill-mode属性可以控制动画结束后元素的样式。主要具有四个属性值:none(默认,回到动画没开始时的状态。),forwards(动画结束后动画停留在结束状态),backwords(动画回到第一帧的状态),both(根据animation-direction轮流应用forwards和backwards规则)


    
区别:

1、transition 是过渡,是样式值的变化的过程,只有开始和结束;animation 其实也叫关键帧,通过和 keyframe 结合可以设置中间帧的一个状态;
2、animation 配合 @keyframe 可以不触发时间就触发这个过程,而 transition 需要通过 hover 或者 js 事件来配合触发;
3、animation 可以设置很多的属性,比如循环次数,动画结束的状态等等,transition 只能触发一次;
4、animation 可以结合 keyframe 设置每一帧,但是 transition 只有两帧,所以animation 动画更细腻些;
5、在性能方面:浏览器有一个主线程和排版线程;主线程一般是对 js 运行的、页面布局、生成位图等等,然后把生成好的位图传递给排版线程,而排版线程会通过 GPU 将位图绘制到页面上,也会向主线程请求位图等等;我们在用使用 aniamtion 的时候这样就可以改变很多属性,像我们改变了 width、height、postion 等等这些改变文档流的属性的时候就会引起,页面的回流和重绘,对性能影响就比较大,但是我们用 transition 的时候一般会结合 tansfrom 来进行旋转和缩放等不会生成新的位图,当然也就不会引起页面的重排了;

animation和transition的性能探究

现代浏览器通常由两个重要的线程组成。这两个线程一起工作完成绘制页面的任务:

  • 主线程
  • 合成线程

主线程需要做的任务如下:

  • 运行Javascript
  • 计算HTML元素的CSS样式
  • layout (relayout)
  • 将页面元素绘制成一张或多张位图
  • 将位图发送给合成线程

合成线程主要任务是:

  • 利用GPU将位图绘制到屏幕上
  • 让主线程将可见的或即将可见的位图发给自己
  • 计算哪部分页面是可见的
  • 计算哪部分页面是即将可见的(当你的滚动页面的时候)
  • 在你滚动时移动部分页面

在很长的一段时间内,主线程都在忙于运行Javascript和绘制大型元素。当它忙碌的时候,它就没空响应用户的输入了。

换个角度说,合成线程一直在尝试保证对用户输入的响应。它会在页面改变时每秒绘制60次页面,即使页面还不完整。

例如,当用户滚动一个页面时,合成线程会让主线程提供最新的可见部分的页面位图。然而主线程不能及时的响应。这时合成线程不会等待,它会绘制已有的页面位图。对于没有的部分则绘制白屏。

GPU

如今大多数手机、平板和电脑都带有了GPU芯片。它非常的特别,它很擅长做某些事情,又很不擅长做其他事情。

GPU在做如下操作时很快:
1.绘制东西到屏幕上
2.一次次绘制同一张位图到屏幕上
3.绘制同一张位图到不同的位置、旋转角度和缩放比例

GPU很不擅长做
1.加载位图到内存中

假设我们将一个页面元素的高度从100px渐变到200px,代码如下:

div {
    height: 100px;
    transition: height 1s linear;
}

div:hover {
    height: 200px;
}

下图是一张主线程和合成线程的互相交互的时间线图。注意:黄色盒子的操作是潜在耗时较长的,蓝色盒子的操作是很快的。

image.png

可以看到有很多黄色的盒子,这意味着浏览器要做很多复杂的操作。这就表明这个transition动画很可能会卡。

在transition动画的每一帧中,浏览器都要做下relayout和repaint,然后将位图发送给GPU。之前我们提到了,加载位图到GPU内存中是很慢的。

浏览器之所以这么拼命的工作是因为元素在不停的变化。而且修改元素的高度可能会导致子元素的大小也会变化,所以浏览器不得不进行relayout。在relayout之后主线程还需要重新生成元素的位图。

transition: transform

所以高度的变化是很耗时的,有没有什么东西耗时更少呢?

假设我们将一个元素缩小到其一半大小。同时假设我们使用了transform来缩放元素。那么这个缩小动画的CSS如下:

div {
    transform: scale(0.5);
    transition: transform 1s linear;
}

div:hover {
    transform: scale(1.0);
}

时间线图:

image.png

这次我们很少看到黄色盒子了,这就意味着这个动画可以很流畅!那么为什么transform的动画会和height的动画差别这么大呢?

依据规范,CSS transform属性并不会触发当前元素或附近元素的relayout。浏览器将当前元素视为一个整体,它会缩放、旋转、移动这一整个元素。

这样浏览器只需要在动画开始之时生成位图,然后将位图发送给GPU。之后浏览器不需要做额外的relayout和repaint,甚至不需要发送位图给GPU。浏览器只需要充分发挥GPU的长处:绘制同一张位图到不同的位置、旋转角度和缩放比例。

你可能感兴趣的:(animation和transition的区别)