首页 前端知识 CSS 之 帧动画(Keyframe Animation)

CSS 之 帧动画(Keyframe Animation)

2024-06-18 09:06:58 前端知识 前端哥 998 588 我要收藏

一、简介

​ CSS 制作 Web 动画有两种方式: 帧动画(Keyframe Animation)和过渡动画(Transition Animation)。在不同的业务场景中,我们应该选择不同的动画方式,通常来说:对于交互元素,会使用过渡动画,而对于连续的装饰性元素,则应该使用帧动画。

​ 本文章将会仔细讲解帧动画的相关知识,让你对其有一个较为全面的了解。

二、帧动画

1、基本概念

​ 帧动画允许你通过指定 CSS 属性在不同时间点上的行为来创建动画效果,这些时间点被称为关键帧,所以又被称为关键帧动画。帧动画需要通过@keyframes来创建。

​ 关键帧动画的主要思想是在多个不同时间点的CSS代码块之间进行插值计算,这个插值计算由浏览器自动完成的,它会根据@keyframes中定义的多个代码块中的样式变化,自动创建样式变化的中间状态,从而样式能够平滑的变化。

​ 一个帧动画主要由两个关键部分组成:创建帧动画和使用帧动画。

2、创建帧动画
动画名称:

​ 在使用@keyframes创建关键帧动画时,会在其后面跟随一个自定义标识符,表示当前动画的名称,该名称可在其所在作用域内通过animation-name使用。但要注意的是:不要使用CSS的关键词来命名动画,例如autowidth等等,这可能会导致动画失效。

@keyframes 动画名称 {...}

/* 正确命名 */
@keyframes fadeOut {...}

/* 错误命名 */
@keyframes auto {...}   

​ 动画名称标识符是严格区分大小写的,fadeOutfadeout是两个不同的名称。而且如果多个动画使用相同的名称,则通过动画名称调用动画时,将以定义顺序中的最后一个动画为准。

/* 严格区分大小写 */
@keyframes fadeOut {...}
/* 两者并不相同 */
@keyframes fadeout {...}

/* 当命名重复时 以最后定义的为准 */
@keyframes fadeOut {...}
动画关键帧:

@keyframes内部没有时间的概念,它只有一个百分比完成的概念,n%表示的是动画完成的百分比,可以在0%~100%之间的任何一个位置定义,一个百分比表示一个关键帧,可以定义任意数量的关键帧。浏览器会在关键帧之间进行插值计算,使帧与帧之间的样式平滑的进行变化。

@keyframes 动画名称 {
  /* 动画关键帧 */
  0% {
    /* 样式 */
  }
  /* 。。。 */
  100% {
    /* 样式 */
  }
}

​ 除了使用n%之外,还有两个关键字fromto可以使用,两者分别等同于0%100%

@keyframes fadeOut {
    0% {
        opacity: 1;
    }
    
    100% {
        opacity: 0;
    }
}
/* 等同于 */
@keyframes fadeOut {
    from {
        opacity: 1;
    }
    
    to {
        opacity: 0;
    }
}

​ 在 @keyframes 规则中的关键帧顺序并不重要,因为浏览器将按照百分比值的顺序播放,而不是按照它们在代码中出现的先后顺序播放。而且如果定义的关键帧百分比出现了重复的情况,则在执行时,会将重复的关键帧百分比进行合并,如果存在重复的属性,则属性值以最后定义的为准。

@keyframes move {
    0% {
      background: red;
      transform: translateX(0);
    }
    50% {
      background: yellow;
      transform: translateX(200px);
    }
    100% {
      background: red;
      transform: translateX(0);
    }
    50% {
      transform: translateX(50px);
      opacity: 0.5;
    }
}
/* 等同于 */
@keyframes move {
    0% {
      background: red;
      transform: translateX(0);
    }
    50% {
      background: yellow;
      transform: translateX(50px);
      opacity: 0.5;
    }
    100% {
      background: red;
      transform: translateX(0);
    }
}

