目录
经验教训1:80天太长了。
经验教训1A:60天仍然太长了。
经验教训2:交互式动画很难制作,响应式设计更难。
经验教训3:如果你想要响应式动画,请将所有内容都放入(其中一个)视口单位中。
经验教训3A:对SVG元素内部的移动使用像素单位。
经验教训4:SVG在运行时缩放效果很差。
经验教训5:坐标轴并非普遍真理。
经验教训6. 将复杂的动画分解成同心元素以方便调整。
经验教训7:SVG和CSS变换是相同的。
经验教训8:在变换SVG的一部分时,使用transform-origin保持理智
经验教训9:精灵动画可以是响应式的
经验教训9A:在创建响应式精灵动画时,使用视口单位设置图像的背景大小
经验教训10:邀请人们参与项目。
首页 web前端 css教程 从60天用手工编码的CSS重新动画僵尸中汲取的经验教训

从60天用手工编码的CSS重新动画僵尸中汲取的经验教训

Apr 02, 2025 pm 06:20 PM

掌握60天纯CSS僵尸动画的十个经验教训

Lessons Learned from Sixty Days of Re-Animating Zombies with Hand-Coded CSS

警告:前方高能预警,大量僵尸及恶搞内容来袭!本文将分享一些实用技巧,但示例几乎都与僵尸和趣味笑话有关。请做好心理准备。

我将在讨论中链接到各个动画作品,但如果您想了解整个项目,请访问Undead Institute查看“60天动画”系列。该项目始于2020年6月1日,并在8月1日结束,与我撰写的一本关于CSS动画、幽默和僵尸的书籍出版日期相吻合——因为很明显,如果不运用你的网页技能阻止末日,僵尸就会毁灭世界。没有什么比动态HTML元素更能打击僵尸群了!

我在整个项目中给自己制定了一些规则:

  1. 所有CSS代码都需手动编写。(我就是一个受虐狂。)
  2. 所有动画都由用户触发。(我讨厌那些已经进行到一半的动画。)
  3. 尽可能少用JavaScript,并且绝不用于动画。(我只在最终动画中使用了一次JavaScript,那是为了启动音频。我并不反对JavaScript,只是这里不需要它。)

经验教训1:80天太长了。

标题不是说“60天”吗?是的,但我最初的目标是80天,当第一天到来时,我只有不到20个动画准备就绪,每个动画的平均制作时间为3天,我惊慌失措,于是改为60天。这让我多了20天准备时间,也减少了20个动画作品。

经验教训1A:60天仍然太长了。

在有限的时间、创意和更有限的艺术技能下,要完成如此多的动画,这确实是一项挑战。虽然我曾想过缩短到30天,但我庆幸我没有这样做。60天让我突破自我,更深入地了解CSS动画——以及CSS本身——的工作原理。我也为后期完成的许多作品感到自豪,因为我的技能有所提高,我不得不更具创新性,并更深入地思考如何让作品更有趣。一旦你用尽了所有简单的选项,真正的工作和最佳成果才会开始。(是的,最终是62天,因为我从6月1日开始,想在8月1日完成最终动画。从6月3日开始感觉很别扭。)

所以,真正的经验教训1:挑战自我

经验教训2:交互式动画很难制作,响应式设计更难。

如果你想让某个元素飞过屏幕并与另一个元素连接,或者似乎启动另一个元素的移动,你必须使用所有标准的、不灵活的单位或所有灵活的单位。

三个变量决定了动画元素在任何动画过程中的时间和位置:持续时间、速度和距离。动画的持续时间在animation属性中设置,不能根据屏幕大小更改。动画时间函数决定速度;屏幕大小也不能改变这一点。因此,如果距离随屏幕大小而变化,则除了特定屏幕宽度和高度外,时间安排都会出现偏差。

看看Tank!在宽屏和窄屏上运行动画。虽然我将时间安排得很接近,但如果你进行比较,你会发现当最后一个僵尸倒下时,坦克相对于僵尸的位置不同。

为了避免这些时间问题,您可以使用固定单位和一个较大的数字,例如2000或5000像素或更大,以便动画可以覆盖除最大显示器外的所有显示器的宽度(或高度)。

经验教训3:如果你想要响应式动画,请将所有内容都放入(其中一个)视口单位中。

对单位比例采取折中方案(例如,以像素设置宽度和高度,但以视口单位设置位置和移动)会导致不可预测的结果。也不要同时使用vwvh,而应使用其中一个;哪个是主要方向。混合使用vhvw单位会使你的动画变得“古怪”,我相信这是专业术语。

例如,看看Superbly Zomborrific。它混合使用了像素、vwvh单位。前提是超级僵尸向上飞,“摄像机”跟随。超级僵尸撞到一个壁架上并掉下来,而摄像机继续移动,但是如果你的屏幕足够高,你就不会理解这一点。

这也意味着,如果你需要某些东西从顶部进入——就像我在Nobody Here But Us Humans中所做的那样——你必须将vw高度设置得足够高,以确保在大多数纵横比下忍者僵尸不可见。

经验教训3A:对SVG元素内部的移动使用像素单位。

也就是说,转换SVG元素内的元素不应使用视口单位。SVG标签是它们自己的比例宇宙。SVG“像素”将在SVG元素内保持与其所有其他SVG元素子元素的比例,而视口单位则不会。因此,在SVG元素内使用像素单位进行转换,但在其他地方使用视口单位。

经验教训4:SVG在运行时缩放效果很差。

对于动画,例如Oops…,我将僵尸的SVG图像放大到原来的五倍,但这会使边缘模糊。[对“可缩放”矢量图形挥舞拳头。]

/* 导致边缘模糊的原始代码 */
.zombie {
  transform: scale(1);
  width: 15vw;
}

.toggle-checkbox:checked ~ .zombie {
  animation: 5s ease-in-out 0s reverseshrinkydink forwards;
}

@keyframes reverseshrinkydink {
  0% {
    transform: scale(1);
  }
  100% {
    transform: scale(5);
  }
}
登录后复制

我学会了将它们的尺寸设置为动画结束时将生效的最终尺寸,然后使用缩放变换将它们缩小到动画开始时的尺寸。

/* 修改后的代码 */
.zombie {
  transform: scale(0.2);
  width: 75vw;
}

.toggle-checkbox:checked ~ .zombie {
  animation: 5s ease-in-out 0s reverseshrinkydink forwards;
}

@keyframes reverseshrinkydink {
  0% {
    transform: scale(0.2);
  }
  100% {
    transform: scale(1);
  }
}
登录后复制

简而言之,修改后的代码从图像的缩小版本移动到完整的宽度和高度。浏览器始终以1进行渲染,从而使边缘在1的比例下清晰锐利。因此,我没有从1缩放至5,而是从0.2缩放至1。

经验教训5:坐标轴并非普遍真理。

元素的坐标轴与其自身保持同步,而不是页面。在translateX之前进行90度旋转会将translateX的方向从水平变为垂直。在Nobody Here But Us Humans… 2中,我使用180度旋转翻转了僵尸。但是正Y值会将忍者移动到顶部,负值会将它们移动到底部(与正常情况相反)。注意旋转如何影响后续的变换。

经验教训6. 将复杂的动画分解成同心元素以方便调整。

在创建多方向移动的复杂动画时,添加包装div或父元素,并分别为每个元素设置动画,可以减少变换冲突,并防止你崩溃。

例如,在Space Cadet中,我有三个不同的变换。第一个是宇航员僵尸的上下运动。第二个是横向移动。第三个是旋转。我没有尝试在一个变换中完成所有操作,而是添加了两个包装元素,并在每个元素上进行了一个动画(我还保住了我的头发……至少一部分)。这有助于避免上一课中讨论的坐标轴问题,因为我在最内层的元素上进行了旋转,从而保留了其父元素和祖父母元素的坐标轴。

经验教训7:SVG和CSS变换是相同的。

某些路径、组和其他SVG元素在其上已经定义了变换。这可能是由优化算法造成的,或者可能只是插图软件生成代码的方式。如果SVG中的路径、组或任何其他元素已经具有SVG变换,则删除该变换将重置元素,通常与其余绘图相比,其位置或大小会发生奇异变化。

