调试 CSS Keyframe 动画

学会语法就可以制作 CSS 动画,但是要想做出动感、美观的动画,仅会语法是不够的。动画直接关系到用户体验,因此我们需要改进代码,从而找到正确的触发时机并掌握调试动画的方法。经过一番研究之后,我总结了一些有用的工具和方法。

使用负的延迟值

如果你需要同时执行多个动画并错开它们的开始时间,可以使用animation-delay。但是这会导致用户打开网页时有些元素需要静止一段时间才会开始移动。

此时可以给animation-delay设置一个负数,这样会将播放头向前移动,因此用户打开网页的时候所有动画都会播放。使用这种方式可以通过共享一套 keyframes 来实现不同的动画。

这个技巧也可以用来调试。设置animation-play-state: paused;然后把延迟设置成不同的负数,就可以看到动画在不同帧的状态。

.thing {
  animation: move 2s linear infinite alternate;
  animation-play-state: paused;
  animation-delay: -1s;
}

示例:

http://codepen.io/css-tricks/embed/LVMMGZ

在下面这个有趣的例子中,可以看到两个机器人的动作错开了一点时间,这样看起来会更自然。我们给粉色的机器人设置一个负的延迟,这样用户打开网页的时候他就已经处在移动状态了。

.teal {
 animation: hover 2s ease-in-out infinite both;
}

.purple {
 animation: hover 2s -0.5s>http://www.0771ybyy.com/case/zhichuangjibing/1775.html< ease-in-out infinite both;
}

@keyframes hover {
  50% {
    transform: translateY(-4px);
  }
}

示例:http://codepen.io/sdras/embed/qdLJLJ

多 transform 之殇

为了充分提高性能,你需要尽可能多地使用transform来移动和改变元素,这样就会减少修改margintop/left之类属性带来的重绘损耗。Paul Lewis维护的CSS Triggers非常棒,可以直观地看出这些属性对应的损耗。然而,如果你使用多个 transform 来移动元素,就可能带来一系列问题。

第一个问题是顺序。Transform 并不像你想的那样同步发生,而是按照一定顺序。最右边的操作最先执行,然后往左依次执行。举例来说,下面的代码中scale首先执行,然后是translate,最后是rotate

@keyframes foo {
 to {
   /*         3rd           2nd              1st      */
   transform: rotate(90deg) >http://www.0771ybyy.com/zc/1795.html<translateX(30px) scale(1.5);
 }
}

大多数情况下这不是我们想要的,通常我们希望这些操作同时发生。此外,如果你把 transform 分割成多个 keyframe,事情会变得更加复杂,有些操作同步,有些操作不同步。比如下面这个例子:

@keyframes foo {
  30% {
    transform: rotateY(360deg);
  }
  65% {
    transform: translateY(-30px) rotateY(-360deg) scale(1.5);
  }
  90% {
    transform: >http://www.0771ybyy.com/zc/1794.html<translateY(10px) scale(0.75);
  }
}

这段代码会产生非常糟糕的效果。不幸的是,解决方法并不优雅,通常你必须嵌套多个<div>,每个应用一个变化,这样就不会产生冲突。

http://codepen.io/sdras/embed/bdOvJL

还有一些解决方法,比如使用矩阵变换(通常无法手写)或者使用 JavaScript 的动画 API(比如GreenSock),这样就可以同步执行多个变换操作。

使用多个 div 还可以解决 SVG 的一些 bug。在 Safari 中,不能同时声明 opacity 和 transform 动画——其中一个会失败。你可以查看本文的第一个例子。

在 2015 年 8 月初,Chrome Canary 支持独立 transform 声明。这意味着我们不再需要关心执行顺序,你可以分别声明rotatetranslatescale

调试工具

ChromeFirefox都提供了调试动画的工具。这些工具提供了控制速度的滑块、暂停按钮以及 easing 值对应的 UI。对于调试 CSS 动画来说,减速并检查特殊位置的动画效果真的非常有用。

这些工具都使用了 Lea Verou 的cubic-bezier.com可视化工具和 GUI。这样你就可以直接进行调试,不用每次都跑到网站上输入文本。

这些工具可以帮助我们细粒度地调整动画,下面是两个工具的 UI:

Chrome 和 Firefox 都可以控制时间(加速或者减速),也可以手动执行动画。Chrome 正在开发许多高级的时间线工具,可以用它们同时调试多个元素。这是件好事,每次只能调试一个元素确实是个很大的限制。

我遇到的一个问题是,如果元素的动画时间很短,那就很难及时获取这个元素。我的解决方案是设置animation-iteration-count: infinite;,这样就不需要和时间赛跑。

此外,我发现减速、重播以及调整时间非常有用,你可以在很低的层面观察动画到底是如何执行的。如果你在低速下调整好动画,恢复到正常速度之后动画会变得非常棒。

使用 JavaScript 调试 CSS 动画事件

如果你想知道每个动画触发的准确时间和位置,可以使用 JavaScript 来监听animationstartanimationiterationanimationend事件并输出信息。