​ 如果没有指定 0% / from 关键帧,以及100% / to 关键帧,则浏览器会以动画绑定元素的初始样式为内容,构造 0% / from 关键帧和100% / to 关键帧。

.d {
  width: 100px;
  height: 100px;
  background: red;
  animation: move 2s infinite;
} 
@keyframes move {
  /* 未定义 0%和100% 关键帧 */
  50% {
    background: yellow;
    transform: translateX(200px);
    width: 200px;
  }
}
/* 等同于 */
@keyframes move {
  0% {
     width: 100px;
     height: 100px;
     background: red;
  }
  50% {
    background: yellow;
    transform: translateX(200px);
    width: 200px;
  }
  100% {
     width: 100px;
     height: 100px;
     background: red;
  }
}
关键帧中的!important

​ 关键帧中的!important将会被忽略,并不会抬高样式属性值的权重。因为在元素动画过程中,关键帧中声明的样式不在级联的上下文中,但本身的权重已经超过所有的普通权重样式,所以再无法通过!important来提高权重。

​ 但是动画所绑定的元素上的样式如果使用了!important,则该样式不会被动画中定义的样式属性值所影响,因为该权重超过了动画样式的权重。

@keyframes move {
    0% {
      background: red;
      transform: translateX(0);
    }
    50% {
      background: yellow;
      transform: translateX(50px);
    }
    100% {
      background: red;
      transform: translateX(0);
    }
}

.d {
    width: 100px;
    height: 100px;
    /* 该样式使用了important提高权重 不会被动画关键帧中的样式所影响 */
    background: red !important;
    animation: move 2s infinite;
}
关键帧中的CSS自定义属性:

​ CSS的自定义属性是指以--开头的声明的变量,其可以通过var(--属性名)的形式,将自定义属性的属性值在作用域范围内的任何一个属性上使用:

.d {
    /* 定义自定义属性 */
    --w: 20px;
    /* 使用自定义属性 等同于 width: 20px; */
    width: var(--w);
    height: 20px;
    background: red;
    /* 使用自定义属性 等同于 border: 20px solid #ccc; */
    border: var(--w) solid #ccc;
}

​ 自定义属性可以在关键帧中使用,可以正常渲染,但是如果在关键帧中修改自定义属性的值,且元素样式中使用了该自定义属性,则浏览器无法对其进行插值计算,也就无法实现平滑的动画效果。主要原因为CSS 自定义属性的值对于浏览器来说相当于一个字符串,字符串的变化属于是不连贯的属性,无法进行插值计算。

@keyframes changeW {
  50% {
    --w: 40px;
  }
}
.d {
   --w: 20px;
   width: var(--w);
   height: 20px;
   background: red;
   border: var(--w) solid #ccc;
   animation: changeW 2s infinite;
}

​ 该问题可以通过CSS的@property特性来解决,但该特性属于实验性技术,有浏览器兼容性问题。因此此处就不展开叙述了,更多具体可查看: @property。

关键帧合并:

​ 如果@keyframes 中定义的多个关键帧存在样式属性重复,则可以将多个关键帧进行合并定义,减少代码重复。再将各个关键帧中不重复的样式属性进行单独定义,浏览器会将定义两次的关键帧内的样书进行合并,如果存在重复的属性,则属性值以最后定义的为准。

@keyframes move {
  /* 将多个关键帧中的重复样式属性合并定义 */
   0%,
   100% {
     background: red;
     transform: translateX(0);
     width: 100px;
   }
   50% {
     background: yellow;
     transform: translateX(200px);
     width: 200px;
   }
  /* 不重复的样式属性再进行单独定义 */
   100% {
     /* 该关键帧的定义位于后面 所以属性值优先级高 */
     width: 150px;
   }
}
/* 等同于 */
@keyframes move {
   0%{
     background: red;
     transform: translateX(0);
     width: 100px;
   }
   50% {
     background: yellow;
     transform: translateX(200px);
     width: 200px;
   }
   100% {
     background: red;
     transform: translateX(0);
     width: 150px;
   }
}
3、使用帧动画

@keyframes 仅仅是定义了在所在作用域内全局都可以使用的关键帧动画,定义好了动画的过程,但是其并不能自动应用。还需要通过CSS的animation属性来显式的指定关键帧动画应用的元素,以及一系列相关的动画属性。

.test-div {
  /* 使用动画 */
  animation: fadeOut 500ms linear;
}
animation-name:

​ 该属性用于指定引用@keyframs动画的名称,必须严格遵守大小写,fadeOutfadeout是两个不同的名称。

animation-name:fadeOut;

​ 该属性可以设置多个动画名称,属性值之间通过,进行分隔,表示同时引用多个动画。

animation-name:fadeOut, moveTo;
animation-duration:

​ 该属性用于指定动画完成一个周期所需要的时间,值必须为非负数,单位为sms,默认为0。该时间定义了**@keyframes** 中的的时间轴,关键帧百分比值(n%)对应的时间节点是相对于该时间轴来计算的。

animation-duration: 2s;
animation-duration: 200ms;

​ 如果该属性值为0,则动画效果是否可见取决于animation-fill-mode属性的值,而animation-fill-mode的表现效果又受到animaiton-direction属性的影响。具体情况分为下面四种:

  • 如果animation-fill-mode: none;,无论animaiton-direction设置什么值,则动画无任何视觉效果。
  • 如果animation-fill-mode: forwards/both;,且animaiton-direction: normal/alternate;,则动画会直接显示最后一帧的样式效果。
  • 如果animation-fill-mode: forwards/both;,且animaiton-direction: reverse/alternate-reverse;,则动画会直接显示第一帧的样式效果。
  • 如果animation-fill-mode: backwards;,无论animaiton-direction设置什么值,则动画都会直接显示第一帧的样式效果。

​ 该属性可以设置多个运动时间,属性值之间通过,进行分隔,设置的多个属性值会按照顺序映射到对应的animation-name中的动画上。如果该属性值的数量等于animation-name属性值的数量,则两者一一对应;如果该属性值的数量小于animation-name属性值的数量,则多余的动画以重复该属性的属性值,使属性值与动画一一对应;如果该属性值的数量大于animation-name属性值的数量,则多余的属性值会被忽略。

.animated {
    animation-name: translate, rotate, scale;
    animation-duration: 1s;
    /* 属性值数量小于动画的数量 最终等同于 */
    animation-duration: 1s, 1s, 1s;
}

.animated {
    animation-name: translate, rotate, scale;
    animation-duration: 1s, 2s;
    /* 属性值数量小于动画的数量 最终等同于 */
    animation-duration: 1s, 2s, 1s;
}

.animated {
    animation-name: translate, rotate, scale;
    /* 属性值数量等于动画的数量 一一对应 */
    animation-duration: 1s, 2s, 3s; 
}

.animated {
    animation-name: translate, rotate, scale;
    animation-duration: 1s, 2s, 3s, 4s;
    /* 属性值数量大于动画的数量 最终等同于 */
    animation-duration: 1s, 2s, 3s; 
    /* 动画时间 4s 没有相应的关键帧动画,将会被忽略 */
}

animation-timing-function:

​ 该属性用于指定动画执行时的速度曲线,属性值有:linearease(默认值)、ease-inease-outease-in-out ,以及steps()cubic-bezier()(贝塞尔曲线函数)。

animation-timing-function:linear;
  • linear表示匀速运动,速度曲线是一条直线。

  • ease(默认值)表示慢-快-慢,初期速度很慢,然后先逐渐加速,再快速减速,最终缓慢结束。加速过程较缓,减速过程较快。

  • ease-out表示减速运动,先快后慢,初期速度很快,然后逐渐减速,最终缓慢结束。

  • ease-in表示加速运动,先慢后快,初期速度很慢,然后逐渐加速,最终快速结束。

  • ease-in-out表示慢-快-慢,初期速度慢,然后逐渐加速,中期速度最快,然后逐渐减速,最终缓慢结束。加速过程和减速过程相当。

  • linear() 函数定义了一个分段线性函数,可以在其各个点之间线性插值,从而允许你模拟出更复杂的动画效果,比如弹跳和弹簧等效果。JS或SVG可以通过linear曲线生成器 生成相应的曲线参数。

  • steps()函数定义了分步运动,其效果相当于逐步执行过渡动画,类似于帧动画,接受两个参数,第一个参数指定的是步数,第二个参数指定的是方向。第二个参数值可以是 jump-startjump-endjump-nonejump-bothstartend(默认值) ,其中 startjump-start 表现行为一样,同样的 endjump-end 表现行为一样。函数还有两个预定义的关键字:step-startstep-end。前者等同于 steps(1, start),而后者等同于 steps(1, end)

    jump-start表示第一步动画在开始时发生;jump-end 表示最后一步动画在结束时发生;jump-both 表示在 0% 和 100% 处均出现跳跃,相当于在动画过程中加上一步;表示两端均无跳跃,而是在 0% 处和 100% 处将值各保持 1/n 的时长。更多内容可以查看:easing-function

  • cubic-bezier()用于定义贝塞尔曲线,贝塞尔曲线由 P0、P1、P2 和 P3 四个点进行定义。P0 和 P3 是曲线的起点和终点,在 CSS 中,这两个点是固定的,因为坐标是成比例。P0 为 (0, 0),代表初始时间和初始状态,P3 为 (1, 1),代表最终时间和最终状态。其余的中间点 P1(x1,y1)、P2(x2,y2) 是可以动态改变的两个点,对应 cubic-bezier(x1,y1,x2,y2) 中的四个参数,通过改变 P1、P2 两点的坐标值来动态生成的贝塞尔曲线表示动画中的速度变化。

    ​ 具体的贝塞尔曲线很难直接书写出来,我们可以通过贝塞尔曲线生成器,来获取对应的曲线值。或者可以通过浏览器调试工具对速度曲线进行调整。

    ​ 在固定y的情况下,x越大运动越慢,在固定x情况下,y越大运动越快。y如果是负数,则元素会变小,y’如果大于1,则会变大,但最终还会恢复为1。

    在这里插入图片描述

animation-delay:

​ 该属性用于指定动画初始开始执行前需要延迟等待的时间,单位为sms,默认为0。如果动画会执行多次,也只会在初次执行时进行延迟等待,在后续执行时,不会再进行延迟等待。

animation-delay: 2s;

​ 该属性设置的属性值通常为正值,但如果属性值为负数,则浏览器会按照该负数的绝对值时间,跳转到该时间对应的动画节点处开始执行动画,类似于动画从中间节点开始执行。其实负值中的负号相当于一个信号,告诉浏览器将这个值视为偏移而不是延迟,偏移到该时间对应的动画节点处开始执行动画。

​ 如果指定的偏移时间(animtion-delay)大于动画单次迭代的持续时间,则需要进一步考虑是否有足够的迭代次数,使动画总的执行时间大于偏移时间。如果大于等于,则初始会偏移跳转到对应的时间节点处开始执行动画;如果小于,则动画不会有执行过程,而且直接跳转到动画的最终结束状态。

<style>
@keyframes move {
  0% {
    background: red;
    transform: translateX(20px);
  }
  50% {
    background: yellow;
    transform: translateX(200px);
  }
  100% {
    background: red;
    transform: translateX(0);
  }
}
.d {
    width: 180px;
    height: 100px;
    margin-bottom: 10px;
    background: red;
    /* 执行时间5秒 匀速 保留结束和开始样式 执行1次 */
    animation: move 5s linear both 1;
    /* 延迟时间为0 */
    animation-delay: 0;
}
.d1 {
    /* 延迟时间为正数 正常延迟 */
    animation-delay: 3s;
}
.d2 {
    /* 延迟时间为负数 且绝对值小于动画的总执行周期 延迟变为偏移 从中间1.5s节点开始执行 */
    animation-delay: -1.5s;
}
.d3 {
    /* 延迟时间为负数 且绝对值大于动画的总执行周期 直接展示结束状态 */
    animation-delay: -6s;
}
</style>

<body>
  <div class="d"></div>
  <div class="d d1"></div>
  <div class="d d2"></div>
  <div class="d d3"></div>
</body>

页面效果:

在这里插入图片描述

​ 该属性还可以设置多个动画延迟时间,属性值之间通过,进行分隔,设置的多个属性值会按照顺序映射到对应的animation-name中的动画上。如果该属性值的数量等于animation-name属性值的数量,则两者一一对应;如果该属性值的数量小于animation-name属性值的数量,则多余的动画以重复该属性的属性值,使属性值与动画一一对应;如果该属性值的数量大于animation-name属性值的数量,则多余的属性值会被忽略。

.element {
    animation-name: color, translate, scale, rotate, opacity;
    animation-delay: .5s;
    /* 属性值数量相等 最终等同于 */
    animation-delay: .5s, .5s, .5s, .5s, .5s;
}

.element {
    animation-name: color, translate, scale, rotate, opacity;
    animation-delay: .5s, 1s;
    /* 属性值数量小于动画的数量 最终等同于 */
    animation-delay: .5s, 1s, .5s, 1s, .5s;
}

.element {
    animation-name: color, translate, scale, rotate, opacity;
    animation-delay: .5s, 1s, 1.5s, 2s, 2.5s;
    /* 属性值数量等于动画的数量 一一对应 */
    animation-delay: .5s, 1s, 1.5s, 2s, 2.5s;
}

.element {
    animation-name: color, translate, scale, rotate, opacity;
    animation-delay: .5s, 1s, 1.5s, 2s, 2.5s, 3s;
    /* 属性值数量大于动画的数量 最终等同于 */
    animation-delay: .5s, 1s, 1.5s, 2s, 2.5s; /* 多余的 3s 将会被忽略 */
}
animation-iteration-count:

​ 该属性用于指定动画播放的次数,属性值可以为正整数或infinite(循环无限播放),默认为1,表示动画只执行一次。

animation-iteration-count: infinite;
animation-direction:

​ 该属性用于指定动画的执行方向,其属性值有四种:

  • normal(默认值):表示动画正向执行,在每次执行中,都是从0%/from执行到100%/to。如果动画执行多次(animation-iteration-count),则一次执行结束后,下一次执行时会立即回到起点(0%/from),并重新从起点执行。
  • reverse:表示动画反向执行,在每次执行中,都是从100%/to执行到0%/from。如果动画执行多次(animation-iteration-count),则一次执行结束后,下一次执行时会立即回到动画起点(100%/to),并重新从起点执行。
  • alternate:表示动画正反交替执行。如果动画执行多次(animation-iteration-count),则奇数次执行按正向执行,而偶数次迭代按反向执行。
  • alternate-reverse:表示动画反向交替执行。如果动画执行多次(animation-iteration-count),则奇数次执行按反向执行,而偶数次迭代按正向执行。

​ 总结一下:normalreverse 两者表现行为恰好相反;alternatealternate-reverse 两者表现行为恰好相反;alternate 同时具备 normalreverse 两者表现特征。

animation-direction: altermate;

​ 当该属性值为reverse时,动画的时间函数效果也会被反转,因为设置的时间函数是相对于正向执行的。例如:ease-in 时间函数将变为 ease-out

​ 该属性还会影响到animation-fill-mode属性的最终效果,具体可以看下面的animation-fill-mode章节。

animation-play-state:

