---
id: daily-gsap-frameworks
name: "gsap-frameworks"
url: https://skills.yangsir.net/skill/daily-gsap-frameworks
author: greensock
domain: ai-frontend-engineering
tags: ["gsap", "vue", "svelte", "frameworks", "lifecycle"]
install_count: 27300
rating: 4.60 (41 reviews)
github: https://github.com/greensock/gsap-skills
---

# gsap-frameworks

> 在 Vue、Svelte 等组件框架中使用 GSAP，处理生命周期挂载和清理，避免内存泄漏

**Stats**: 27,300 installs · 4.6/5 (41 reviews)

## Before / After 对比

### 框架动画集成

**Before**:

在组件中使用 GSAP 容易忘记清理动画，导致内存泄漏，重复挂载时动画异常

**After**:

正确处理组件生命周期，自动清理动画，避免内存泄漏和重复执行

| Metric | Before | After | Change |
|---|---|---|---|
| 内存泄漏率 | 25% | 0% | -100% |
| 代码稳定性 | 70% | 95% | +36% |

## Readme

# gsap-frameworks

# GSAP with Vue, Svelte, and Other Frameworks

## When to Use This Skill

Apply when writing or reviewing GSAP code in Vue (or Nuxt), Svelte (or SvelteKit), or other component frameworks that use a lifecycle (mounted/unmounted). For **React** specifically, use **gsap-react** (useGSAP hook, gsap.context()).

**Related skills:** For tweens and timelines use **gsap-core** and **gsap-timeline**; for scroll-based animation use **gsap-scrolltrigger**; for React use **gsap-react**.

## Principles (All Frameworks)

- **Create** tweens and ScrollTriggers **after** the component’s DOM is available (e.g. onMounted, onMount).

- **Kill or revert** them in the **unmount** (or equivalent) cleanup so nothing runs on detached nodes and there are no leaks.

- **Scope selectors** to the component root so `.box` and similar only match elements inside that component, not the rest of the page.

## Vue 3 (Composition API)

Use **onMounted** to run GSAP after the component is in the DOM. Use **onUnmounted** to clean up.

```
import { onMounted, onUnmounted, ref } from "vue";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger); // once per app, e.g. in main.js

export default {
  setup() {
    const container = ref(null);
    let ctx;

    onMounted(() => {
      if (!container.value) return;
      ctx = gsap.context(() => {
        gsap.to(".box", { x: 100, duration: 0.6 });
        gsap.from(".item", { autoAlpha: 0, y: 20, stagger: 0.1 });
      }, container.value);
    });

    onUnmounted(() => {
      ctx?.revert();
    });

    return { container };
  }
};

```

- ✅ **gsap.context(scope)** — pass the container ref (e.g. `container.value`) as the second argument so selectors like `.item` are scoped to that root. All animations and ScrollTriggers created inside the callback are tracked and reverted when **ctx.revert()** is called.

- ✅ **onUnmounted** — always call **ctx.revert()** so tweens and ScrollTriggers are killed and inline styles reverted.

## Vue 3 (script setup)

Same idea with `<script setup>` and refs:

```
<script setup>
import { onMounted, onUnmounted, ref } from "vue";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";

const container = ref(null);
let ctx;

onMounted(() => {
  if (!container.value) return;
  ctx = gsap.context(() => {
    gsap.to(".box", { x: 100 });
    gsap.from(".item", { autoAlpha: 0, stagger: 0.1 });
  }, container.value);
});

onUnmounted(() => {
  ctx?.revert();
});
</script>

<template>
  <div ref="container">
    <div class="box">Box</div>
    <div class="item">Item</div>
  </div>
</template>

```

## Svelte

Use **onMount** to run GSAP after the DOM is ready. Use the **returned cleanup function** from onMount (or track the context and clean up in a reactive block / component destroy) to revert. Svelte 5 uses a different lifecycle; the same principle applies: create in “mounted” and revert in “destroyed.”

```
<script>
  import { onMount } from "svelte";
  import { gsap } from "gsap";
  import { ScrollTrigger } from "gsap/ScrollTrigger";

  let container;

  onMount(() => {
    if (!container) return;
    const ctx = gsap.context(() => {
      gsap.to(".box", { x: 100 });
      gsap.from(".item", { autoAlpha: 0, stagger: 0.1 });
    }, container);
    return () => ctx.revert();
  });
</script>

<div bind:this={container}>
  <div class="box">Box</div>
  <div class="item">Item</div>
</div>

```

- ✅ **bind:this={container}** — get a reference to the root element so you can pass it to **gsap.context(scope)**.

- ✅ **return () => ctx.revert()** — Svelte’s onMount can return a cleanup function; call **ctx.revert()** there so cleanup runs when the component is destroyed.

## Scoping Selectors

Do not use global selectors that can match elements outside the current component. Always pass the **scope** (container element or ref) as the second argument to **gsap.context(callback, scope)** so that any selector run inside the callback is limited to that subtree.

- ✅ **gsap.context(() => { gsap.to(".box", ...) }, containerRef)** — `.box` is only searched inside `containerRef`.

- ❌ Running **gsap.to(".box", ...)** without a context scope in a component can affect other instances or the rest of the page.

## ScrollTrigger Cleanup

ScrollTrigger instances are created when you use the `scrollTrigger` config on a tween/timeline or **ScrollTrigger.create()**. They are **included** in **gsap.context()** and reverted when you call **ctx.revert()**. So:

- Create ScrollTriggers inside the same **gsap.context()** callback you use for tweens.

- Call **ScrollTrigger.refresh()** after layout changes (e.g. after data loads) that affect trigger positions; in Vue/Svelte that often means after the DOM updates (e.g. nextTick in Vue, tick in Svelte, or after async content load).

## When to Create vs Kill

Lifecycle
Action

**Mounted**
Create tweens and ScrollTriggers inside **gsap.context(scope)**.

**Unmount / Destroy**
Call **ctx.revert()** so all animations and ScrollTriggers in that context are killed and inline styles reverted.

Do not create GSAP animations in the component’s setup or in a synchronous top-level script that runs before the root element exists. Wait for **onMounted** / **onMount** (or equivalent) so the container ref is in the DOM.

## Do Not

- ❌ Create tweens or ScrollTriggers before the component is mounted (e.g. in setup without onMounted); the DOM nodes may not exist yet.

- ❌ Use selector strings without a **scope** (pass the container to gsap.context() as the second argument) so selectors don’t match elements outside the component.

- ❌ Skip cleanup; always call **ctx.revert()** in onUnmounted / onMount’s return so animations and ScrollTriggers are killed when the component is destroyed.

- ❌ Register plugins inside a component body that runs every render (it doesn't hurt anything, it's just wasteful); register once at app level.

### Learn More

- **gsap-react** skill for React-specific patterns (useGSAP, contextSafe).

Weekly Installs249Repository[greensock/gsap-skills](https://github.com/greensock/gsap-skills)GitHub Stars239First Seen1 day agoSecurity Audits[Gen Agent Trust HubPass](/greensock/gsap-skills/gsap-frameworks/security/agent-trust-hub)[SocketPass](/greensock/gsap-skills/gsap-frameworks/security/socket)[SnykPass](/greensock/gsap-skills/gsap-frameworks/security/snyk)Installed onkimi-cli248gemini-cli248amp248cline248github-copilot248codex248

---
*Source: https://skills.yangsir.net/skill/daily-gsap-frameworks*
*Markdown mirror: https://skills.yangsir.net/api/skill/daily-gsap-frameworks/markdown*