看下面这个例子:

http://codepen.io/sdras/embed/PqXeMX

保证 keyframe 足够准确

我经常看到有人在 0% 和 100% keyframe中声明相同的属性和值。没必要这样做,浏览器会在动画开始和结束时自动处理属性值。

如下所示:

.element {
 animation: >http://www.0771ybyy.com/sunshang/1788.html<animation-name 2s linear infinite;
}

@keyframes animation-name {
  0% {
   transform:>http://www.0771ybyy.com/zc/1793.html< translateX(200px);
 }
  50% {
   transform: translateX(350px);
 }
 100% {
   transform: translateX(200px);
 }
}

可以改写成:

.element {
 transform: translateX(200px);
 animation: >http://www.0771ybyy.com/zc/1792.html<animation-name 2s linear infinite;
}

@keyframes animation-name {
  50% {
   transform: translateX(350px);
 }
}

让动画也 DRY

漂亮和简洁的动画通常意味着一个特殊的cubic-bezier()easing 函数。仔细调整过的 easing 函数会成为公司的一个特点。动画会传递公司的品牌和“声音”。如果你在网站中大量使用这个函数,最简单(并且最一致)的方法就是把函数保存到变量中,我们就是这么做的。SASS 或者其他预/后处理器都可以做到这一点:

$smooth: cubic-bezier(0.17, 0.67, 0.48, 1.28);

.foo { animation: >http://www.0771ybyy.com/zc/1791.html<animation-name 3s $smooth; }

.bar { animation: animation-name 1s $smooth; }

如果使用 CSS keyframe 编写动画,我们需要尽量利用 GPU。这意味着如果你需要操作多个对象,就需要提前准备好 DOM 并给元素分层。使用标准的 CSS 声明代码块可以让硬件加速原生 DOM 元素(SVG 不行)。由于我们需要复用代码块,把它存储到 mixin 或者 extend 中是个不错的选择:

@mixin accelerate($name) {
 will-change: $name;
 transform: translateZ(0);
 backface-visibility: hidden;
 perspective: >http://www.0771ybyy.com/zc/1790.html<1000px;
}

.foo {
  @include accelerate(transform);
}

一定要小心,同时操作多个元素可能会引发副作用并严重降低性能。大多数动画都没有问题,不过如果你使用类似 haml 的技术来生成多个 DOM 元素,那就要小心了。

使用循环提高性能

Smashing Magazine 最近发布的一篇文章中详细介绍了Species in Pices项目的原理。在其中的一节里,作者解释了为什么同时操作大量对象会导致性能问题。他说:

假设你要同时移动 30 个对象;你需要浏览器做很多工作,因此会导致问题。如果你的动画速度是 0.199 秒并且每个对象都延迟 0.2 秒,那同时只会操作一个对象,从而解决问题。虽然总的动画次数不变,但是因为动画现在变成了一个连续执行的序列,性能可以提高 30 倍。

可以使用 Sass 或者其他预/后处理器的for循环来编写这样的代码。下面是我写的一个简单的例子:

@for $i from 1 through $n {
  &:nth-child(#{$i}) {
    animation: loadIn >http://www.0771ybyy.com/sunshang/1789.html<2s #{$i*0.11}s $easeOutSine forwards;
  }
}

这不仅会错开动画,还可以错开其他的视觉效果,比如颜色改变。(点击 rerun 来重播动画。)

示例:http://codepen.io/sdras/embed/RPEMZr

调整动画顺序

编写很长的动画时,常用的办法是把它们写成一个序列并加上延迟,比如:

animation: foo 3s ease-in-out, bar 4s 3s ease-in-out, brainz 6s 7s ease-in-out;

但是假设你现在要重构代码,需要修改第一个动画的时间,这会导致后续的动画都需要修改时间。这也不是什么大事:

animation: foo 2.5s ease-in-out, bar 4s 2.5s ease-in-out, brainz 6s 6.5s ease-in-out;

不过假设我们需要添加一个新动画并再次调整时间(在实际项目中类似的改动经常发生),就会发现这种修改方式非常低效。如果你做过 3 次以上,就会明白,这真的很低效。

继续,假设动画执行到一半的时候有两个改动需要同时出发,所以你需要保证两个不同的属性一致然后……好的,你应该懂了。这就是为什么处理超过三个串联动画时我会使用 JavaScript 的原因。就我自己来说,我喜欢使用GreenSock 动画 API,因为它的时间线功能非常好用,而且不需要重新计算就能轻松重叠多个动画,这可以极大地提升效率。

改进动画远比编写难。通常来说,需要不断编辑、修改和调试才能提高项目的质量和性能。希望这些技巧可以帮助你更好地编写动画。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: CSS3动画是一种非常强大的动画技术,它可以让网页变得更加生动、美丽。本文将为大家详细介绍CSS3动画的各个属性,包括动画名称,持续时间,延迟时间,动画速度曲线,以及动画的执行次数等。 动画名称(animation-name):与CSS中的类似,动画名称是指定CSS3动画使用的关键帧动画。这个属性用来指定一个已定义的动画名称,以便调用该动画。 持续时间(animation-duration):定义CSS3动画的持续时间。默认值为0,表示没有动画效果。通过使用单位“秒(s)”或“毫秒(ms)”来定义动画的持续时间。 延迟时间(animation-delay):指定动画开始前的等待时长。默认值为0,即动画将立即开始。通过使用单位“秒(s)”或“毫秒(ms)”来定义延迟时间。 动画速度曲线(animation-timing-function):定义动画的速度曲线,可以使动画有更加自然的过渡效果。使用缓动函数可以让动画更具有灵活性,可以在不同的时间点采用不同的速度曲线,从而实现更复杂的动画效果。 动画执行次数(animation-iteration-count):指定动画的执行次数。可以使用数字或者“infinite”关键字来指定动画的执行次数。如果将其设置为“infinite”则表示动画将一直持续执行下去。 动画方向(animation-direction):指定动画是否循环播放,并且指定循环播放的方向。这个属性可以使用以下值:normal,reverse,alternate和alternate-reverse。 动画填充模式(animation-fill-mode):指定动画在开始或结束时对元素的样式应该如何处理。使用这个属性可以让动画具有更加平滑的效果,可以避免由于动画结束时样式的改变而造成的过度影响。 总之,通过使用上述属性,我们可以为网页添加各种丰富的动画效果,让网页更加互动、生动,也更能吸引用户的眼球。 ### 回答2: CSS3动画是网页开发中非常常用的一种技术,通过使用动画属性可以给页面的元素增添动态的效果。本文将详细介绍CSS3动画的各个属性。 1. animation-name 该属性定义要绑定到要执行动画的@keyframes的名称。@keyframes是定义动画的关键帧的规则集合。 2. animation-duration 该属性定义了动画完成所需的时间,以秒或毫秒为单位。 3. animation-timing-function 该属性定义了动画执行的时间曲线。通过使用不同的时序函数,可以使动画更真实,更有质感。 4. animation-delay 该属性定义动画开始之前的延迟时间,以秒或毫秒为单位。 5. animation-iteration-count 该属性定义动画的迭代次数。可以将其设置为有限或无限。 6. animation-direction 该属性定义动画是否反向播放。 7. animation-fill-mode 该属性定义了元素在动画之前和之后的状态。可以设置为none、forwards、backwards或both。 8. animation-play-state 该属性定义动画的运行状态。可以将其设置为paused或running。 9. animation animation属性是所有动画属性的缩写。它接受每个属性的值作为逗号分隔列表。 总结: 上述就是CSS3动画常用属性的详细介绍。CSS3动画可以用来为页面增添动态效果,提高用户的交互体验。在实际开发中,可以通过不同的动画属性以及不同的取值方式,创建出各种不同的动画效果。在制作动画时,需要考虑兼容性问题,如果要兼容IE9及以下版本,我们还需要使用Vendor Prefix前缀来避免浏览器的兼容问题。 ### 回答3: CSS3动画是将元素从一个状态变换到另一个状态的方式,其中使用了一些简单的CSS属性。CSS3动画属性可以通过@keyframe规则或transition属性设置。它们可以用来创造一些很棒的效果,比如向上滚动的标题、浮动的按钮等。下面详细介绍一下CSS3动画涉及的各种属性。 1. animation-name:用来定义动画的名称,这个名称会由animation属性引用。 2. animation-duration:定义动画的持续时间。单位为秒(s)和毫秒(ms)。 3. animation-timing-function:定义动画的速度变化曲线。这个属性定义了过渡的速度,是一个三次贝塞尔函数。可以设置ease、linear、ease-in、ease-out、ease-in-out和cubic-bezier等值。 4. animation-delay:定义动画开始之前的延迟时间。单位为秒(s)和毫秒(ms)。 5. animation-iteration-count:定义动画的重复次数。可以设置为一个具体的数字或infinite表示无限次重复。 6. animation-direction:定义动画结束后是否负向重复播放。可以设置为normal、reverse、alternate和alternate-reverse。 7. animation-play-state:定义动画是运行还是暂停。可以设置为paused和running。 8. animation-fill-mode:定义动画结束后如何应用样式。可以设置为none、forwards、backwards和both。 以上是CSS3动画中涉及的主要属性。其中最重要的要数animation-iteration-count和animation-duration两个属性。animation-iteration-count可以定义动画的重复次数,也可以设置为infinite表示无限次重复。animation-duration用来定义动画的持续时间,如果不设置,默认值为0,此时动画是不会播放的。在设置这两个属性时,需要根据具体情况来确定合适的数值,以达到最佳的动画效果。 总的来说,CSS3动画提供了丰富的效果和属性,可以应用于页面中的各种元素和功能,让页面更加生动、美观、时尚。在开发过程中,合理应用这些属性,可以使前端开发变得更加有趣和富有挑战性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值