logo
Technology

Creating Interactive Websites with GSAP and Three.js

Abhishek Sharma
Feb 12, 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 optimizations. 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: Organizes 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, synchronized 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 allow developers to create advanced visual effects, such as realistic lighting, reflections, and procedural textures.

Shaders are a key component of the graphics pipeline, influencing how vertices and pixels are processed to render a final scene. They enable custom rendering techniques beyond what built-in materials provide.

Types of Shaders:

Vertex Shader

  • Processes each vertex individually.
  • Manipulates vertex positions in 3D space (e.g., transformations, scaling, and rotation).
  • Used for effects like morphing, vertex displacement, and procedural animation.
  • Outputs transformed vertex data for further processing.

Fragment (Pixel) Shader

  • Determines the final color of each pixel on the screen.
  • Computes shading effects like lighting, shadows, reflections, and transparency.
  • Can include texture mapping, bump mapping, and procedural effects.
  • Used to create realistic materials and special effects.

Geometry Shader (Less common in Three.js)

  • Operates on entire primitives (points, lines, triangles) rather than individual vertices.
  • Can dynamically generate new geometry or modify existing shapes.
  • Useful for advanced effects like tessellation, grass, and particle systems.

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-synchronized 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 initialize 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/            # core 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 Optimizations

Optimize 3D Models

Reduce unnecessary geometry complexity by simplifying high-poly models. Use tools like Blender or Three.js's BufferGeometryUtils to merge geometries and minimize 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.

Optimize 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, 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.

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

Loved this article?

Hit the like button

Share this article

Spread the knowledge