GSAP 时间轴:一杯交互式咖啡的冷却动画
GSAP(GreenSock Animation Platform)的时间轴功能为前端动画提供了精准的时序控制能力。通过模拟一杯咖啡的冷却过程,可以直观地展示如何利用时间轴实现复杂的交互式动画效果。
咖啡冷却动画的核心需求
一杯热咖啡的冷却过程涉及多个视觉变化:蒸汽逐渐减少、液体表面波纹减弱、杯壁水珠凝结等。这些变化需要按特定顺序触发,且部分动画需与用户交互(如搅拌)联动。传统CSS动画难以处理这种多元素、多阶段的时序逻辑。
创建基础时间轴结构
GSAP的时间轴(Timeline)允许将多个动画串联或并联。以下代码初始化一个时间轴并添加基础冷却动画:
import { gsap } from "gsap";
const coffeeTimeline = gsap.timeline({
defaults: { duration: 1.5, ease: "power2.out" }
});
// 蒸汽减少动画
coffeeTimeline.to(".steam", {
opacity: 0.3,
y: -50,
scale: 0.8
}, 0);
// 液体表面波纹减弱
coffeeTimeline.to(".liquid-surface", {
attr: {
d: "M10,20 Q50,15 90,20" // 修改SVG路径实现波纹平缓
}
}, 2);
处理温度变化的阶段动画
咖啡温度下降不是线性的,需要分阶段调整动画曲线。使用时间轴的addLabel
方法标记关键温度节点:
coffeeTimeline
.addLabel("highTemp")
.to(".temperature-gauge", { fill: "#FF4500" }, "highTemp")
.addLabel("mediumTemp", "+=4")
.to(".temperature-gauge", { fill: "#FF8C00" }, "mediumTemp")
.addLabel("lowTemp", "+=6")
.to(".temperature-gauge", { fill: "#FFA500" }, "lowTemp");
用户交互的时间轴控制
当用户点击搅拌按钮时,需要临时加速冷却过程。通过时间轴的timeScale
方法实现动态调速:
document.querySelector(".stir-button").addEventListener("click", () => {
// 创建搅拌粒子动画
const stirParticles = gsap.to(".particle", {
x: "+=random(-20,20)",
y: "+=random(-10,5)",
opacity: 0,
duration: 0.8,
stagger: 0.05
});
// 加速主时间轴
coffeeTimeline.timeScale(2.5);
// 3秒后恢复原速
setTimeout(() => {
coffeeTimeline.timeScale(1);
}, 3000);
});
物理模拟与时间轴结合
更真实的冷却效果需要物理参数。使用GSAP的插件系统整合物理引擎:
import { Physics2DPlugin } from "gsap/Physics2DPlugin";
gsap.registerPlugin(Physics2DPlugin);
coffeeTimeline.to(".coffee-molecule", {
physics2D: {
velocity: "random(-50,50)",
acceleration: 5,
friction: 0.8
},
duration: 3
}, "coolingStart+=1");
响应式时间轴调整
不同屏幕尺寸下,动画参数需要动态适应。使用GSAP的matchMedia
功能:
gsap.matchMedia().add("(max-width: 600px)", () => {
coffeeTimeline.to(".steam", {
y: -30,
duration: 1
}, 0);
});
性能优化技巧
复杂动画中需注意:
- 对静态元素启用
will-change
- 使用
transform
代替位置动画 - 分阶段销毁已完成动画对象
.coffee-cup {
will-change: transform, opacity;
}
调试时间轴的工具方法
GSAP提供可视化调试工具,也可自定义调试面板:
function createDebugPanel() {
const slider = document.createElement("input");
slider.type = "range";
slider.addEventListener("input", (e) => {
coffeeTimeline.pause();
coffeeTimeline.progress(e.target.value / 100);
});
document.body.appendChild(slider);
}
时间轴与Web组件的集成
在自定义元素中封装咖啡动画组件:
class CoffeeAnimation extends HTMLElement {
constructor() {
super();
this.timeline = gsap.timeline({ paused: true });
this._initAnimations();
}
_initAnimations() {
this.timeline
.fromTo(this.querySelector(".liquid"),
{ yPercent: 10 },
{ yPercent: 0 }
);
}
}
customElements.define("coffee-animation", CoffeeAnimation);
动态数据驱动的动画
当需要根据实时温度数据驱动动画时:
function updateCoolingAnimation(currentTemp) {
const progress = gsap.utils.mapRange(95, 30, 0, 1, currentTemp);
coffeeTimeline.progress(progress);
}
// 模拟温度传感器数据
setInterval(() => {
const temp = getCoffeeTemperature(); // 假设的获取温度方法
updateCoolingAnimation(temp);
}, 1000);
时间轴序列的精细控制
精确控制600毫秒内的微动画序列:
coffeeTimeline
.set(".bubble-1", { opacity: 0 })
.to(".bubble-1", {
opacity: 1,
duration: 0.2
}, 0.1)
.to(".bubble-1", {
y: -20,
duration: 0.3
}, 0.3)
.set(".bubble-1", { opacity: 0 }, 0.6);
动画事件的业务逻辑绑定
在特定动画节点触发业务逻辑:
coffeeTimeline.eventCallback("onComplete", () => {
document.querySelector(".status-indicator").textContent = "咖啡已冷却";
});
coffeeTimeline.eventCallback("onUpdate", () => {
const currentProgress = coffeeTimeline.progress();
if(currentProgress > 0.7) {
enableDrinkWarning();
}
});
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn