logo
Technology

Creating Interactive Websites with GSAP and Three.js

Abhishek Sharma
Feb 10, 2025
12 minutes

In a digital world where AI can generate basic websites in seconds, standing out requires more than just a well-structured layout. Engaging, interactive, and visually compelling web experiences have become essential. This is where GSAP (GreenSock Animation Platform) and Three.js shine. These powerful tools allow developers to create dynamic, immersive experiences that captivate users and elevate web design to new heights.

In this blog, we'll explore how GSAP and Three.js can transform your web projects, walking through the setup, core components, animations, and performance optimisations. Our featured project is a 3D submarine experience with realistic ripple effects and smooth animations.

What is Three.js?

Three.js is a JavaScript library that makes working with WebGL easier by providing an abstraction layer for creating 3D graphics in the browser. It enables developers to create immersive experiences by rendering 3D objects, handling lighting, shadows, and animations.

Key Features of Three.js:

  • Scene Graph System: Organises objects in a hierarchical structure.
  • Camera Controls: Supports different camera types (Perspective, Orthographic, etc.).
  • Materials and Textures: Offers various materials (MeshBasicMaterial, MeshStandardMaterial) for realistic visuals.
  • Lighting and Shadows: Supports ambient, directional, point, and spotlights.
  • Physics Integration: Can be used with libraries like Cannon.js for physics simulations.
  • Post-Processing Effects: Enables effects like bloom, depth of field, and motion blur.

What is GSAP?

GSAP (GreenSock Animation Platform) is a high-performance JavaScript animation library widely used for smooth, efficient animations. It allows developers to animate DOM elements, SVG, and even WebGL objects with ease.

Key Features of GSAP:

  • Timeline-Based Animation: Sequence multiple animations efficiently.
  • Smooth Performance: Hardware-accelerated animations for lag-free performance.
  • ScrollTrigger: Sync animations with scroll events.
  • Easing Functions: Provides a variety of easing options like power1.inOut, bounce, and elastic.
  • SVG and WebGL Animation: Supports complex animations for 3D objects in Three.js.

By integrating GSAP with Three.js, developers can create fluid, synchronised animations that enhance user engagement.

What are Shaders?

Shaders are small programs that run on the GPU and control the appearance of 3D objects by defining how light interacts with them. In Three.js, shaders are written in GLSL (OpenGL Shading Language) and can be used for creating advanced visual effects.

Types of Shaders:

  1. Vertex Shader: Manipulates vertex positions in 3D space.
  2. Fragment Shader: Determines the final pixel colors.

Common Use Cases:

  • Water Effects: Simulate realistic waves and ripples.
  • Post-Processing Effects: Create glow, blur, and distortion effects.
  • Custom Materials: Define unique object appearances beyond built-in materials.

Project Overview

The project is an interactive 3D web experience featuring a highly detailed submarine model. By leveraging Three.js for real-time 3D rendering and GSAP for fluid animations, we create an engaging, immersive journey that responds to user interactions and scroll behavior.

Features:

  • 3D Submarine Model: A high-quality, interactive submarine rendered using Three.js.
  • Smooth GSAP Animations: Scroll-synchronised animations for lifelike movements.
  • Ripple Effects: A custom water shader reacts to mouse interactions.

Project Setup

First, let's set up our project using Vite with React. Follow the steps to create a new Vite project, navigate to the directory, install core dependencies, and initialise Tailwind CSS.

 # Create a new Vite project with React
 npm create vite@latest submarine-3d -- --template react

 # Navigate to project directory
 cd submarine-3d

 # Install core dependencies
 npm install @react-three/fiber @react-three/drei three gsap
 npm install -D tailwindcss postcss autoprefixer

 # Initialize Tailwind CSS
 npx tailwindcss init -p 


Project Structure

The project is organized into several directories, including components, helpers, sections, and the main application file.

 src/
 ├── components/
 ├── helpers/
 │ ├── Submarine_steampunk_palych.jsx # 3D model component
 │ └── Ripples.jsx          # Water effect shader
 ├── sections/             # Content sections
 └── App.jsx              # Main application


Core Components

1. Scene Setup

The 3D scene is built using React Three Fiber. It includes a canvas with shadows, a camera setup, and scroll controls for interactive navigation.

