freeCodeCamp 课程拆解:用 animation-duration 让多个元素以不同速率闪烁(Animate Multiple Elements at Variable Rates)

freeCodeCamp 课程拆解:用 animation-duration 让多个元素以不同速率闪烁(Animate Multiple Elements at Variable Rates) freeCodeCamp 课程拆解用 animation-duration 让多个元素以不同速率闪烁Animate Multiple Elements at Variable Rates【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp本篇基于 freeCodeCamp 开源课程库中的挑战文件 Animate Multiple Elements at Variable Rates完整讲解Applied Visual Design课程中这道 CSS 动画练习的问题设定、参考答案、自动测试原理以及它与前后章节通过keyframes变速、通过animation-timing-function变速构成的技术脉络。读完后你将掌握用单一keyframes规则配合不同animation-duration让多个元素以不同速率独立循环动画的完整方案并能看懂 freeCodeCamp 挑战文件的组织方式与测试运行机制。挑战在课程中的位置与文件组织这道挑战属于 Responsive Web Design 认证下的applied-visual-design课程块。课程块的挑战顺序由结构文件 applied-visual-design.json 声明其中本挑战id 为587d78a8367417b2b2512ae6位于两个关键练习之间前一课 Animate Elements at Variable Rates通过为每个元素单独编写keyframes规则修改关键帧百分比位置来改变各自的动画节奏本课 Animate Multiple Elements at Variable Rates改用同一个keyframes规则 不同的animation-duration达到同样的变速效果后一课 Change Animation Timing with Keywords在animation-duration相同的前提下用animation-timing-functionlinear/ease-out等改变元素在时长内的加减速曲线。三道课环环相扣共同覆盖了 CSS 动画速率控制的三个正交维度时长duration、关键帧形态keyframes、缓动曲线timing function。从源码结构看每个挑战是一个 Markdown 文件文件名为挑战的 Mongo ObjectId存放于curriculum/challenges/english/blocks/块名/目录下。这些文件会被课程构建工具解析为结构化挑战数据并由 challenge-schema.js 中的 Joi schema 校验。其中与本挑战 frontmatter 直接相关的字段约束包括dashedName第 182 行Joi.string().regex(slugRE)正则要求小写字母、数字、连字符对应本文件的dashedName: animate-multiple-elements-at-variable-rateschallengeType第 180 行取值 033 的整数本挑战为0经典 HTML/CSS 挑战tests第 375-389 行要求每个挑战必须携带至少一条测试公开挑战需含text与testString这正是文末三段断言的来源。Markdown 文件内部以# --description--、# --instructions--、# --hints--、# --seed--含## --seed-contents--初始代码、# --solutions--参考答案等标记分隔内容--seed--与--solutions--各包含一段完整的可运行 HTML。题目设定三颗同速闪烁的星星原始挑战的初始代码seed如下它模拟了一个夜空场景#back是一个固定定位、铺满视口的渐变背景三颗 30×30px 的圆形白色星星以相同的 1s 周期无限循环闪烁style .stars { background-color: white; height: 30px; width: 30px; border-radius: 50%; animation-iteration-count: infinite; } .star-1 { margin-top: 15%; margin-left: 60%; animation-duration: 1s; animation-name: twinkle; } .star-2 { margin-top: 25%; margin-left: 25%; animation-duration: 1s; animation-name: twinkle; } .star-3 { margin-top: 10%; margin-left: 50%; animation-duration: 1s; animation-name: twinkle; } keyframes twinkle { 20% { transform: scale(0.5); opacity: 0.5; } } #back { position: fixed; padding: 0; margin: 0; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(black, #000099, #66c2ff, #ffcccc, #ffeee6); } /style div idback/div div classstar-1 stars/div div classstar-2 stars/div div classstar-3 stars/div这段代码里有几个值得注意的设计点公共样式抽到.stars上尺寸、圆角、animation-iteration-count: infinite无限循环写在共享类上三个星星元素在 HTML 中同时携带stars与各自的编号类如classstar-1 stars利用 CSS 多类叠加来继承 差异化单一keyframes twinkle所有星星引用同一条关键帧规则。规则内只声明了20%关键帧缩小到 0.5 倍、透明度降到 0.5其余关键帧0% 和 100%由浏览器隐式取元素的当前样式因此动画呈现为每周期前 20% 快速变暗变小、随后恢复的闪烁效果三颗星星位置不同但节奏完全相同margin-top/margin-left使用百分比控制布局位置而animation-duration三者都是1s——这正是题目要改变的地方三颗星齐步走的闪烁看起来机械真实夜空中的星星应有错落感。挑战描述--description--指出在前一课中你已经通过修改两个相似动画元素的keyframes规则改变了它们的动画速率而本课题目要求换一种等价但更简洁的手段——直接操纵多个元素的animation-duration。指令--instructions--非常明确将类名分别为star-1、star-2、star-3的三个元素的animation-duration分别设置为1s、0.9s、1.1s。参考答案只改两个时长值完整参考答案--solutions--区块与 seed 代码几乎一致唯一差异是两个时长声明style .stars { background-color: white; height: 30px; width: 30px; border-radius: 50%; animation-iteration-count: infinite; } .star-1 { margin-top: 15%; margin-left: 60%; animation-duration: 1s; animation-name: twinkle; } .star-2 { margin-top: 25%; margin-left: 25%; animation-duration: 0.9s; /* 由 1s 改为 0.9s */ animation-name: twinkle; } .star-3 { margin-top: 10%; margin-left: 50%; animation-duration: 1.1s; /* 由 1s 改为 1.1s */ animation-name: twinkle; } keyframes twinkle { 20% { transform: scale(0.5); opacity: 0.5; } } #back { position: fixed; padding: 0; margin: 0; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(black, #000099, #66c2ff, #ffcccc, #ffeee6); } /style div idback/div div classstar-1 stars/div div classstar-2 stars/div div classstar-3 stars/div修改后三颗星星共享同一份关键帧形态但各自一个完整闪烁周期分别为 1s、0.9s、1.1s。由于周期不同三者的闪烁相位会随时间不断错开形成参差不齐的自然闪烁感——这正是variable rates可变速率的视觉目标。这里体现了 CSS 动画的时长与关键帧解耦原则keyframes定义的是一个周期内动画如何随时间百分比变化而animation-duration决定一个周期有多长。改变周期长度不需要改写关键帧只需调整animation-duration即可这也是本课相对前一课需要为每个元素单独复制一份keyframes更优的原因——代码更少、维护更容易。测试机制getComputedStyle 读取运行时样式挑战文件--hints--区块中内置了三条自动测试见 挑战文件它们分别对三颗星星做计算样式断言const starOne document.querySelector(.star-1); const starOneStyle window.getComputedStyle(starOne); assert.equal(starOneStyle?.animationDuration, 1s);const starTwo document.querySelector(.star-2); const starTwoStyle window.getComputedStyle(starTwo); assert.equal(starTwoStyle?.animationDuration , 0.9s);const starThree document.querySelector(.star-3); const starThreeStyle window.getComputedStyle(starThree); assert.equal(starThreeStyle?.animationDuration, 1.1s);三段测试的共同模式是用document.querySelector按类名定位元素用window.getComputedStyle读取浏览器实际计算后的样式CSSStyleDeclaration对象的animationDuration属性而不是读取元素的style内联属性或源码文本用assert.equal精确比较字符串形式的时长值。用getComputedStyle而非检查源码字符串意味着只要页面中任何层级的 CSS类选择器、内联样式等最终让元素的生效时长等于目标值测试就能通过。这也解释了为什么答案中star-1的1s原值不动也能通过第一条断言。从客户端源码看这些测试如何到达执行环境经典挑战页面 classic/show.tsx 中的 GraphQL 查询会拉取挑战的tests { text testString }字段第 586-589 行即把每条测试的描述文案与可执行断言代码一起下发到前端用户的代码与断言随后在隔离的沙箱环境中运行全部断言通过挑战才算完成。这种源码级 schema 校验 运行时断言的双层验证正是 freeCodeCamp 课程体系能自动批改 HTML/CSS 挑战的基础。与前后两课的方法对比把三道课的解法放在一起可以更清晰地看到 CSS 动画变速的三个独立旋钮手段对应课程控制维度代码代价为每个元素复制并修改keyframes改变关键帧百分比Animate Elements at Variable Rates一个周期内变化的时刻与形态需为每个元素维护一份独立的关键帧规则共享keyframes 不同animation-duration本课本挑战一个周期的总时长只改一个属性值关键帧只写一份相同时长 不同animation-timing-functionChange Animation Timing with Keywords周期内的加减速曲线linear、ease-out等每元素一行属性以本课场景为例如果三颗星都想周期相同但节奏不同animation-timing-function可以改变闪烁的起止快慢而本课的animation-duration差异则是让一个闪烁周期本身有多长不同。二者可以叠加使用先共享关键帧再为每个元素设置不同的duration、delay、iteration-count就能用最少代码构造出复杂的错峰动画。小结本挑战的核心知识点可以浓缩为一句话多个元素引用同一份keyframes时通过为每个元素设置不同的animation-duration如 1s / 0.9s / 1.1s即可让它们的循环动画以不同速率独立运转无需复制关键帧规则。结合 课程结构文件、挑战 schema 与 挑战渲染入口可以看出 freeCodeCamp 是如何把一段可编辑 seed 代码 参考答案 getComputedStyle 断言组织成一道可自动批改、可独立复现的课程挑战的这套结构本身就是学习 CSS 动画课程化组织方式的一个范例。【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考