​ 该属性用于指定动画是否执行,默认值为running,表示正在执行。可以设置属性值为paused,表示暂停动画,动画会暂停执行,并保留当前时间节点的样式状态。如果再次设置属性值为running,则会从当前状态继续执行。

// 暂停动画
animation-play-state: paused;
// 运行动画
animation-play-state: running;

​ 该属性通常与:hover:focus以及通过Js变更类名等操作结合使用,实现动画的暂停与播放。

@keyframes spin {
    to {
        rotate: 360deg;
    }
}

.animated {
    /* 默认正常执行动画 */
    animation: spin 2s linear infinite;
}
.animated:hover {
  	/* hover时暂停动画 离开hover状态时继续执行动画 */
    animation-play-state: paused;
}

​ 还有一种常见的应用场景是:在页面中存在大量的动画时,这些动画可能会消耗大量的 CPU 和 GPU 资源。即使用户当前并未查看页面上的某些动画,它们仍然在后台运行,可能导致性能下降。可以通过暂停那些不在视窗或容器可视区中的动画,只播放位于可视区域内的动画的方式,从而减轻系统负担,提高页面整体性能。

animation-fill-mode:

​ 该属性用于指定动画的填充模式,即在动画执行开始前/结束后,@keyframes 中声明的关键帧样式是否对目标元素有效。

​ 该属性有四个属性值:

  • none(默认值),表示在动画执行结束后@keyframes 中所有样式都无效,展示元素本身的样式。
  • forwards(向前取样式),表示在动画结束后,将会应用动画结束时最后一帧的样式,也就是正常情况下@keyframes100%/to关键帧的样式。该关键帧位于动画结束后的前面,所以是向前取样式。
  • backwards(向后取样式),表示在动画开始前(包括animation-delay时间),将会应用动画开始时第一帧的样式,也就是正常情况下@keyframes0%/from关键帧的样式。该关键帧位于动画开始前的后面,所以是向后取样式。
  • both,表示同时遵循forwardsbackwards的规则,在开始前应用动画开始时的样式,在结束后应用动画结束时的样式。
animation-fill-mode: both;

​ 该属性会被animation-direction属性和animation-iteration-count属性影响到,在使用时要注意。

​ 如果animation-direction属性值为reversealternate-reverse,动画反向播放,则此时动画第一帧的样式对应100%/to,动画的最后一帧对应0%/from。此时该属性设置属性值为forwards/backwards/both,具体的样式效果就会与正常情况相反。

animation-iteration-count属性也是类似的道理,其效果会改变动画的最后一帧对应的样式,从而会影响到animation-fill-mode属性的具体效果。例如下面的例子:动画的最后一个关键帧是 0% ,因为动画运行了两次,第一次迭代是从 0%100% ,第二次迭代从 100%0%

@keyframes ani {
    0% {
        translate: -300px;
    }
    100% {
        translate: 300px;
    }
}
.animated {
    animation: ani5s linear forwards;
    animation-fill-mode: forwards;
		animation-direction: alternate;
		animation-iteration-count: 2;
}

animation-direction属性和animation-iteration-count属性与最后一帧的关系,如下图所示:

在这里插入图片描述

animation-composition:

​ 该属性用于指定动画合成的逻辑,即动画关键帧中的样式属性(效果值)与元素本身的同一样式属性(基础值)或者多个动画元素之前的相同样式属性的复合操作。

  • replace(替换,默认值):表示将效果值覆盖基础值,页面样式为效果值。或者是在多个动画之间,最后一个动画将完全替换之前的动画效果,也就是只有最后一个动画效果会起作用。
  • add(叠加):表示将效果值添加到基础值之后,其效果相当于在基础值的的样式基础上继续叠加效果值的样式。或者是在多个动画之间,将多个动画的效果会叠加在一起,一起影响属性的最终效果。例如,如果一个动画元素向右移动 30px ,而另一个动画使元素向左移动 20px ,使用 add 复合操作之后,元素将向右移动 10px
  • accumulate(累计):表示将效果值与基础值累计相加。如果属性值为数值类型,则最终效果为两者相加后的样式。或者是在多个动画之间,将属性值累计相加。例如元素默认有一个 filter 属性的值为 blur(5px) , 动画1的 0% 位置有一个 blur(10px) ,动画2的 0% 位置有一个 blur(20px) ,设置该属性后,0% 关键帧的 filter 属性的复合值是 blur(35px)
