阿里云主机折上折
  • 微信号
Current Site:Index > GSAP Timeline: An Interactive Coffee Cooling Animation

GSAP Timeline: An Interactive Coffee Cooling Animation

Author:Chuan Chen 阅读数:14122人阅读 分类: 前端综合

GSAP (GreenSock Animation Platform)'s timeline feature provides precise timing control for front-end animations. By simulating the cooling process of a cup of coffee, it intuitively demonstrates how to use timelines to achieve complex interactive animation effects.

Core Requirements for the Coffee Cooling Animation

The cooling process of a hot cup of coffee involves multiple visual changes: steam gradually diminishing, liquid surface ripples weakening, and water droplets condensing on the cup walls. These changes need to be triggered in a specific order, with some animations requiring linkage to user interactions (such as stirring). Traditional CSS animations struggle to handle this multi-element, multi-stage timing logic.

Creating the Basic Timeline Structure

GSAP's Timeline allows multiple animations to be chained or parallelized. The following code initializes a timeline and adds basic cooling animations:

import { gsap } from "gsap";

const coffeeTimeline = gsap.timeline({
  defaults: { duration: 1.5, ease: "power2.out" }
});

// Steam reduction animation  
coffeeTimeline.to(".steam", {
  opacity: 0.3,
  y: -50,
  scale: 0.8
}, 0);

// Liquid surface ripple weakening  
coffeeTimeline.to(".liquid-surface", {
  attr: { 
    d: "M10,20 Q50,15 90,20" // Modify SVG path to smooth ripples  
  }
}, 2);

Handling Phased Animations for Temperature Changes

The drop in coffee temperature is not linear and requires phased adjustments to the animation curve. Use the timeline's addLabel method to mark key temperature nodes:

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");

User Interaction with Timeline Control

When the user clicks the stir button, the cooling process needs to temporarily accelerate. Dynamic speed adjustment is achieved using the timeline's timeScale method:

document.querySelector(".stir-button").addEventListener("click", () => {
  // Create stirring particle animation  
  const stirParticles = gsap.to(".particle", {
    x: "+=random(-20,20)",
    y: "+=random(-10,5)",
    opacity: 0,
    duration: 0.8,
    stagger: 0.05
  });

  // Accelerate the main timeline  
  coffeeTimeline.timeScale(2.5);
  
  // Restore original speed after 3 seconds  
  setTimeout(() => {
    coffeeTimeline.timeScale(1);
  }, 3000);
});

Combining Physics Simulation with Timeline

More realistic cooling effects require physical parameters. Integrate a physics engine using GSAP's plugin system:

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");

Responsive Timeline Adjustments

Animation parameters need to adapt dynamically to different screen sizes. Use GSAP's matchMedia feature:

gsap.matchMedia().add("(max-width: 600px)", () => {
  coffeeTimeline.to(".steam", { 
    y: -30, 
    duration: 1 
  }, 0);
});

Performance Optimization Tips

For complex animations, note the following:

  1. Enable will-change for static elements
  2. Use transform instead of positional animations
  3. Destroy completed animation objects in phases
.coffee-cup {
  will-change: transform, opacity;
}

Debugging Tools for Timelines

GSAP provides visual debugging tools, or you can create custom debug panels:

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);
}

Integrating Timelines with Web Components

Encapsulate coffee animation components in custom elements:

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);

Dynamic Data-Driven Animations

When animations need to be driven by real-time temperature data:

function updateCoolingAnimation(currentTemp) {
  const progress = gsap.utils.mapRange(95, 30, 0, 1, currentTemp);
  coffeeTimeline.progress(progress);
}

// Simulate temperature sensor data  
setInterval(() => {
  const temp = getCoffeeTemperature(); // Hypothetical temperature-fetching method  
  updateCoolingAnimation(temp);
}, 1000);

Fine Control Over Timeline Sequences

Precisely control micro-animation sequences within 600 milliseconds:

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);

Binding Business Logic to Animation Events

Trigger business logic at specific animation nodes:

coffeeTimeline.eventCallback("onComplete", () => {
  document.querySelector(".status-indicator").textContent = "Coffee has cooled";
});

coffeeTimeline.eventCallback("onUpdate", () => {
  const currentProgress = coffeeTimeline.progress();
  if(currentProgress > 0.7) {
    enableDrinkWarning();
  }
});

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.