网页设计中的环境动画:原理与实现(第一部分)

本文由网页设计先驱Andy Clarke详细介绍环境动画的概念与实现方法。通过具体代码示例展示如何使用CSS和SVG创建微妙的环境动画,包括动画元素选择、自然运动提示、性能优化以及可访问性考虑。文章包含完整的CodePen演示代码,帮助开发者掌握创建不干扰用户体验的沉浸式动画效果。

环境动画在网页设计中的应用:原理与实现(第一部分)

创建动画效果可能很棘手。过多会分散注意力,过少则让设计显得平淡。环境动画正是中间地带——微妙、缓慢移动的细节,能够增添氛围而不喧宾夺主。在这篇文章中,网页设计先驱Andy Clarke介绍了环境动画的概念,并解释了如何实现它们。

与基于时间线的动画(通过一系列事件讲述故事)或交互式动画(在用户触摸某物时触发)不同,环境动画是一种被动的运动,起初可能不会引起注意,但它们以微妙的方式让设计显得生动。

在环境动画中,元素可能会微妙地过渡颜色、缓慢移动或逐渐改变位置。元素可以出现和消失、改变大小,或者缓慢旋转。

环境动画不会干扰用户;它们不要求关注、不会分散注意力,也不会干扰用户在使用产品或网站时试图完成的任务。它们也可以很有趣,当用户注意到它们时会露出微笑。这样,环境动画为品牌个性增添了深度。

选择要动画化的元素

并非页面或图形中的所有内容都需要移动,设计环境动画的部分工作是知道何时停止。关键在于选择那些自然适合微妙运动的元素,而不是将运动强加于不合适的地方。

自然运动提示

在决定动画化什么时,我会寻找自然运动提示,并思考在现实世界中某物何时会自然移动。我会问自己:“这个东西有重量吗?”“它灵活吗?”以及“它在现实生活中会移动吗?”如果答案是“是”,那么它移动起来可能会感觉自然。在Ray Dirgo的封面艺术中有几个运动提示。

例如,Quick Draw正在抽的和平烟斗上挂着两根羽毛。当烟斗移动时,它们会左右摆动约三度,就像真正的羽毛一样。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#quick-draw-pipe {
  animation: quick-draw-pipe-rotate 6s ease-in-out infinite alternate;
}

@keyframes quick-draw-pipe-rotate {
  0% { transform: rotate(3deg); }
  100% { transform: rotate(-3deg); }
}

#quick-draw-feather-1 {
  animation: quick-draw-feather-1-rotate 3s ease-in-out infinite alternate;
}

#quick-draw-feather-2 {
  animation: quick-draw-feather-2-rotate 3s ease-in-out infinite alternate;
}

@keyframes quick-draw-feather-1-rotate {
  0% { transform: rotate(3deg); }
  100% { transform: rotate(-3deg); }
}

@keyframes quick-draw-feather-2-rotate {
  0% { transform: rotate(-3deg); }
  100% { transform: rotate(3deg); }
}

氛围而非动作

我经常选择那些能增添氛围但不会争夺注意力的元素或装饰性细节。环境动画不是向用户示意应该看哪里;而是关于创造一种情绪。

在这里,首领在抽烟斗时缓慢而微妙地上升和下降。

1
2
3
4
5
6
7
8
#chief {
  animation: chief-rise-fall 3s ease-in-out infinite alternate;
}

@keyframes chief-group-rise-fall {
  0% { transform: translateY(0); }
  100% { transform: translateY(-20px); }
}

为了增加效果,他头上的羽毛也随着他的上升和下降而移动:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#chief-feather-1 {
  animation: chief-feather-1-rotate 3s ease-in-out infinite alternate;
}

#chief-feather-2 {
  animation: chief-feather-2-rotate 3s ease-in-out infinite alternate;
}

@keyframes chief-feather-1-rotate {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(-9deg); }
}

@keyframes chief-feather-2-rotate {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(9deg); }
}

趣味性与乐趣

我最喜欢环境动画的一点是它们如何为设计带来乐趣。它们是通过有趣的细节展示个性的机会,当人们注意到这些细节时会露出微笑。

仔细看看首领,你可能会发现当他用力抽烟斗时,他的眉毛会扬起,眼睛会交叉。Quick Draw的眉毛也在看似随机的时间间隔内弹跳。

1
2
3
4
5
6
7
8
#quick-draw-eyebrow {
  animation: quick-draw-eyebrow-raise 5s ease-in-out infinite;
}

@keyframes quick-draw-eyebrow-raise {
  0%, 20%, 60%, 100% { transform: translateY(0); }
  10%, 50%, 80% { transform: translateY(-10px); }
}

牢记层次结构

运动会吸引眼球,即使微妙的运动也有视觉重量。因此,我将最明显的动画保留给需要产生最大影响的元素。

抽烟斗显然对Quick Draw McGraw有很大影响,为了证明这一点,我将他的元素——包括烟斗及其羽毛——包裹在一个新的SVG组中,然后让该组摇摆。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#quick-draw-group {
  animation: quick-draw-group-wobble 6s ease-in-out infinite;
}

@keyframes quick-draw-group-wobble {
  0% { transform: rotate(0deg); }
  15% { transform: rotate(2deg); }
  30% { transform: rotate(-2deg); }
  45% { transform: rotate(1deg); }
  60% { transform: rotate(-1deg); }
  75% { transform: rotate(0.5deg); }
  100% { transform: rotate(0deg); }
}