@keyframes move {
  0% {
    transform: translateX(0px);
    width: 200px;
  }
  50% {
    transform: translateX(200px);
    width: 400px;
  }
  100% {
    transform: translateX(0);
    width: 200px;
  }
}
.d {
   width: 180px;
   height: 100px;
   background: red;
   animation: move 5s infinite;
   /* 设置效果为相加 则初始0% 和 结束100%时 的width的实际效果为380px 50%时的实际效果为580px */
   animation-composition: accumulate;
}

​ 该属性通常不在CSS中使用,都是在JavaScript中使用,结合Web动画API使用:

element.animate([
  { transform: 'translateX(0px)' },
  { transform: 'translateX(100px)' }
], {
  duration: 1000,
  composite: 'add'
});

​ 更多相关内容可查看:animation-composition。

其他属性:

​ 除了上面那些标准动画属性之外,还有一些实验性动画属性,此处就不展开讲述了,感兴趣的可以自行查看:

  • animation-range:该属性用于设置动画附件范围沿其时间线的开始和结束位置,即动画沿时间线的开始和结束位置。
  • animation-range-start:该属性用于设置动画的附件范围沿其时间线的开始位置,即动画沿时间线的开始位置。
  • animation-range-end:该属性用于设置动画附件范围沿其时间线的结束位置,即动画沿时间线的结束位置。
  • animation-timeline:该属性用于指定控制 CSS 动画进度的时间线。
animation属性简写:

​ 除animation-composition之外,其他animation的相关属性都可以简写到一起,简写属性如下:

animation: 动画名称 持续时间 运动曲线 延迟等待时间 执行次数 执行方向 填充模式 执行状态
animation: animation-name animation-duration animation-timing-function animation-delay animation-iteration-count animation-direction animation-fill-mode animation-play-state;

​ 例如:

animation: move 2s linear 1s infinite alternate forwards running;

​ 简写属性中<time>类型的属性值的顺序很重要,其中第一个可以被解析时间的值会被分配给animation-duration,再次出现的第二个值,才会分配给animation-delay。而其余属性值的顺序就不是那么重要了。

animation同时应用多个动画:

​ 如果要给同一个元素指定多个动画,则只需要在animation中,通过,分隔设置多个动画的相关动画属性即可。

animation: move 2s linear 1s infinite alternate forwards, bear 2s linear·;

​ 不同的动画之间的属性互不干扰,但具体应用到动画元素上的样式可能会有冲突覆盖。例如,一个动画试图将元素向左移动,而另一个动画同时试图将元素向右移动。此时的具体动画效果就取决于animation-composition属性的值。

​ 为了避免这些问题,要尽量减少多个动画同时作用于同一个元素的情况,可以通过分层动画的形式,拆分动画。例如:

<style>
@keyframes xAxis {
    50% {
        animation-timing-function: ease-in;
         translate:450px 0;
    }
}
@keyframes yAxis {
    50% {
      animation-timing-function: ease-out;
      translate: 0 -450px;
    }
}  
.xAxis {
    animation: xAxis 2.5s infinite linear;
}
.yAxis {
    animation: yAxis 2.5s infinite linear;
}
</style>

<div class="dot xAxis">
    <span class="yAxis"></span>
</div>
转载请注明出处或者链接地址:https://www.qianduange.cn//article/12595.html
标签
评论
发布的文章

jQuery基本使用

2024-06-24 02:06:16

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!