由于SVG和CSS变换是相同的,因此你所做的任何CSS变换都会替换SVG变换,这意味着你的CSS变换将从该奇异位置或大小开始,而不是SVG中设置的位置或大小。

您可以将变换从SVG元素复制到CSS,并将其设置为CSS中的起始位置(首先将其更新为CSS语法)。然后,您可以在CSS动画中对其进行修改。

例如,在我的《上班族》致敬作品Uhhh, Yeah…中,不死伦伯格的右上臂(#arm2元素)在原始SVG代码中有一个变换。

<path d="M0 171h9v9H0z" fill="#91c1a3" fill-rule="nonzero" transform="translate(0 -343) scale(4 3.55)"></path>
登录后复制

将该变换移动到CSS中,如下所示:

<path d="M0 171h9v9H0z" fill="#91c1a3" fill-rule="nonzero"></path>
登录后复制
#arm2 {
  transform: translate(0, -343px) scale(4, 3.55);
}
登录后复制

……然后,我可以创建一个不会意外重置位置和比例的动画:

.toggle-checkbox:checked ~ .z #arm2 { 
  animation: 6s ease-in-out 0.15s arm2move forwards;
}

@keyframes arm2move {
  0%, 100% {
    transform: translate(0, -343px) scale(4, 3.55);
  }
  40%, 60% {
    transform: translate(0, -403px) scale(4, 3.55);
  }
  50% {
    transform: translate(0, -408px) scale(4, 3.55);
  }
} 
登录后复制

当生成SVG代码的工具尝试将变换“简化”为矩阵时,此过程会更加困难。虽然您可以通过将其复制到CSS来重新创建矩阵变换,但要以你想要的方式精确地进行缩放、旋转或平移是一项艰巨的任务。

或者,您可以使用平移、旋转和缩放来重新创建矩阵变换,但是如果路径很复杂,那么你能够及时地重新创建它而不让自己陷入困境的可能性很低。

最后也是最简单的选择是用一个组()标签包装元素。为其添加一个类或ID以便于CSS访问,并转换组本身,从而分离变换,就像上一课中讨论的那样。

经验教训8:在变换SVG的一部分时,使用transform-origin保持理智

CSS transform-origin属性移动变换发生的点。如果你试图旋转手臂——就像我在Clubbin’ It中所做的那样——如果你从肩膀中心旋转手臂,你的动画看起来会更自然,但是该路径的自然变换原点在左上角。使用transform-origin来修复此问题,以获得更流畅、更自然的感觉……你知道那种非常自然的像素艺术外观……

在缩放时,变换原点也很有用,就像我在Mustachioed Oops中所做的那样,或者在旋转嘴部运动时,例如Super Tasty中的恐龙的下巴。如果你不更改原点,变换将使用SVG元素左上角的原点。

经验教训9:精灵动画可以是响应式的

我最终为这个项目做了很多精灵动画(即,你使用多个增量帧并在它们之间快速切换,以使角色看起来在移动)。我在一个宽文件中创建了图像,将它们添加为背景图像到单个帧大小的元素,使用background-size将背景图像设置为图像的宽度,并隐藏溢出。然后,我使用background-position和动画时间函数step()来遍历图像;例如:Post-Apocalyptic Celebrations。

在项目之前,我一直使用不灵活的图像。我会稍微缩小一下比例,这样至少会有一些响应式效果,但我认为你无法使其成为完全灵活的宽度。但是,如果你使用SVG作为背景图像,那么你可以使用视口单位来随着屏幕大小的变化来缩放元素。唯一的问题是背景位置。但是,如果你为此使用视口单位,它将保持同步。在Finally, Alone with my Sandwich…中查看这一点。

经验教训9A:在创建响应式精灵动画时,使用视口单位设置图像的背景大小

正如我在这个项目中学到的那样,使用单一类型的单位几乎总是可行的。最初,我使用百分比来设置精灵的背景大小。计算很简单(100% *(步数 1)),并且在大多数情况下都能正常工作。但是,在较长的动画中,精确的帧跟踪可能会出错,并且可能会显示错误的精灵帧的部分内容。随着向精灵添加更多帧,问题会越来越严重。

