mirror of
https://github.com/nexu-io/open-design.git
synced 2026-05-31 19:04:39 +07:00
skills: fix GSAP review follow-ups (#3111)
This commit is contained in:
parent
1083df8769
commit
e9944e0783
2 changed files with 10 additions and 38 deletions
|
|
@ -33,7 +33,7 @@ Apply when writing or reviewing GSAP code in Vue (or Nuxt), Svelte (or SvelteKit
|
|||
|
||||
## Vue 3 (Composition API)
|
||||
|
||||
See `examples/vue/` for a runnable Vite + Vue 3 project demonstrating these patterns.
|
||||
For a runnable Vite + Vue 3 project demonstrating these patterns, see the upstream example at https://github.com/greensock/gsap-skills/tree/main/examples/vue.
|
||||
|
||||
Use **onMounted** to run GSAP after the component is in the DOM. Use **onUnmounted** to clean up.
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ onUnmounted(() => {
|
|||
|
||||
## Nuxt 4
|
||||
|
||||
> See `examples/nuxt/` for a runnable Nuxt 4 project with plugin registration, lazy loading, and SSR-safe patterns.
|
||||
> For a runnable Nuxt 4 project with plugin registration, lazy loading, and SSR-safe patterns, see https://github.com/greensock/gsap-skills/tree/main/examples/nuxt.
|
||||
|
||||
Use a **reusable composable** to register GSAP Plugins and also to lazy load Plugins that are not extensively used in your application:
|
||||
|
||||
|
|
@ -113,35 +113,6 @@ Use a **reusable composable** to register GSAP Plugins and also to lazy load Plu
|
|||
import { gsap } from "gsap";
|
||||
import { ScrollTrigger } from "gsap/ScrollTrigger";
|
||||
|
||||
const PLUGINS = [
|
||||
"CSSRulePlugin",
|
||||
"CustomBounce",
|
||||
"CustomEase",
|
||||
"CustomWiggle",
|
||||
"Draggable",
|
||||
"DrawSVGPlugin",
|
||||
"EaselPlugin",
|
||||
"EasePack",
|
||||
"Flip",
|
||||
"GSDevTools",
|
||||
"InertiaPlugin",
|
||||
"MorphSVGPlugin",
|
||||
"MotionPathHelper",
|
||||
"MotionPathPlugin",
|
||||
"Observer",
|
||||
"Physics2DPlugin",
|
||||
"PhysicsPropsPlugin",
|
||||
"PixiPlugin",
|
||||
"ScrambleTextPlugin",
|
||||
"ScrollSmoother",
|
||||
"ScrollToPlugin",
|
||||
"ScrollTrigger",
|
||||
"SplitText",
|
||||
"TextPlugin",
|
||||
] as const;
|
||||
|
||||
type Plugins = (typeof PLUGINS)[number];
|
||||
|
||||
// In order to dynamically load all the GSAP plugins
|
||||
const pluginMap = {
|
||||
CustomEase: () => import("gsap/CustomEase"),
|
||||
|
|
@ -171,12 +142,12 @@ const pluginMap = {
|
|||
} as const;
|
||||
|
||||
type PluginMap = typeof pluginMap;
|
||||
type Plugins = keyof PluginMap;
|
||||
type LoadablePlugin = keyof PluginMap;
|
||||
|
||||
// Resolves the module type for a given key, then picks the named export matching the key
|
||||
// this allows to have the type definitions for autocomplete in your code editor
|
||||
type PluginModule<K extends Plugins> = Awaited<ReturnType<PluginMap[K]>>;
|
||||
type PluginExport<K extends Plugins> = PluginModule<K>[K & keyof PluginModule<K>];
|
||||
type PluginModule<K extends LoadablePlugin> = Awaited<ReturnType<PluginMap[K]>>;
|
||||
type PluginExport<K extends LoadablePlugin> = PluginModule<K>[K & keyof PluginModule<K>];
|
||||
|
||||
export default function () {
|
||||
// Register all the GSAP Plugins you want at this point
|
||||
|
|
@ -187,7 +158,7 @@ export default function () {
|
|||
not widely used in your app (for example in just a couple
|
||||
of components or a single route), you can use this method
|
||||
*/
|
||||
async function lazyLoadPlugin<K extends Plugins>(plugin: K): Promise<PluginExport<K>> {
|
||||
async function lazyLoadPlugin<K extends LoadablePlugin>(plugin: K): Promise<PluginExport<K>> {
|
||||
const loader = pluginMap[plugin];
|
||||
const m = await loader();
|
||||
const p = (m as any)[plugin];
|
||||
|
|
|
|||
|
|
@ -245,13 +245,15 @@ A common pattern: **pin** a section, then as the user scrolls **vertically**, co
|
|||
const scrollingEl = document.querySelector(".horizontal-el");
|
||||
// Panel = pinned viewport-sized section. .horizontal-wrap = inner content that moves left.
|
||||
const scrollTween = gsap.to(scrollingEl, {
|
||||
xPercent: () => Max.max(0, window.innerWidth - scrollingEl.offsetWidth),
|
||||
x: () => Math.min(0, window.innerWidth - scrollingEl.scrollWidth),
|
||||
ease: "none", // ease: "none" is required
|
||||
scrollTrigger: {
|
||||
trigger: scrollingEl,
|
||||
pin: scrollingEl.parentNode, // wrapper so that we're not animating the pinned element
|
||||
start: "top top",
|
||||
end: "+=1000"
|
||||
end: () => `+=${Math.max(0, scrollingEl.scrollWidth - window.innerWidth)}`,
|
||||
invalidateOnRefresh: true,
|
||||
scrub: true
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -306,4 +308,3 @@ In React, use the `useGSAP()` hook (@gsap/react NPM package) to ensure proper cl
|
|||
### Learn More
|
||||
|
||||
https://gsap.com/docs/v3/Plugins/ScrollTrigger/
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue