调试 CSS Keyframe 动画

2023-12-02 20:20

本文主要是介绍调试 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

调试工具

Chrome和Firefox都提供了调试动画的工具。这些工具提供了控制速度的滑块、暂停按钮以及 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,因为它的时间线功能非常好用,而且不需要重新计算就能轻松重叠多个动画,这可以极大地提升效率。

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

这篇关于调试 CSS Keyframe 动画的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/446683

相关文章

前端如何通过nginx访问本地端口

《前端如何通过nginx访问本地端口》:本文主要介绍前端如何通过nginx访问本地端口的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、nginx安装1、下载(1)下载地址(2)系统选择(3)版本选择2、安装部署(1)解压(2)配置文件修改(3)启动(4)

HTML中meta标签的常见使用案例(示例详解)

《HTML中meta标签的常见使用案例(示例详解)》HTMLmeta标签用于提供文档元数据,涵盖字符编码、SEO优化、社交媒体集成、移动设备适配、浏览器控制及安全隐私设置,优化页面显示与搜索引擎索引... 目录html中meta标签的常见使用案例一、基础功能二、搜索引擎优化(seo)三、社交媒体集成四、移动

HTML input 标签示例详解

《HTMLinput标签示例详解》input标签主要用于接收用户的输入,随type属性值的不同,变换其具体功能,本文通过实例图文并茂的形式给大家介绍HTMLinput标签,感兴趣的朋友一... 目录通用属性输入框单行文本输入框 text密码输入框 password数字输入框 number电子邮件输入编程框

HTML img标签和超链接标签详细介绍

《HTMLimg标签和超链接标签详细介绍》:本文主要介绍了HTML中img标签的使用,包括src属性(指定图片路径)、相对/绝对路径区别、alt替代文本、title提示、宽高控制及边框设置等,详细内容请阅读本文,希望能对你有所帮助... 目录img 标签src 属性alt 属性title 属性width/h

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

HTML5 中的<button>标签用法和特征

《HTML5中的<button>标签用法和特征》在HTML5中,button标签用于定义一个可点击的按钮,它是创建交互式网页的重要元素之一,本文将深入解析HTML5中的button标签,详细介绍其属... 目录引言<button> 标签的基本用法<button> 标签的属性typevaluedisabled

HTML5实现的移动端购物车自动结算功能示例代码

《HTML5实现的移动端购物车自动结算功能示例代码》本文介绍HTML5实现移动端购物车自动结算,通过WebStorage、事件监听、DOM操作等技术,确保实时更新与数据同步,优化性能及无障碍性,提升用... 目录1. 移动端购物车自动结算概述2. 数据存储与状态保存机制2.1 浏览器端的数据存储方式2.1.

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

CSS place-items: center解析与用法详解

《CSSplace-items:center解析与用法详解》place-items:center;是一个强大的CSS简写属性,用于同时控制网格(Grid)和弹性盒(Flexbox)... place-items: center; 是一个强大的 css 简写属性,用于同时控制 网格(Grid) 和 弹性盒(F

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求