我不确定这究竟是为什么导致问题的原因,但我认为这是由于在精灵表长度上累积的舍入误差造成的(位移量随着帧数的增加而增加)。

在我的最终动画It Ain’t Over Till the Zombie Sings中,我让一只恐龙张开嘴,露出一个正在唱歌的僵尸维京人(同时背景中还有激光发射,当然还有跳舞、手风琴演奏和从大炮中发射的僵尸)。是的,我知道如何举办派对……一个极客派对。

恐龙和维京人是为该项目制作的最长的精灵动画之一。但是,当我使用百分比来设置背景大小时,Safari中某些大小的跟踪会出错。在动画结束时,来自不同帧的恐龙鼻子的一部分似乎会出现在右侧,而左侧则会缺少类似的鼻子部分。

这非常难以诊断,因为它在Chrome中似乎工作正常,而且我认为我在Safari中修复了它,只是查看稍微不同的屏幕大小,就会再次看到帧偏离。但是,如果我使用一致的单位——即vw用于background-size、帧宽度和background-position——一切都会正常工作。同样,这归结于使用一致的单位!

经验教训10:邀请人们参与项目。

虽然我在这个过程中学到了很多东西,但我大部分时间都在撞墙(经常是直到墙破了或者我的头破了……我分不清了)。虽然这是一种方法,但即使你很固执,你最终还是会头痛。邀请其他人参与你的项目,无论是寻求建议、指出你错过的明显盲点、提供反馈、帮助完成项目,还是在你感到范围过大时鼓励你继续坚持下去。

因此,让我将此经验教训付诸实践。你的想法是什么?你将如何用CSS动画阻止僵尸群?你将承担什么范围过大的项目来挑战自己?

以上是从60天用手工编码的CSS重新动画僵尸中汲取的经验教训的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

带有粘性定位的堆叠卡和一点点的杂物 带有粘性定位的堆叠卡和一点点的杂物 Apr 03, 2025 am 10:30 AM

前几天,我发现了科里·金尼文(Corey Ginnivan)网站上的这一点,当您滚动时,彼此之间的卡片堆放集。

Google字体可变字体 Google字体可变字体 Apr 09, 2025 am 10:42 AM

我看到Google字体推出了新设计(Tweet)。与上一次大型重新设计相比,这感觉更加迭代。我几乎无法分辨出区别

如何使用HTML,CSS和JavaScript创建动画倒计时计时器 如何使用HTML,CSS和JavaScript创建动画倒计时计时器 Apr 11, 2025 am 11:29 AM

您是否曾经在项目上需要一个倒计时计时器?对于这样的东西,可以自然访问插件,但实际上更多

为什么Flex布局中的紫色斜线区域会被误认为是'溢出空间”? 为什么Flex布局中的紫色斜线区域会被误认为是'溢出空间”? Apr 05, 2025 pm 05:51 PM

关于Flex布局中紫色斜线区域的疑问在使用Flex布局时,你可能会遇到一些令人困惑的现象,比如在开发者工具(d...

如何通过CSS选择第一个类名为item的子元素? 如何通过CSS选择第一个类名为item的子元素? Apr 05, 2025 pm 11:24 PM

在元素个数不固定的情况下如何通过CSS选择第一个指定类名的子元素在处理HTML结构时,常常会遇到元素个数不�...

HTML数据属性指南 HTML数据属性指南 Apr 11, 2025 am 11:50 AM

您想了解的有关HTML,CSS和JavaScript中数据属性的所有信息。

使Sass更快的概念证明 使Sass更快的概念证明 Apr 16, 2025 am 10:38 AM

在一个新项目开始时,Sass汇编发生在眼睛的眨眼中。感觉很棒,尤其是当它与browsersync配对时,它重新加载

在前端开发中,如何使用CSS和JavaScript实现类似Windows 10设置界面的探照灯效果? 在前端开发中,如何使用CSS和JavaScript实现类似Windows 10设置界面的探照灯效果? Apr 05, 2025 pm 10:21 PM

在前端开发中如何实现类似Windows...

See all articles