5.0.1

Advanced GSAP Animations

Learn how to create complex animations using GSAP with TresJS

This recipe demonstrates how to create sophisticated animations using GSAP (GreenSock Animation Platform) with TresJS for smooth, performance-optimized animations with advanced features like staggering and timeline control.

Install GSAP

First, install GSAP as a dependency in your project:

npm install gsap

Import required modules

Import GSAP and the necessary Vue composables. Use shallowRef for better performance with Three.js objects:

import { shallowRef, watch } from 'vue'
import { OrbitControls } from '@tresjs/cientos'
import gsap from 'gsap'
Use shallowRef instead of ref to avoid unnecessary reactivity on Three.js objects, which improves performance.

Create multiple objects to animate

Set up an array of positions for multiple boxes that will be animated with stagger effects:

const boxesRef = shallowRef()
const zs = []
for (let z = -4.5; z <= 4.5; z++) {
  zs.push(z)
}

Set up the scene structure

Create a group of meshes that will be animated together:

<template>
  <TresPerspectiveCamera :position="[-15, 10, 15]" />
  <OrbitControls />
  <TresGroup ref="boxesRef">
    <TresMesh v-for="(z, i) of zs" :key="i" :position="[0, 0.5, z]">
      <TresBoxGeometry />
      <TresMeshNormalMaterial />
    </TresMesh>
  </TresGroup>
  <TresGridHelper :args="[10, 10, 0x444444, 'teal']" />
</template>

Create the GSAP staggered animation

Use Vue's watch to set up the animation when the template ref is available:

watch(boxesRef, () => {
  if (!boxesRef.value) return

  // Get positions and rotations for all boxes
  const positions = Array.from(boxesRef.value.children).map(
    (child) => child.position
  )
  const rotations = Array.from(boxesRef.value.children).map(
    (child) => child.rotation
  )

  const animProperties = {
    ease: 'power1.inOut',
    duration: 1,
    stagger: {
      each: 0.25,
      repeat: -1,
      yoyo: true,
    },
  }

  // Animate positions
  gsap.to(positions, {
    y: 2.5,
    ...animProperties,
  })

  // Animate rotations
  gsap.to(rotations, {
    x: 2,
    ...animProperties,
  })
})

Understanding GSAP Stagger Options

The stagger property provides powerful control over timing:

const animProperties = {
  ease: 'power1.inOut',     // Easing function
  duration: 1,              // Animation duration in seconds
  stagger: {
    each: 0.25,            // Delay between each object (0.25s)
    repeat: -1,            // Infinite repeat (-1)
    yoyo: true,            // Reverse on alternate cycles
    from: 'start',         // Animation direction (start, center, end)
  },
}
Learn more about GSAP stagger options and configurations.

Advanced Techniques

Timeline Control

For more complex sequences, use GSAP timelines to coordinate multiple animations:

TimelineAnimation.vue
<script setup lang="ts">
import { shallowRef, watch, onMounted } from 'vue'
import gsap from 'gsap'

const groupRef = shallowRef()
const timeline = gsap.timeline({ paused: true })

watch(groupRef, () => {
  if (!groupRef.value) return

  const children = Array.from(groupRef.value.children)

  // Clear existing timeline
  timeline.clear()

  // Add multiple animations to timeline
  timeline
    .to(children.map(child => child.position), {
      y: 3,
      duration: 1,
      ease: 'back.out(1.7)',
      stagger: 0.1
    })
    .to(children.map(child => child.rotation), {
      y: Math.PI * 2,
      duration: 2,
      ease: 'power2.inOut',
      stagger: 0.1
    }, '-=0.5') // Start 0.5s before previous animation ends
    .to(children.map(child => child.scale), {
      x: 1.5,
      y: 1.5,
      z: 1.5,
      duration: 0.5,
      ease: 'elastic.out(1, 0.3)',
      stagger: 0.05
    })
})

// Control functions
const playAnimation = () => timeline.play()
const pauseAnimation = () => timeline.pause()
const reverseAnimation = () => timeline.reverse()
const restartAnimation = () => timeline.restart()
</script>

Performance Optimization

When animating many objects, optimize performance by:

  1. Use shallowRef for Three.js object references
  2. Batch property access to avoid repeated DOM queries
  3. Use GSAP's set() method for immediate property changes
  4. Leverage hardware acceleration with force3D: true
// Optimized animation setup
const optimizedAnimation = () => {
  // Get all properties at once
  const meshes = Array.from(boxesRef.value.children)
  const positions = meshes.map(mesh => mesh.position)
  const rotations = meshes.map(mesh => mesh.rotation)

  // Use force3D for hardware acceleration
  gsap.to(positions, {
    y: 2,
    duration: 1,
    force3D: true,
    ease: 'power2.out'
  })
}

Animation Events

GSAP provides powerful callback events to sync with your application state:

gsap.to(positions, {
  y: 2,
  duration: 1,
  stagger: 0.1,
  onStart: () => console.log('Animation started'),
  onComplete: () => console.log('Animation completed'),
  onUpdate: function() {
    // Called on every frame
    console.log('Progress:', this.progress())
  },
  onRepeat: () => console.log('Animation repeated')
})
GSAP automatically handles frame rate optimization and provides better performance than manual animations for complex sequences.
Explore the full GSAP documentation for advanced features and techniques.