You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React中使用GSAP实现滚动触发的缩放切换效果?

需求与问题修复

交互需求

  • 向下滚动至section1区域时,通过缓慢放大section1的操作逐步显示section2内容
  • 向上滚动离开section2区域时,section1缩小恢复原状,重新显示section1内容
  • 重复滚动时交互行为保持一致

原尝试代码(存在问题)

import React, { useEffect } from 'react';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';

const SampleZoom () => {
  useEffect(() => {
    // Initialize gsap and ScrollTrigger
    gsap.registerPlugin(ScrollTrigger);

    // Get the innerHeight
    const { innerHeight } = window;

    // Define the zoom-out animation
    gsap.from("#section1", {
      scale: 2, // Zoom out by scaling down
      opacity: 0, // Make it fade in
      scrollTrigger: {
        trigger: "#zoom-out",
        start: "top top", // Start the animation at the top of the element
        end: `+=${innerHeight * 0.5}`, // End the animation after scrolling down by 50% of the viewport height
        scrub: 1, // Add scrubbing effect
      }
    });

    // Define the zoom-in animation
    gsap.to("#section2", {
      scale: 1, // Zoom back in to normal size
      opacity: 1, // Make it fade in
      scrollTrigger: {
        trigger: "#zoom-in",
        start: "top top", // Start the animation at the top of the element
        end: `+=${innerHeight * 0.5}`, // End the animation after scrolling down by 50% of the viewport height
        scrub: 1, // Add scrubbing effect
      }
    });
  }, []);

  return (
    <div>
      <div id="section1">
       <h2>ROBO</h2>
      </div>
      <div id="section2">
        Hello world. I am Chitti, The Robot .. Speed 1 THz .. Memory 1 zettabyte. I'll be back. Get ready folks!"
The most expensive movie made in India till date has finally released and has already broken all box office records. Enthiran! This is the same movie that was originally supposed to start in 1998 with Kamal Hassan playing the lead role, then with vikram in the early 2000 and went on to cast Shah Rukh Khan a couple of years back and finally released with Rajnikanth playing the lead role. I managed to watch the movie a week into its release and like a farewell note sent by an IT/ITES employee, I have mixed feeling.
      </div>
    </div>
  );
};

export default SampleZoom;

修复后的代码

import React, { useEffect } from 'react';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import './SampleZoom.css'; // 引入配套样式

const SampleZoom = () => {
  useEffect(() => {
    gsap.registerPlugin(ScrollTrigger);

    // 创建时间线绑定同步动画
    const timeline = gsap.timeline({
      scrollTrigger: {
        trigger: "#container",
        start: "top top",
        end: "+=100vh", // 滚动一屏高度完成动画
        scrub: true,
        toggleActions: "play reverse play reverse" // 适配滚动方向的动画行为
      }
    });

    // 同步执行:section1放大,section2逐步显示
    timeline
      .to("#section1", {
        scale: 3,
        duration: 1
      })
      .to("#section2", {
        opacity: 1,
        duration: 1
      }, 0); // 0表示与上一动画同时启动

    // 清理ScrollTrigger防止内存泄漏
    return () => {
      ScrollTrigger.getAll().forEach(trigger => trigger.kill());
    };
  }, []);

  return (
    <div id="container">
      <div id="section1">
        <h2>ROBO</h2>
      </div>
      <div id="section2">
        Hello world. I am Chitti, The Robot .. Speed 1 THz .. Memory 1 zettabyte. I'll be back. Get ready folks!
        The most expensive movie made in India till date has finally released and has already broken all box office records. Enthiran! This is the same movie that was originally supposed to start in 1998 with Kamal Hassan playing the lead role, then with vikram in the early 2000 and went on to cast Shah Rukh Khan a couple of years back and finally released with Rajnikanth playing the lead role. I managed to watch the movie a week into its release and like a farewell note sent by an IT/ITES employee, I have mixed feeling.
      </div>
    </div>
  );
};

export default SampleZoom;

配套样式文件(SampleZoom.css)

#container {
  height: 200vh; /* 容器高度设为两屏,提供滚动空间 */
  position: relative;
}

#section1 {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #fff;
  z-index: 1;
  transform-origin: center; /* 从中心向外放大 */
}

#section2 {
  position: absolute;
  top: 100vh;
  left: 0;
  width: 100%;
  min-height: 100vh;
  padding: 2rem;
  box-sizing: border-box;
  opacity: 0; /* 初始状态隐藏 */
  z-index: 0;
}

关键修改说明

  1. 修复语法错误:修正组件定义的语法错误const SampleZoom () => → const SampleZoom = () =>
  2. 统一动画逻辑:使用GSAP Timeline将section1放大与section2显示绑定为同步动画,确保交互连贯
  3. 调整布局结构:设置容器高度为200vh提供滚动空间,section1设为fixed固定在视口,section2放在容器第二屏位置
  4. 优化ScrollTrigger配置:通过toggleActions确保滚动方向切换时动画正确反向执行,添加清理函数避免内存泄漏
  5. 对齐初始状态:section2初始opacity设为0,随section1放大逐步显示,匹配需求中的"缓慢放大显示section2"效果

内容的提问来源于stack exchange,提问作者Allu Manikyam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 01:40:27