Featured Article

AppleBurstPerfect:苹果官网招聘风的爆发色彩 + 背景过场是如何实现的

记录并拆解 AppleBurstPerfect 在 Hero 区实现的“爆发色彩 + 背景过场”,以及与内容区的无缝交接策略。包含结构设计、GSAP 时间线、参数选择、稳定性优化与常见坑。

September 29, 2025 (1w ago)
10 min read
2,175 views
194 likes
Category
Intermediate
#GSAP#ScrollTrigger#Animation#UX#Apple-style

AppleBurstPerfect:苹果官网招聘风的爆发色彩 + 背景过场是如何实现的

本文记录 src/components/ui/apple-burst-perfect.tsx 中的实现思路,并说明它如何和内容区 src/components/ui/projects-stepper.tsx 无缝接力,产出类似苹果招聘页的“有张力且顺滑”的观感。

效果目标

  • 在 Hero 区播放一段“色彩爆发”的视觉开场(叠加卡片逐张出现)。
  • 黑幕层淡出,舞台权利平滑交给后续的内容区。
  • 反向滚动时,可以安全回退到开场阶段,不出现重叠与拖尾。

核心结构

  • 爆发层 overlay:驱动 CSS 变量(如 --burst-size)与 opacity/blur,制造“能量扩散”感。
  • 黑幕层 blackoutOverlay:控光与节奏的“把关人”,负责淡入/淡出。
  • 叠加卡片 overlay cards:动态创建的 DOM 卡片,按节奏入场 → 停留 → 退场。

目录与文件:

  • src/components/ui/apple-burst-perfect.tsx
  • src/components/ui/projects-stepper.tsx

时间线与参数

时间线由 GSAP 统一调度,关键参数如下(桌面端):

  • 卡片节奏:
    • cardEnterDuration ≈ 0.58
    • cardHoldDuration ≈ 0.15
  • 黑幕衔接:
    • blackoutFadeStart = finalCardExitTime + 0.35
    • 最后一张卡片 exitStart = max(blackoutFadeStart - 0.3, exitTime - 0.12)(防拖尾)
  • 标题位移(如保留):
    • titleShiftDelay:Desktop 0.35 / Mobile 0.28

这些数值来自多轮观感与稳定性权衡:既保留“张力”,又避免节奏拖沓与残影。

关键时间线片段

// 伪代码:核心过场
const tl = gsap.timeline({ paused: true });
 
// 1) overlay 爆发与清晰化
tl.to(overlay, { opacity: 1, filter: "blur(0px)", duration: 0.6, ease: "power2.inOut" }, 0);
 
// 2) 叠加卡片逐张入场/退场
overlayCardEntries.forEach((entry, index) => {
  const enterTime = cardIntroStart + index * cardStep; // cardStep = enter + hold
  const exitTime  = enterTime + cardEnterDuration + cardHoldDuration;
 
  tl.set(entry.wrapper, { visibility: "visible" }, enterTime)
    .to(entry.wrapper, {
      opacity: 1, y: 0, filter: "blur(0px)", duration: cardEnterDuration, ease: "power3.out"
    }, enterTime)
    .to(entry.wrapper, {
      opacity: 0, y: -30, filter: "blur(16px)", duration: 0.35, ease: "power2.inOut"
    }, index === lastIndex
        ? Math.max(blackoutFadeStart - 0.3, exitTime - 0.12)
        : exitTime);
});
 
// 3) 黑幕淡出 + 发送就绪事件(交接给内容区)
tl.to(blackoutOverlay, {
  opacity: 0,
  duration: 0.45,
  ease: "power2.inOut",
  onComplete: () => window.dispatchEvent(new CustomEvent("projects:ready")),
  onReverseComplete: () => window.dispatchEvent(new CustomEvent("projects:unready")),
}, blackoutFadeStart);

与内容区的“时序交接”

projects-stepper.tsx 中:

  • 监听 projects:ready / projects:unready 事件,仅对卡片根容器设置显隐门控:
    • opacity: 0/1
    • pointer-events: none/auto
  • 加入 尾哨兵 data-stepper-end:滚过尾部时整体淡出,杜绝“最后一张遗留”。

这套“事件门控 + 尾哨兵”的组合,保证了正向/反向滚动时都能稳态过渡。

稳定性策略

  • 最后一张卡的退场提早:防止黑幕淡出时仍有卡片残留。
  • 就绪延迟 ~150ms:在接到 projects:ready 后,稍作延迟再显示内容,留给黑幕“最后一帧”沉降时间,减少快滚抖动。
  • visibility/opacity 双保险:卡片在入场前 visibility: hidden,入场瞬间再切 visible,退场后重置到初态。

性能与可维护性

  • 对运动元素设置 will-change: transform, opacity,降低重绘成本。
  • 所有阶段集中在同一条 GSAP Timeline 中统一管理,避免多个时间线“打架”。
  • 通过事件解耦跨组件通信,降低耦合度,方便替换或 A/B 测试。

常见坑与规避

  • 卡片与内容重叠:使用事件门控 + 尾哨兵,并确保黑幕淡出在卡片完全退场之后。
  • 快滚导致时序错乱:就绪延迟 + 仅门控卡片根容器(而非整个区块),可有效缓解。
  • 移动端负载:适度降低位移与模糊半径;必要时关闭部分粒子/高斯效果。

小结

“爆发色彩 + 背景过场”的质感,来自于节奏、层次与交接的共同塑形。AppleBurstPerfect 将爆发、卡片、黑幕这三者放在一条时间线上精细编排;ProjectsStepper 以事件为纽带,在正确的时刻接棒。两者协作,才有最终顺滑、克制而富有张力的体验。

想把这套方案复用到其他区块?可以把叠加卡片与黑幕提取为可配置模块(颜色、数量、节奏),再配一个 onHandoff 回调,即可通用化。

CleanLove

Written by CleanLove

Full-stack developer passionate about modern web technologies

Initializing application
Loading page content, please wait...