经典卡通动画如何启发现代CSS动画技术

本文探讨了早期卡通动画的局限性如何为现代CSS动画提供灵感,通过实际代码示例展示如何使用CSS实现循环背景、元素复用和帧动画,创造出既高效又富有表现力的网页动画效果。

粉碎动画第一部分:经典卡通如何启发现代CSS

你是否曾想过早期卡通动画的局限性如何与当今的网页设计相关联?从循环背景到最小帧变化,这些复古动画技术与现代CSS有着惊人的相似之处。在这篇文章中,先驱作者和网页设计师Andy Clarke展示了他如何将这些原则应用于艾美奖获奖作曲家Mike Worth的新网站,使用CSS制作出引人入胜且有趣的动画,将他的世界栩栩如生地呈现出来。

浏览器制造商很快就在CSS中添加了运动功能。首先是简单的:hover伪类,随后是两个状态之间的过渡。然后是跨一组@keyframes改变状态的能力,以及最近出现的将关键帧与滚动位置链接的滚动驱动动画。

尽管增加了这些功能,CSS动画仍然相对基础。它们让我想起了我小时候在电视上观看的Hanna-Barbera动画系列。

解剖运动

在这一集中,Hanna-Barbera的技术在邮递员带着电报给Ranger Smith时变得明显。摄像机横向平移穿过背景艺术家Robert Gentle的风景画,创造出邮递员在移动的错觉。

当场景持续时间超过Robert Gentle风景画的单次平移时,背景会循环,灌木和树木反复出现。

这可以使用单个元素和改变其背景图像位置的动画来重新创建:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
@keyframes background-scroll {
  0% { background-position: 2750px 0; }
  100% { background-position: 0 0; }
}

div {
  overflow: hidden;
  width: 100vw;
  height: 540px;
  background-image: url("…");
  background-size: 2750px 540px;
  background-repeat: repeat-x;
  animation: background-scroll 5s linear infinite;
}

重用元素

由于每集的预算和制作时间有限,William Hanna和Joseph Barbera创建了一个简化的动画制作流程。他们每集使用少至2000个单独绘图和仅几个背景画,经常在多集中重复使用它们。

在我的Mike Worth网站删除场景中,我将这些岩石引入前景,为动画增加深度:

1
2
3
4
<figure>
  <img id="bumpy-ride" src="..." alt="" />
  <img id="apes-rock" src="..." alt="" />
</figure>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
figure {
  position: relative; 

  #bumpy-ride { ... }

  #apes-rock {
    position: absolute;
    width: 960px;
    left: calc(50% - 480px);
    bottom: 0;
  }
}

循环帧创造运动

为了满足有限的预算和制作计划,Hanna Barbera的动画师精心策划了他们的动画,并巧妙地只动画特定元素。虽然头部和面部表情使角色说话,腿部变化使它们行走,但大多数角色的身体保持相对静态。

SVG提供了惊人的性能,并且在动画元素时提供了极大的灵活性。使用CSS操作组和其他元素的能力使其成为动画的理想选择。

我复制了Hanna-Barbera如何让Ranger Smith和其他角色的嘴巴移动,首先包含一个包含管理员身体和头部的组,这些在整个过程中保持静态。然后,我添加了六个组,每个包含一个嘴巴移动的帧:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<svg>
  <!-- 静态元素 -->
  <g>...</g>

  <!-- 动画帧 -->
  <g class="frame-1">...</g>
  <g class="frame-2">...</g>
  <g class="frame-3">...</g>
  <g class="frame-4">...</g>
  <g class="frame-5">...</g>
  <g class="frame-6">...</g>
</svg>
 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
:root {
  --animation-duration: 1s;
  --frame-count: 6;
}

@keyframes ranger-talking {
  0% { visibility: visible; }
  16.67% { visibility: hidden; }
  100% { visibility: hidden; }
}

[class*="frame"] {
  visibility: hidden;
  animation: ranger-talking var(--animation-duration) infinite;
}

.frame-1 {
  animation-delay: calc(var(--animation-duration) * 0 / var(--frame-count));
}

/* ... */

.frame-6 {
  animation-delay: calc(var(--animation-duration) * 5 / var(--frame-count));
}

环境动画

微妙的环境动画有助于网站的氛围,并帮助讲故事,而不会分散其内容或功能。

对于Mike Worth的关于页面插图,我将光束照射到石板上,为原本平坦的图像增加深度。在我的SVG中,我添加了一个光的路径,并将其不透明度降低到.25:

1
2
3
4
<svg>
  <!-- ... -->
  <path class="light-shaft" fill="#F1DCA9" opacity=".25" d=""/>
</svg>

然后我定义了一个SVG滤镜来模糊我的光束边缘,并将其链接到我的路径:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<defs>
  <filter id="light-shaft" width="100%" height="100%" x="0" y="0" filterUnits="objectBoundingBox">
  <feGaussianBlur in="SourceGraphic" stdDeviation="20"/>
  </filter>
</defs>

<svg>
  <!-- ... -->
  <path class="light-shaft" filter="url(#light-shaft)"  />
</svg>

最后,我添加了一个微妙的环境动画,旋转光束并创造更自然的感觉:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@keyframes shaft-rotate {
  0% { rotate: 2deg; }
  50% { rotate: -2deg; }
  100% { rotate: 2deg; }
}

.light-shaft {
  animation: shaft-rotate 20s infinite;
  transform-origin: 100% 0;
}

交互动画

就像:hover伪类在有人与元素交互时提供有价值的视觉反馈一样,CSS动画可以在人与设计之间建立更深的联系。

我在Mike Worth的评论页面插图中包含了一个彩蛋交互。大红按钮打开和关闭台灯,这让Mike的猩猩吉祥物非常懊恼,他正试图研究他的地图。为了实现这一点,我向SVG插图应用了一个data-属性:

1
2
3
<svg  data-lights="lights-on">
  <!-- ... -->
</svg>

并添加了一个红色按钮供任何好奇的访问者按下:

1
2
3
4
5
<a href="javascript:void(0);" id="light-switch" title="Lights on/off">
  <path fill="#0a0908" d="..."/>
  <ellipse fill="#9c1621"  />
  <path fill="#fff" d="..."/>
</a>

当有人按下那个红色按钮时,灯会熄灭,这是通过将SVG的data-属性值从lights-on更改为lights-off来实现的。

插图中的几个元素在台灯打开时会亮起。为了实现这一点,我向这些特定项目应用了一个类值:

1
<path class="lamp-glow" />

并使用data-attribute值在有人按下灯按钮时切换发光:

1
2
3
4
5
6
7
8
9
[data-lights="lights-on"] .lamp-glow {
  opacity: 1;
  transition: opacity .25s linear;
}

[data-lights="lights-off"] .lamp-glow {
  opacity: .25;
  transition: opacity .25s linear;
}

当有人打开灯时,它会在看似随机的时间间隔闪烁。我首先向闪烁元素应用了一个类值:

1
<path class="lamp-flicker" />

然后,在灯关闭时隐藏它们:

1
2
3
[data-lights="lights-off"] .lamp-flicker {
  visibility: hidden;
}

最后,我创建了一个关键帧动画,在看似随机的时间间隔闪烁灯光的不透明度:

1
2
3
4
5
6
7
8
@keyframes lamp-flicker {
  0%, 19.9%, 22%, 62.9%, 64%, 64.9%, 70%, 100% { opacity: 1; }
  20%, 21.9%, 63%, 63.9%, 65%, 69.9% { opacity: .5; }
}

[data-lights="lights-on"] .lamp-flicker {
  animation: lamp-flicker 3s 3s linear infinite;
}

动画还可以吸引人们更深入地探索设计,所以我让桌子上的水晶头骨振动,暗示有更多可以发现的东西:

1
2
3
<a href="/easter-egg">
  <g id="crystal-skull">...</g>
</a>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@keyframes crystal-skull-vibrate {
  0% { translate: 0 0; }
  20% { translate: -2px 2px; }
  40% { translate: -2px -2px; }
  60% { translate: 2px 2px; }
  80% { translate: 2px -2px; }
  100% { translate: 0 0; }
}

#crystal-skull:hover {
  animation: crystal-skull-vibrate .5s ease 0s infinite normal forwards;
}

动画讲述故事

经过仔细考虑,动画可以反映品牌的标识并帮助讲述其故事。

Mike Worth的品牌是高能量的——就像他的个性一样——他关于自己作为视频游戏作曲家的工作的故事引人入胜且有趣。Mike希望与他的网站的每一次互动都能将他的个性带到屏幕上。

如果有人在他们旅程中迷路,他们会最终到达Mike的404页面,在那里他的英雄有一种下沉的感觉。当Mike的猩猩冒险家越来越深地陷入流沙时,动画气泡上升:

1
2
3
4
5
6
<g>
  <circle class="four-oh-dear-bubble" ... />
  <circle class="four-oh-dear-bubble" ... />
  <circle class="four-oh-dear-bubble" ... />
  <!-- ... -->
</g>
 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
27
28
29
30
31
32
33
34
35
36
37
38
@keyframes four-oh-dear-bubbles {
  0% { 
    animation-timing-function: ease-in; 
    opacity: 1; 
    transform: translateY(45px);
  }
  24% { 
    opacity: 1; 
  }
  40% { 
    animation-timing-function: ease-in; 
    translate: 0 24px;
  }
  65% { 
    animation-timing-function: ease-in;
    translate: 0 12px;
  }
  82% { 
    animation-timing-function: ease-in;
    translate: 0 6px;
  }
  93% { 
    animation-timing-function: ease-in;
    translate: 0 4px;
  }
  25%, 55%, 75%, 87% { 
    animation-timing-function: ease-out;
    translate: 0 0;
  }
  100% { 
    animation-timing-function: ease-out;
    opacity: 1; 
    translate: 0 0;
  }
}

.four-oh-dear-bubble {
  animation: four-oh-dear-bubbles 2s ease 0s infinite alternate forwards; }

赋予生命

就像Hanna-Barbera的动画师将技术限制转化为他们的标志性风格一样,CSS动画使网络专业人士能够制作出有个性的体验。通过分层元素、循环帧和应用微妙的运动,您可以为设计注入个性,同时改善某人的体验。

在我为Mike Worth网站的设计中,动画不仅仅是为了装饰;它讲述了一个关于他和他工作的引人入胜的故事。每一个动作都反映了他的品牌标识,并使他的网站成为他创意世界的延伸。

下次您使用CSS动画时,请超越运动思考。也要考虑情感、身份和情绪。毕竟,一个经过深思熟虑的动画可以做的不仅仅是吸引某人的眼球。它可以捕捉他们的想象力。

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