现代 JavaScript 教程实战:用 cubic-bezier 让 CSS 尺寸动画“跳脱“边界(飞机缩放回弹动画) 文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载导读本文基于《现代 JavaScript 教程The Modern JavaScript Tutorial》中文仓库中的动画章节实战任务讲解如何利用 CSStransition与三次贝塞尔曲线cubic-bezier让过渡动画产生超出目标值再回弹的过冲overshoot效果。通过本任务你将掌握transition-timing-function中贝塞尔曲线控制点y值超出0..1范围时的行为规律并能在不编写任何 JavaScript 动画逻辑的情况下仅凭一条曲线完成放大 → 超出 → 回落的三阶段动效。任务背景从放大十倍到跳脱边界本任务位于仓库 7-animation/2-css-animations/2-animate-logo-bezier-css/task.md它是前一任务 让飞机动起来CSS 的进阶版。先回顾基础任务的要求点击后飞机图片从40x24px变为400x240px放大十倍动画持续三秒动画结束后输出Done!动画过程中再次点击不应打断动画。基础任务的解决方案见 1-animate-logo-css/solution.md非常简洁核心是给元素加上transition: all 3s;再通过 JS 添加.growing类来改变width与height/* 原始类 */ #flyjet { transition: all 3s; } /* JS 添加的 .growing */ #flyjet.growing { width: 400px; height: 240px; }flyjet.onclick function() { flyjet.classList.add(growing); };而进阶任务则提出了一个新要求让飞机超过最终的400x240px先跳脱出去然后再回到最终大小。也就是说动画的完成度y需要短暂地突破1超过目标值再回落收敛。这正是本任务的难点所在也是本文要解决的核心问题。核心原理贝塞尔曲线如何让动画过头要理解本任务的解法必须先掌握 CSS 过渡中贝塞尔曲线的语义。教程主文章 CSS 动画 的贝塞尔曲线一节对此有系统讲解。CSS 的时间函数可以用一条三次贝塞尔曲线描述通过设置四个控制点其中第一个控制点固定为(0, 0)最后一个控制点固定为(1, 1)中间两个控制点的x必须位于0..1之间而y可以是任意值。CSS 中的写法为cubic-bezier(x2, y2, x3, y3)——只需要给出第二个和第三个控制点x轴表示时间0是开始时刻1是transition-duration结束的时刻y轴表示动画进程的完成度0是属性的起始值1是属性的最终值。关键洞察在于当中间控制点的y超出0..1范围时曲线就会越界动画对应的属性值也会短暂地小于起始值或大于最终值。教程主文章中用一个列车位移的示例train-over展示了这一点当left本应在100px到400px之间变化时使用曲线cubic-bezier(.5, -1, .5, 2)会让列车先反向运动left 100px再冲过400px最后回到400px。原因正是第二个控制点的y -1 0第三个控制点的y 2 1y 0意味着属性值小于初始值y 1则意味着属性值大于最终值。本任务的解法y 1 让飞机跳出来进阶任务的官方解决方案见 2-animate-logo-bezier-css/solution.md思路非常直接我们需要为此选择合适的贝塞尔曲线。它应该在某个地方拥有y 1来使得飞机『跳出来』。举例来说我们可以使两个控制点的y都大于1cubic-bezier(0.25, 1.5, 0.75, 1.5)。该曲线的形态如下图所示两个中间控制点的y值都被抬高到1.5使曲线在时间轴中段冲高突破y 1的完成水平线随后再回落对照教程主文章中的列车示例图可以更直观地看到同类曲线的形态——中间控制点y大于1时曲线会向上拱起动画完成度短暂超过最终值用数学视角解读y可以理解为当前属性值在起始值与最终值之间的线性插值系数。当y 1.5时当前值 起始值 1.5 × (最终值 − 起始值)即超出最终值 50%随着动画推进y回落到1属性值也就收敛到最终值。本任务中飞机尺寸从40x24px放大到400x240px在过冲阶段会短暂超过400x240px随后回落形成放大 → 超出 → 回弹的视觉节奏。完整可运行实现仓库中该任务的可运行示例位于 2-animate-logo-bezier-css/solution.view/index.html核心实现只需在前一任务基础上修改一行transition声明!DOCTYPE html html head meta charsetutf-8 style img { display: block; cursor: pointer; } /style style #flyjet { width: 40px; height: 24px; transition: all 3s cubic-bezier(0.25, 1.5, 0.75, 1.5); } #flyjet.growing { width: 400px; height: 240px; } /style /head body img idflyjet srchttps://en.js.cx/clipart/flyjet.jpg script flyjet.onclick function() { flyjet.classList.add(growing); }; /script /body /html逐行拆解这段代码#flyjet定义了初始尺寸40x24px并声明过渡属性transition: all 3s cubic-bezier(0.25, 1.5, 0.75, 1.5)。其中all表示对所有可动画属性生效3s是动画时长最后是本次任务的核心——过冲曲线#flyjet.growing仅在元素同时拥有growing类时生效将尺寸改写为400x240px。浏览器检测到width/height变化后会按照贝塞尔曲线生成 3 秒过渡动画JavaScript 部分只需一行flyjet.classList.add(growing)点击事件触发后动画完全交由 CSS 引擎驱动无需任何逐帧逻辑。动画期间飞机处于超出状态时由于中间控制点y 1.5曲线的峰值完成度可达约1.5对应width短暂超过400px最大约40 1.5 × 360 580px附近的峰值具体峰值取决于曲线形状随后回落并停在400px。这就是任务要求中超过原有大小跳脱出来然后再回到之前的大小的实现机理。参数调优控制过冲的幅度与手感贝塞尔曲线的两个中间控制点(x2, y2)与(x3, y3)共同决定了过冲的形状本任务采用的cubic-bezier(0.25, 1.5, 0.75, 1.5)只是众多可行取值之一。调整思路如下y值决定过冲幅度y2与y3越大峰值完成度越高飞机超出最终尺寸越远。若取y 1.2过冲较柔和取y 2甚至更高飞机将明显飞过头再弹回。教程主文章也提示把y设为-99或99这类极端值时偏移会非常夸张y 0产生反向效果若让中间控制点的y为负值动画会先向相反方向小于起始值运动再折返与列车示例cubic-bezier(.5, -1, .5, 2)的行为一致可用于制作后坐-前冲类动效x值影响过冲出现的时机x必须保持在0..1之间x2偏小意味着曲线在前段快速爬升过冲峰值出现得更早transition: all 3s的语义all同时为width与height应用同一条曲线。由于两个属性按相同比例放大40→400、24→240视觉上飞机保持等比缩放、整体跳出再回落。实际调试时可以使用教程中提到的cubic-bezier.com一类可视化工具实时拖拽控制点观察曲线形态与预览效果再回填到transition声明中。实战注意点transitionend 的双触发与任务延展本任务在基础任务之上只修改了时间函数但基础任务中的一个坑同样适用于这里transitionend会对每个发生过渡的属性各触发一次。基础任务的官方解决方案中动画同时改变了width与height因此transitionend会触发两次若在事件回调中直接输出Done!而不做防重入检查提示会出现两次。基础任务的参考实现见 1-animate-logo-css/solution.view/index.html通过一个ended布尔标志做了拦截flyjet.addEventListener(transitionend, function() { if (!ended) { ended true; alert(Done!); } });此外transitionend事件对象还带有两个实用属性详见 CSS 动画 的transitionend 事件一节event.propertyName当前完成动画的属性名多属性同时动画时可据此区分是哪条属性结束event.elapsedTime动画完成耗时秒不包含transition-delay。进阶任务在此基础上延展时可以进一步试验给.growing类添加transition-delay让过冲分阶段发生或结合keyframes与animation属性实现更复杂的多段回弹序列。若想深入理解贝塞尔曲线的数学定义与绘制方法可继续阅读仓库中的 贝塞尔曲线 章节。总结一个任务的本质在40x24px→400x240px的 CSS 尺寸过渡上把时间函数换成cubic-bezier(0.25, 1.5, 0.75, 1.5)利用中间控制点y 1让动画完成度短暂突破最终值形成跳出—回弹效果核心原理贝塞尔曲线的y轴表示完成度y 1即属性值超过目标值y 0即属性值低于起始值这正是 CSS 过渡能越界的根源工程量相比基础任务仅改动一行transition声明全程无需 JavaScript 逐帧控制体现了简单的事简单地做的 CSS 动画哲学可验证依据任务说明见 task.md解法与曲线图见 solution.md完整可运行页面见 solution.view/index.html。赞分享文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载相关推荐现代 JavaScript 教程实战用 cubic-bezier 让飞机图片“跳出去”再回弹CSS 动画任务解析现代 JavaScript 教程实战用 cubic bezier 让飞机图片“跳出去”再回弹CSS 动画任务解析 导读 本文聚焦《现代 JavaScrip文档/教程前端JavaScript.info CSS 动画实战用 cubic-bezier 控制点让飞机跳出尺寸上限JavaScript.info CSS 动画实战用 cubic bezier 控制点让飞机跳出尺寸上限 本篇基于 Modern JavaScript Tu文档/教程前端CSS 贝塞尔曲线回弹动画实战让飞机“跳出”边界再归位zh.javascript.infoCSS 贝塞尔曲线回弹动画实战让飞机“跳出”边界再归位zh.javascript.info 本指南基于《现代 JavaScript 教程》仓库中的 CSS文档教程前端上一篇R3nzSkin英雄联盟国服免费换肤终极解决方案下一篇为什么你的Windows 11 LTSC系统需要微软应用商店3分钟解决方案揭秘创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考