export const Scene = () => (
  <Canvas
   shadows
   resize
   camera={{ position: [1, 0, 0], fov: 30, near: 0.05, far: 10 }}
  >
   <Suspense fallback={<Loader />}>
    <ScrollControls pages={5} damping={0.8}>
     <SubMarineModel scale={0.03} />
     <Environment files={"warehouse.hdr"} path={"/hdr/"} />
     {/* Other components */}
    </ScrollControls>
   </Suspense>
  </Canvas>
 );

2. GSAP Animation System

The animation system uses GSAP timelines synchronized with scroll position. It includes an animation sequence for scaling, rotating, and adjusting the position of the submarine model.

 // Timeline setup
 const tl = useRef();
 const scroll = useScroll();

 // Initialize timeline
 useEffect(() => {
  tl.current = gsap.timeline({
   defaults: { duration: 2, ease: "power1.inOut" }
  });

  // Animation sequence
  tl.current
   // Initial state
   .to(groupRef.current.scale, { 
    y: 0.04, x: 0.04, z: 0.04,
    duration: 1.5,
    ease: "back.out(1.7)"
   }, 0)
   
   // Rotation animation
   .to(groupRef.current.rotation, { 
    y: -Math.PI / 2,
    duration: 2,
    ease: "power2.inOut"
   }, 2)
   
   // Position adjustment
   .to(groupRef.current.position, {
    z: 0.2,
    duration: 1,
    ease: "sine.out"
   }, 2);
 }, []);

 // Sync with scroll
 useFrame(() => {
  tl.current.seek(scroll.offset * tl.current.duration());
 });

3. Interactive Water Effects

The water ripple effect uses custom GLSL shaders to create dynamic visual effects based on mouse movement.

 const RippleShaderMaterial = shaderMaterial(
  // Uniforms
  {
   time: 0,
   mouse: new THREE.Vector2(0, 0)
  },
  // Vertex shader
  `
   varying vec2 vUv;
   uniform vec2 mouse;
   uniform float time;

   void main() {
    vUv = uv;
    vec3 pos = position;
    
    float dist = distance(mouse, vUv) * 10.0;
    pos.z += sin(dist - time * 3.0) * 0.03 * exp(-dist * 0.4);
    
    gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
   }
  `,
  // Fragment shader
  `
   varying vec2 vUv;
   void main() {
    gl_FragColor = vec4(0.0, 0.2, 0.5, 0.3);
   }
  `
 );

4. Loader Component

The Loader component uses the useProgress hook from @react-three/drei to display the loading progress of 3D assets. This provides a visual indication of loading status to the user, enhancing the user experience.

Performance Optimisations

Optimise 3D Models

Reduce unnecessary geometry complexity by simplifying high-poly models. Use tools like Blender or Three.js's BufferGeometryUtils to merge geometries and minimise draw calls, improving rendering efficiency.

Use Compressed Textures

Implement WebP and Draco compression to reduce texture file sizes without sacrificing quality. This ensures faster loading times and lower memory usage while maintaining visual fidelity.

Optimise GSAP Animations

Keep animations fluid and performant by limiting the number of active tweens at a time. Use gsap.quickTo() for smooth transitions and gsap.matchMedia() to tailor animations for different devices and screen sizes.

Monitor and Maintain Frame Rates

Use tools like Stats.js and requestAnimationFrame to track FPS and detect performance bottlenecks. Implement level-of-detail (LOD) techniques to dynamically adjust model detail based on the camera's distance, ensuring optimal performance without sacrificing user experience.

Final Thoughts

By combining Three.js, GSAP, and custom shaders, developers can craft truly immersive and interactive web experiences that go beyond traditional design. Whether it's an engaging product showcase, a dynamic portfolio, or an interactive storytelling experience, these technologies offer the flexibility and power to bring creative visions to life.

Three.js provides the 3D rendering backbone, GSAP ensures smooth and synchronised animations, and shaders add realistic visual effects like water ripples and lighting interactions. By following best practices in performance optimisation, such as reducing model complexity, compressing textures, and monitoring frame rates, you can ensure that your interactive experiences run smoothly across devices.

As web experiences continue to evolve, leveraging real-time 3D graphics and high-performance animations will be key to captivating users and differentiating your projects in an increasingly competitive digital landscape. The tools are there—now it's time to explore, experiment, and push the boundaries of web interactivity! 🚀


View Demo | GitHub Repository

Share this article

Spread the knowledge