gsap-nuxt-module 1.1.5 → 1.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +4 -6
- package/dist/runtime/composables/createGsapComposable.d.ts +48 -13
- package/dist/runtime/composables/createGsapComposable.js +37 -0
- package/dist/runtime/create-gsap-composable.d.ts +13 -4
- package/dist/runtime/create-gsap-composable.js +1 -0
- package/dist/runtime/gsap-loaders.d.ts +3 -0
- package/dist/runtime/gsap-loaders.js +7 -0
- package/dist/runtime/gsap-plugins.d.ts +0 -4
- package/dist/runtime/gsap-plugins.js +4 -3
- package/dist/runtime/plugin.js +34 -30
- package/package.json +11 -10
package/README.md
CHANGED
|
@@ -18,7 +18,8 @@ Find and replace all on all files (CMD+SHIFT+F):
|
|
|
18
18
|
|
|
19
19
|
**Enhance your Nuxt application with powerful animations and transitions using GSAP!**
|
|
20
20
|
|
|
21
|
-
- [
|
|
21
|
+
- [📖 Documentation](https://lucaargentieri.github.io/gsap-nuxt-module/)
|
|
22
|
+
- [🏀 Online playground](https://stackblitz.com/edit/gsap-nuxt-module?file=README.md)
|
|
22
23
|
- [📖 GSAP](https://gsap.com/)
|
|
23
24
|
|
|
24
25
|
## Features
|
|
@@ -100,6 +101,114 @@ onMounted(() => {
|
|
|
100
101
|
|
|
101
102
|
That's it! You can now use gsap-nuxt-module in your Nuxt app ✨
|
|
102
103
|
|
|
104
|
+
## useGsap()
|
|
105
|
+
|
|
106
|
+
`useGsap()` returns the GSAP instance directly — use it to access `gsap.timeline()`,
|
|
107
|
+
`gsap.to()`, `gsap.set()`, utility methods like `gsap.utils.toArray()`, and more.
|
|
108
|
+
No import needed; it is auto-imported like all other composables.
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
<script setup lang="ts">
|
|
112
|
+
const gsap = useGsap()
|
|
113
|
+
const boxRef = ref(null)
|
|
114
|
+
|
|
115
|
+
onMounted(() => {
|
|
116
|
+
const tl = gsap.timeline({ repeat: -1, yoyo: true })
|
|
117
|
+
tl.to(boxRef.value, { x: 200, duration: 1, ease: 'power2.inOut' })
|
|
118
|
+
.to(boxRef.value, { rotation: 360, duration: 0.8 })
|
|
119
|
+
})
|
|
120
|
+
</script>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Available composables
|
|
124
|
+
|
|
125
|
+
| Composable | Plugin | `nuxt.config.ts` key |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| `useGsap()` | GSAP core | — (always available) |
|
|
128
|
+
| `useScrollTrigger()` | ScrollTrigger | `ScrollTrigger` |
|
|
129
|
+
| `useScrollSmoother()` | ScrollSmoother | `ScrollSmoother` |
|
|
130
|
+
| `useSplitText()` | SplitText | `SplitText` |
|
|
131
|
+
| `useMotionPathHelper()` | MotionPathHelper | `MotionPathHelper` |
|
|
132
|
+
| `useDraggable()` | Draggable | `Draggable` |
|
|
133
|
+
| `useFlip()` | Flip | `Flip` |
|
|
134
|
+
| `useObserver()` | Observer | `Observer` |
|
|
135
|
+
| `useGSDevTools()` | GSDevTools | `GSDevTools` |
|
|
136
|
+
| `useCustomEase()` | CustomEase | `CustomEase` |
|
|
137
|
+
| `useCustomWiggle()` | CustomWiggle | `CustomWiggle` |
|
|
138
|
+
| `useCustomBounce()` | CustomBounce | `CustomBounce` |
|
|
139
|
+
|
|
140
|
+
## Plugin loading
|
|
141
|
+
|
|
142
|
+
Only plugins listed in `nuxt.config.ts` are dynamically imported —
|
|
143
|
+
zero bundle overhead for unused plugins.
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
// nuxt.config.ts
|
|
147
|
+
export default defineNuxtConfig({
|
|
148
|
+
gsap: {
|
|
149
|
+
plugins: ['ScrollTrigger', 'Draggable'],
|
|
150
|
+
// only these two will be bundled
|
|
151
|
+
},
|
|
152
|
+
})
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Cleanup
|
|
156
|
+
|
|
157
|
+
GSAP animations are not automatically cleaned up when a component unmounts.
|
|
158
|
+
Use `onUnmounted` to prevent memory leaks.
|
|
159
|
+
|
|
160
|
+
Plugin registration is handled once by the module at app startup — never call `gsap.registerPlugin()` manually.
|
|
161
|
+
In components, clean up only the instances your component created (tweens, timelines, ScrollTrigger instances, Draggable instances, etc.).
|
|
162
|
+
|
|
163
|
+
**Simple plugin instance cleanup (`Draggable`):**
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
<script setup lang="ts">
|
|
167
|
+
const Draggable = useDraggable()
|
|
168
|
+
const boxRef = ref<HTMLElement | null>(null)
|
|
169
|
+
let draggables: ReturnType<typeof Draggable.create> = []
|
|
170
|
+
|
|
171
|
+
onMounted(() => {
|
|
172
|
+
if (!boxRef.value) return
|
|
173
|
+
draggables = Draggable.create(boxRef.value)
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
onUnmounted(() => {
|
|
177
|
+
draggables.forEach((instance) => instance.kill())
|
|
178
|
+
draggables = []
|
|
179
|
+
})
|
|
180
|
+
</script>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
See real cleanup examples in `playground/pages/draggable.vue`, `playground/pages/scroll-trigger.vue`, `playground/pages/split-text.vue`, and `playground/pages/scroll-smoother.vue`.
|
|
184
|
+
|
|
185
|
+
**Recommended — `gsap.context()` (covers all child tweens, timelines and ScrollTriggers):**
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
<script setup lang="ts">
|
|
189
|
+
const gsap = useGsap()
|
|
190
|
+
let ctx: gsap.Context
|
|
191
|
+
|
|
192
|
+
onMounted(() => {
|
|
193
|
+
ctx = gsap.context(() => {
|
|
194
|
+
gsap.to('.box', { x: 100 })
|
|
195
|
+
})
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
onUnmounted(() => ctx.revert())
|
|
199
|
+
</script>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Single timeline:**
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
const gsap = useGsap()
|
|
206
|
+
const tl = gsap.timeline()
|
|
207
|
+
onUnmounted(() => tl.kill())
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
→ [gsap.context() docs](https://gsap.com/docs/v3/GSAP/gsap.context())
|
|
211
|
+
|
|
103
212
|
## Contribution
|
|
104
213
|
|
|
105
214
|
<details>
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { fileURLToPath } from 'node:url';
|
|
2
1
|
import { defineNuxtModule, createResolver, addPlugin, addImportsDir } from '@nuxt/kit';
|
|
3
2
|
|
|
4
3
|
const module$1 = defineNuxtModule({
|
|
@@ -13,14 +12,13 @@ const module$1 = defineNuxtModule({
|
|
|
13
12
|
plugins: []
|
|
14
13
|
},
|
|
15
14
|
setup(_options, _nuxt) {
|
|
16
|
-
const
|
|
17
|
-
const runtimeDir = fileURLToPath(new URL("./runtime", import.meta.url));
|
|
15
|
+
const { resolve } = createResolver(import.meta.url);
|
|
18
16
|
_nuxt.options.runtimeConfig.public.gsap = {
|
|
19
17
|
plugins: _options.plugins ?? []
|
|
20
18
|
};
|
|
21
|
-
addPlugin(
|
|
22
|
-
addImportsDir(
|
|
23
|
-
addImportsDir(
|
|
19
|
+
addPlugin({ src: resolve("./runtime/plugin"), mode: "client" });
|
|
20
|
+
addImportsDir(resolve("./runtime/composables"));
|
|
21
|
+
addImportsDir(resolve("./runtime/utils"));
|
|
24
22
|
}
|
|
25
23
|
});
|
|
26
24
|
|
|
@@ -1,3 +1,37 @@
|
|
|
1
|
+
import { gsap } from 'gsap';
|
|
2
|
+
import type { ComputedRef, Ref, WatchSource } from 'vue';
|
|
3
|
+
type ContextSafeFn = <F extends (...args: unknown[]) => unknown>(fn: F) => F;
|
|
4
|
+
export interface UseGsapOptions {
|
|
5
|
+
scope?: Ref<HTMLElement | null> | ComputedRef<HTMLElement | null>;
|
|
6
|
+
dependencies?: WatchSource | WatchSource[];
|
|
7
|
+
revertOnUpdate?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Zero-argument overload — returns the raw GSAP instance.
|
|
11
|
+
*
|
|
12
|
+
* Use it to call `gsap.timeline()`, `gsap.to()`, `gsap.set()`,
|
|
13
|
+
* utility methods (`gsap.utils`, `gsap.ticker`), and more.
|
|
14
|
+
*
|
|
15
|
+
* **Cleanup is the caller's responsibility.**
|
|
16
|
+
*
|
|
17
|
+
* @see https://gsap.com/docs/v3/GSAP/
|
|
18
|
+
*/
|
|
19
|
+
export declare function useGsap(): typeof gsap;
|
|
20
|
+
/**
|
|
21
|
+
* Setup-function overload — wraps `gsap.context()` with automatic revert.
|
|
22
|
+
*
|
|
23
|
+
* Animations declared inside `setup` are scoped to the optional `scope` element
|
|
24
|
+
* and are reverted automatically when the component unmounts (or the effect scope
|
|
25
|
+
* is disposed). Pass `dependencies` to re-run `setup` reactively.
|
|
26
|
+
*
|
|
27
|
+
* Returns `{ contextSafe }` — a wrapper for event handlers that need to add
|
|
28
|
+
* animations to the existing context after mount.
|
|
29
|
+
*
|
|
30
|
+
* @see https://gsap.com/docs/v3/GSAP/gsap.context()
|
|
31
|
+
*/
|
|
32
|
+
export declare function useGsap(setup: (ctx: gsap.Context) => void, options?: UseGsapOptions): {
|
|
33
|
+
contextSafe: ContextSafeFn;
|
|
34
|
+
};
|
|
1
35
|
export declare const useScrollTrigger: () => {
|
|
2
36
|
new (vars: ScrollTrigger.StaticVars, animation?: gsap.core.Animation): {
|
|
3
37
|
readonly animation?: gsap.core.Animation | undefined;
|
|
@@ -51,14 +85,14 @@ export declare const useScrollTrigger: () => {
|
|
|
51
85
|
observe(vars: Observer.ObserverVars): Observer;
|
|
52
86
|
positionInViewport(element: Element | string, referencePoint?: string | number, horizontal?: boolean): number;
|
|
53
87
|
refresh(safe?: boolean): void;
|
|
54
|
-
register(core: typeof gsap): void;
|
|
88
|
+
register(core: typeof globalThis.gsap): void;
|
|
55
89
|
removeEventListener(event: "scrollStart" | "scrollEnd" | "refreshInit" | "refresh" | "matchMedia" | "revert", callback: gsap.Callback): void;
|
|
56
90
|
saveStyles(targets: gsap.DOMTarget): void;
|
|
57
91
|
scrollerProxy(scroller: gsap.DOMTarget, vars?: ScrollTrigger.ScrollerProxyVars): void;
|
|
58
92
|
snapDirectional(incrementOrArray: number | number[]): ScrollTrigger.SnapDirectionalFunc;
|
|
59
93
|
sort(func?: Function): ScrollTrigger[];
|
|
60
94
|
update(): void;
|
|
61
|
-
};
|
|
95
|
+
} | null;
|
|
62
96
|
export declare const useScrollSmoother: () => {
|
|
63
97
|
new (vars: ScrollSmoother.Vars): {
|
|
64
98
|
readonly scrollTrigger: ScrollTrigger;
|
|
@@ -86,7 +120,7 @@ export declare const useScrollSmoother: () => {
|
|
|
86
120
|
create(vars: ScrollSmoother.Vars): ScrollSmoother;
|
|
87
121
|
get(): ScrollSmoother | undefined;
|
|
88
122
|
refresh(safe?: boolean): void;
|
|
89
|
-
};
|
|
123
|
+
} | null;
|
|
90
124
|
export declare const useSplitText: () => {
|
|
91
125
|
new (target: gsap.DOMTarget, vars?: SplitText.Vars): {
|
|
92
126
|
readonly chars: Element[];
|
|
@@ -100,14 +134,14 @@ export declare const useSplitText: () => {
|
|
|
100
134
|
split(vars: SplitText.Vars): SplitText;
|
|
101
135
|
};
|
|
102
136
|
create(target: gsap.DOMTarget, vars?: SplitText.Vars): SplitText;
|
|
103
|
-
};
|
|
137
|
+
} | null;
|
|
104
138
|
export declare const useMotionPathHelper: () => {
|
|
105
139
|
new (target: gsap.DOMTarget, vars?: MotionPathHelper.Vars): {
|
|
106
140
|
kill(): void;
|
|
107
141
|
};
|
|
108
142
|
create(target: gsap.DOMTarget, vars?: MotionPathHelper.Vars): MotionPathHelper;
|
|
109
143
|
editPath(target: gsap.DOMTarget, vars?: MotionPathHelper.EditPathVars): MotionPathHelper;
|
|
110
|
-
};
|
|
144
|
+
} | null;
|
|
111
145
|
export declare const useDraggable: () => {
|
|
112
146
|
new (target: gsap.DOMTarget, vars?: Draggable.Vars): {
|
|
113
147
|
readonly autoScroll: number;
|
|
@@ -160,7 +194,7 @@ export declare const useDraggable: () => {
|
|
|
160
194
|
get(target: gsap.DOMTarget): Draggable;
|
|
161
195
|
hitTest(testObject1: Draggable.TestObject, testObject2: Draggable.TestObject, threshold?: number | string): boolean;
|
|
162
196
|
timeSinceDrag(): number;
|
|
163
|
-
};
|
|
197
|
+
} | null;
|
|
164
198
|
export declare const useFlip: () => {
|
|
165
199
|
new (): {};
|
|
166
200
|
readonly version: string;
|
|
@@ -175,10 +209,10 @@ export declare const useFlip: () => {
|
|
|
175
209
|
killFlipsOf(targets: gsap.DOMTarget, complete?: boolean): void;
|
|
176
210
|
makeAbsolute(targets: gsap.DOMTarget | Flip.FlipState[]): Element[];
|
|
177
211
|
to(state: Flip.FlipState, vars?: Flip.FromToVars): gsap.core.Timeline;
|
|
178
|
-
register(core: typeof gsap): void;
|
|
212
|
+
register(core: typeof globalThis.gsap): void;
|
|
179
213
|
ElementState: typeof Flip.ElementState;
|
|
180
214
|
FlipState: typeof Flip.FlipState;
|
|
181
|
-
};
|
|
215
|
+
} | null;
|
|
182
216
|
export declare const useObserver: () => {
|
|
183
217
|
new (): {
|
|
184
218
|
readonly deltaX: number;
|
|
@@ -210,14 +244,14 @@ export declare const useObserver: () => {
|
|
|
210
244
|
create(vars: Observer.ObserverVars): Observer;
|
|
211
245
|
getAll(): Observer[];
|
|
212
246
|
getById(id: string): Observer | undefined;
|
|
213
|
-
};
|
|
247
|
+
} | null;
|
|
214
248
|
export declare const useGSDevTools: () => {
|
|
215
249
|
new (target: gsap.DOMTarget, vars?: GSDevTools.Vars): {
|
|
216
250
|
kill(): void;
|
|
217
251
|
};
|
|
218
252
|
create(vars?: GSDevTools.Vars): GSDevTools;
|
|
219
253
|
getById(id: string): GSDevTools | null;
|
|
220
|
-
};
|
|
254
|
+
} | null;
|
|
221
255
|
export declare const useCustomEase: () => {
|
|
222
256
|
new (id: string, data?: string | number[], config?: CustomEaseConfig): {
|
|
223
257
|
id: string;
|
|
@@ -231,18 +265,19 @@ export declare const useCustomEase: () => {
|
|
|
231
265
|
register(core: object): void;
|
|
232
266
|
get(id: string): EaseFunction;
|
|
233
267
|
getSVGData(ease: CustomEase | EaseFunction | string, config?: CustomEaseConfig): string;
|
|
234
|
-
};
|
|
268
|
+
} | null;
|
|
235
269
|
export declare const useCustomWiggle: () => {
|
|
236
270
|
new (id: string, vars?: CustomWiggleVars): {
|
|
237
271
|
ease: EaseFunction;
|
|
238
272
|
};
|
|
239
273
|
create(id: string, vars?: CustomWiggleVars): EaseFunction;
|
|
240
274
|
register(core: object): void;
|
|
241
|
-
};
|
|
275
|
+
} | null;
|
|
242
276
|
export declare const useCustomBounce: () => {
|
|
243
277
|
new (id: string, vars?: CustomBounceVars): {
|
|
244
278
|
ease: EaseFunction;
|
|
245
279
|
};
|
|
246
280
|
create(id: string, vars?: CustomBounceVars): EaseFunction;
|
|
247
281
|
register(core: object): void;
|
|
248
|
-
};
|
|
282
|
+
} | null;
|
|
283
|
+
export {};
|
|
@@ -1,4 +1,41 @@
|
|
|
1
|
+
import { gsap } from "gsap";
|
|
2
|
+
import { onMounted, onScopeDispose, watch } from "vue";
|
|
1
3
|
import { createGsapComposable } from "../create-gsap-composable.js";
|
|
4
|
+
export function useGsap(setup, options) {
|
|
5
|
+
if (!setup) return gsap;
|
|
6
|
+
if (import.meta.server) {
|
|
7
|
+
return { contextSafe: (fn) => fn };
|
|
8
|
+
}
|
|
9
|
+
let ctx = null;
|
|
10
|
+
const runSetup = () => {
|
|
11
|
+
const scope = options?.scope?.value ?? void 0;
|
|
12
|
+
ctx = gsap.context(setup, scope);
|
|
13
|
+
};
|
|
14
|
+
onMounted(() => {
|
|
15
|
+
runSetup();
|
|
16
|
+
});
|
|
17
|
+
if (options?.dependencies !== void 0) {
|
|
18
|
+
const deps = Array.isArray(options.dependencies) ? options.dependencies : [options.dependencies];
|
|
19
|
+
watch(deps, () => {
|
|
20
|
+
if (options.revertOnUpdate === false) return;
|
|
21
|
+
ctx?.revert();
|
|
22
|
+
runSetup();
|
|
23
|
+
}, { flush: "post" });
|
|
24
|
+
}
|
|
25
|
+
onScopeDispose(() => {
|
|
26
|
+
ctx?.revert();
|
|
27
|
+
ctx = null;
|
|
28
|
+
});
|
|
29
|
+
const contextSafe = (fn) => {
|
|
30
|
+
return ((...args) => {
|
|
31
|
+
if (ctx) {
|
|
32
|
+
return ctx.add(() => fn(...args));
|
|
33
|
+
}
|
|
34
|
+
return fn(...args);
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
return { contextSafe };
|
|
38
|
+
}
|
|
2
39
|
export const useScrollTrigger = createGsapComposable("ScrollTrigger");
|
|
3
40
|
export const useScrollSmoother = createGsapComposable("ScrollSmoother");
|
|
4
41
|
export const useSplitText = createGsapComposable("SplitText");
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Factory
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Factory that creates a composable returning a registered GSAP plugin.
|
|
3
|
+
*
|
|
4
|
+
* The returned composable reads the plugin from `nuxtApp` at call time.
|
|
5
|
+
* Returns `null` during SSR (plugin is client-only).
|
|
6
|
+
* Throws on the client if the plugin was not enabled in `nuxt.config.ts`.
|
|
7
|
+
*
|
|
8
|
+
* **Cleanup is the caller's responsibility.**
|
|
9
|
+
* Destroy instances created from the plugin (e.g. `Draggable`, `ScrollTrigger`)
|
|
10
|
+
* in `onUnmounted` to avoid memory leaks.
|
|
11
|
+
*
|
|
12
|
+
* @param pluginName - Name of the GSAP plugin as registered in nuxtApp.
|
|
13
|
+
* @param fallbackMessage - Optional custom error message for missing plugin.
|
|
5
14
|
*/
|
|
6
|
-
export declare function createGsapComposable<T>(pluginName: string, fallbackMessage?: string): () => T;
|
|
15
|
+
export declare function createGsapComposable<T>(pluginName: string, fallbackMessage?: string): () => T | null;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { loadDraggable, loadFlip, loadObserver } from "./gsap-loaders.js";
|
|
1
2
|
export const gsapPlugins = {
|
|
2
3
|
// Scroll Plugins
|
|
3
4
|
ScrollTrigger: () => import("gsap/ScrollTrigger").then((mod) => mod.ScrollTrigger),
|
|
@@ -13,10 +14,10 @@ export const gsapPlugins = {
|
|
|
13
14
|
MotionPathPlugin: () => import("gsap/MotionPathPlugin").then((mod) => mod.MotionPathPlugin),
|
|
14
15
|
MotionPathHelper: () => import("gsap/MotionPathHelper").then((mod) => mod.MotionPathHelper),
|
|
15
16
|
// UI Plugins
|
|
16
|
-
Flip: () =>
|
|
17
|
-
Draggable: () =>
|
|
17
|
+
Flip: () => loadFlip().then((mod) => mod.Flip),
|
|
18
|
+
Draggable: () => loadDraggable().then((mod) => mod.Draggable),
|
|
18
19
|
InertiaPlugin: () => import("gsap/InertiaPlugin").then((mod) => mod.InertiaPlugin),
|
|
19
|
-
Observer: () =>
|
|
20
|
+
Observer: () => loadObserver().then((mod) => mod.Observer),
|
|
20
21
|
// Other Plugins
|
|
21
22
|
PixiPlugin: () => import("gsap/PixiPlugin").then((mod) => mod.PixiPlugin),
|
|
22
23
|
EaselPlugin: () => import("gsap/EaselPlugin").then((mod) => mod.EaselPlugin),
|
package/dist/runtime/plugin.js
CHANGED
|
@@ -1,37 +1,41 @@
|
|
|
1
1
|
import { gsap } from "gsap";
|
|
2
2
|
import { gsapPlugins } from "./gsap-plugins.js";
|
|
3
3
|
import { defineNuxtPlugin, useRuntimeConfig } from "#app";
|
|
4
|
-
export default defineNuxtPlugin(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (!loader) {
|
|
25
|
-
throw new Error(
|
|
26
|
-
`[gsap-nuxt-module] Plugin "${pluginName}" not found. Available plugins: ${Object.keys(gsapPlugins).join(", ")}`
|
|
27
|
-
);
|
|
4
|
+
export default defineNuxtPlugin({
|
|
5
|
+
name: "gsap-nuxt-module",
|
|
6
|
+
enforce: "post",
|
|
7
|
+
setup: async (nuxtApp) => {
|
|
8
|
+
const config = useRuntimeConfig().public.gsap;
|
|
9
|
+
const pluginsToRegister = new Set(config.plugins || []);
|
|
10
|
+
const pluginDependencies = {
|
|
11
|
+
ScrollSmoother: ["ScrollTrigger"],
|
|
12
|
+
CustomWiggle: ["CustomEase"],
|
|
13
|
+
CustomBounce: ["CustomEase"]
|
|
14
|
+
};
|
|
15
|
+
const resolvedPlugins = /* @__PURE__ */ new Set();
|
|
16
|
+
const resolvePlugin = (plugin) => {
|
|
17
|
+
if (resolvedPlugins.has(plugin)) return;
|
|
18
|
+
const deps = pluginDependencies[plugin] || [];
|
|
19
|
+
deps.forEach(resolvePlugin);
|
|
20
|
+
resolvedPlugins.add(plugin);
|
|
21
|
+
};
|
|
22
|
+
for (const plugin of pluginsToRegister) {
|
|
23
|
+
resolvePlugin(plugin);
|
|
28
24
|
}
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
for (const pluginName of resolvedPlugins) {
|
|
26
|
+
const loader = gsapPlugins[pluginName];
|
|
27
|
+
if (!loader) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
`[gsap-nuxt-module] Plugin "${pluginName}" not found. Available plugins: ${Object.keys(gsapPlugins).join(", ")}`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const plugin = await loader();
|
|
34
|
+
gsap.registerPlugin(plugin);
|
|
35
|
+
nuxtApp.provide(pluginName, plugin);
|
|
36
|
+
} catch (err) {
|
|
37
|
+
console.error(`[gsap-nuxt-module] Failed to load plugin "${pluginName}":`, err);
|
|
38
|
+
}
|
|
35
39
|
}
|
|
36
40
|
}
|
|
37
41
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gsap-nuxt-module",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"description": "GSAP integration for Nuxt.",
|
|
5
5
|
"repository": "LucaArgentieri/gsap-nuxt-module",
|
|
6
6
|
"author": "Luca Argentieri",
|
|
@@ -29,26 +29,27 @@
|
|
|
29
29
|
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
|
|
30
30
|
"release": "npm run lint && npm run prepack && changelogen --release --patch && npm publish && git push --follow-tags",
|
|
31
31
|
"lint": "eslint .",
|
|
32
|
+
"lint:fix": "eslint . --fix",
|
|
32
33
|
"test": "vitest run",
|
|
33
34
|
"test:watch": "vitest watch",
|
|
34
|
-
"test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
|
|
35
|
+
"test:types": "vue-tsc --noEmit && nuxi prepare playground && cd playground && vue-tsc --noEmit"
|
|
35
36
|
},
|
|
36
37
|
"dependencies": {
|
|
37
|
-
"@nuxt/kit": "^
|
|
38
|
+
"@nuxt/kit": "^4.0.0",
|
|
38
39
|
"gsap": "^3.14.2"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
|
-
"@nuxt/devtools": "^
|
|
42
|
+
"@nuxt/devtools": "^3.0.0",
|
|
42
43
|
"@nuxt/eslint-config": "^1.1.0",
|
|
43
44
|
"@nuxt/module-builder": "^1.0.1",
|
|
44
|
-
"@nuxt/schema": "^
|
|
45
|
-
"@nuxt/test-utils": "^
|
|
45
|
+
"@nuxt/schema": "^4.0.0",
|
|
46
|
+
"@nuxt/test-utils": "^4.0.0",
|
|
46
47
|
"@types/node": "latest",
|
|
47
48
|
"changelogen": "^0.6.0",
|
|
48
|
-
"eslint": "^
|
|
49
|
-
"nuxt": "^
|
|
49
|
+
"eslint": "^10.0.0",
|
|
50
|
+
"nuxt": "^4.0.0",
|
|
50
51
|
"typescript": "^5.9.3",
|
|
51
|
-
"vitest": "^
|
|
52
|
-
"vue-tsc": "^
|
|
52
|
+
"vitest": "^4.0.0",
|
|
53
|
+
"vue-tsc": "^3.0.0"
|
|
53
54
|
}
|
|
54
55
|
}
|