从60天用手工编码的CSS重新动画僵尸中汲取的经验教训
掌握60天纯CSS僵尸动画的十个经验教训
警告:前方高能预警,大量僵尸及恶搞内容来袭!本文将分享一些实用技巧,但示例几乎都与僵尸和趣味笑话有关。请做好心理准备。
我将在讨论中链接到各个动画作品,但如果您想了解整个项目,请访问Undead Institute查看“60天动画”系列。该项目始于2020年6月1日,并在8月1日结束,与我撰写的一本关于CSS动画、幽默和僵尸的书籍出版日期相吻合——因为很明显,如果不运用你的网页技能阻止末日,僵尸就会毁灭世界。没有什么比动态HTML元素更能打击僵尸群了!
我在整个项目中给自己制定了一些规则:
- 所有CSS代码都需手动编写。(我就是一个受虐狂。)
- 所有动画都由用户触发。(我讨厌那些已经进行到一半的动画。)
- 尽可能少用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:如果你想要响应式动画,请将所有内容都放入(其中一个)视口单位中。
对单位比例采取折中方案(例如,以像素设置宽度和高度,但以视口单位设置位置和移动)会导致不可预测的结果。也不要同时使用vw
和vh
,而应使用其中一个;哪个是主要方向。混合使用vh
和vw
单位会使你的动画变得“古怪”,我相信这是专业术语。
例如,看看Superbly Zomborrific。它混合使用了像素、vw
和vh
单位。前提是超级僵尸向上飞,“摄像机”跟随。超级僵尸撞到一个壁架上并掉下来,而摄像机继续移动,但是如果你的屏幕足够高,你就不会理解这一点。
这也意味着,如果你需要某些东西从顶部进入——就像我在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来重新创建矩阵变换,但要以你想要的方式精确地进行缩放、旋转或平移是一项艰巨的任务。
或者,您可以使用平移、旋转和缩放来重新创建矩阵变换,但是如果路径很复杂,那么你能够及时地重新创建它而不让自己陷入困境的可能性很低。
最后也是最简单的选择是用一个组(
经验教训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中文网其他相关文章!

热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

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

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

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

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

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