然后,为了强调这种运动,我镜像了这些值以使他的阴影摇摆:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#quick-draw-shadow {
  animation: quick-draw-shadow-wobble 6s ease-in-out infinite;
}

@keyframes quick-draw-shadow-wobble {
  0% { transform: rotate(0deg); }
  15% { transform: rotate(-2deg); }
  30% { transform: rotate(2deg); }
  45% { transform: rotate(-1deg); }
  60% { transform: rotate(1deg); }
  75% { transform: rotate(-0.5deg); }
  100% { transform: rotate(0deg); }
}

保持克制

仅仅因为某物可以动画化并不意味着它应该被动画化。在创建环境动画时,我会研究图像并记录那些微妙运动可能增添生机的元素。我牢记这些问题:“我要讲述的故事是什么?运动在何处有帮助,何时可能变得分散注意力?”

请记住,克制不仅仅是少做;而是少做正确的事情。

分层导出SVG

在“Smashing Animations Part 4: Optimising SVGs”中,我写到了我依赖的“准备、优化和构建SVG以进行动画”的过程。当元素挤在一个SVG文件中时,导航可能是一场噩梦。找到特定的路径或组可能感觉像大海捞针。

这就是为什么我分层开发SVG,一次导出一组元素并优化——始终按照它们在最终文件中出现的顺序。这让我可以通过将每个清理过的部分粘贴到我的SVG文件中来逐步构建主SVG。

我首先导出背景元素,优化它们,添加类和ID属性,并将它们的代码粘贴到我的SVG文件中。

然后,我导出通常保持静态或作为组移动的元素,如首领和Quick Draw McGraw。

最后,导出、命名和添加细节,如Quick Draw的烟斗、眼睛和他恍惚的火花。

由于我从相同大小的画板导出每个图层,因此我不需要担心对齐或定位问题,因为它们都会自动就位。

实现环境动画

您不需要动画框架或库即可将环境动画添加到项目中。大多数时候,您只需要一个准备充分的SVG和一些深思熟虑的CSS。

但是,让我们从SVG开始。关键是将元素逻辑分组并赋予它们有意义的类或ID属性,这些属性在CSS中充当动画钩子。对于此动画,我为每个移动部分赋予了自己的标识符,如#quick-draw-tail#chief-smoke-2。这样,我可以精确地定位所需内容,而无需像浣熊翻垃圾桶一样挖掘DOM。

设置好SVG后,CSS完成大部分工作。我可以使用@keyframes实现更具表现力的运动,或使用animation-delay模拟随机性和错开时间。诀窍是保持一切微妙,并记住我不是为了吸引注意力而动画化,而是为了营造氛围而动画化。

请记住,大多数环境动画是连续循环的,因此它们应该是轻量级且对性能友好的。当然,尊重要求减少运动的用户是一种好习惯。您可以将动画包装在@media prefers-reduced-motion查询中,以便它们仅在受欢迎时运行。

1
2
3
4
5
@media (prefers-reduced-motion: no-preference) {
  #quick-draw-shadow {
    animation: quick-draw-shadow-wobble 6s ease-in-out infinite;
  }
}

这是一个易于实现的小细节,它使您的设计更具包容性。

环境动画设计原则

如果您希望动画感觉像环境,更像氛围而非动作,遵循一些原则会有所帮助。这些不是硬性规定,而是我在动画化烟雾、火花、眼球和眉毛时学到的东西。

保持动画缓慢平滑

环境动画应该感觉轻松,因此使用较长的持续时间并选择感觉有机的缓动曲线。我经常使用ease-in-out,但当您想要更轻松的感觉和自然界中可能找到的运动时,三次贝塞尔曲线也很有帮助。

无缝循环并避免突然变化

硬重置或突然跳跃会破坏情绪,因此如果动画循环,请确保它平滑循环。您可以通过匹配开始和结束关键帧,或将animation-direction设置为alternate值来实现,这样动画会向前播放,然后向后播放。

使用分层构建复杂性

单个动画可能很无聊。五个微妙的动画,每个都在单独的层上,可以感觉丰富而生动。将其视为构建声音混合——您需要节奏、音调和时间上的变化。在我的动画中,火花以不同的间隔闪烁,烟雾向上卷曲,羽毛摇摆,眼睛凸出。没有哪个占主导地位,每个运动都在场景中扮演着小角色。

避免分散注意力

环境动画的重点是它不占主导地位。它是一个背景元素,而不是号召性用语。如果某人的眼睛被扬起的眉毛吸引,那可能太过分了,因此请调低动画,直到它感觉像是只有真正看时才能捕捉到的东西。

考虑可访问性和性能

检查prefers-reduced-motion,不要假设每个人的设备都能处理复杂的动画。SVG和CSS是轻量级的,但模糊滤镜和阴影以及复杂的CSS动画仍然会给性能较低的设备带来负担。当动画纯粹是装饰性的时,考虑添加aria-hidden="true"以防止它扰乱可访问性树。

快速上手

环境动画就像一道佳肴上的调味料。它是您几乎注意不到的那一撮盐,但没有时您会想念。它不喊叫,它低语。它不引领,它徘徊。它是漂浮的烟雾、摇摆的羽毛和您眼角瞥见的火花。当它做得好时,环境动画为设计增添个性而不要求掌声。

现在,我意识到不是每个人都需要动画卡通人物。因此,在第二部分中,我将分享如何为几个最近的客户项目创建动画。下次再见,如果您正在制作插图或使用SVG,请问自己:如果这是真实的,什么会移动?然后只动画化那部分。让它缓慢而柔和。保持环境感。

您可以在CodePen上查看完整的环境动画代码。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计