gclass-anims 1.0.0-beta.1

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/Config.js ADDED
@@ -0,0 +1,160 @@
1
+ import {
2
+ bounce, expandH, expandV, shake, SpawnH, SpawnV, spawnSpinCCW, spawnSpinCW,
3
+ spinCCW, spinCW, expandA, typewriter, bell, spawnBlur, spawnFade, spawnXDown,
4
+ spawnXUp, spawnYRight, spawnYLeft, pulse, radiate, hover, expandRight,
5
+ expandLeft, expandUp, expandDown, marquee, countUp,
6
+ spawnClipReveal, curtainHorizontal, curtainVertical,
7
+ } from './Animations.js'
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // GClass configuration — THE single place to add / remove / tweak animations.
11
+ //
12
+ // `animations` is an array of entries. Each entry is a plain object; the engine
13
+ // inspects which fields are present and wires up the matching behaviour
14
+ // automatically — no engine edits needed:
15
+ //
16
+ // sel - the className you put on elements (e.g. ".spawn-up")
17
+ //
18
+ // play - (el, delay, dur, ease) => tween|timeline. The entrance
19
+ // (load / appear / scroll-enter) animation. When present, the
20
+ // entry is treated as a "spawn" and AUTOMATICALLY gets:
21
+ // • `.order` / `priority-*` / `reverse` ordering
22
+ // • `time-*` duration, `ease-*`, `delay` support
23
+ // • `.scroll` + `.scroll-progress` ScrollTrigger versions
24
+ // • `.appear` for dynamically-added elements
25
+ // • `.leave` reverse exit
26
+ // • a `.spawn-text-<name>` SplitText variant (unless text:false)
27
+ //
28
+ // from - optional. The hidden starting state ({ opacity: 0, ... }).
29
+ // Required if you want leave/scroll reversal to look right.
30
+ //
31
+ // typewriter - optional true. Marks the entry as a text typewriter (TextPlugin)
32
+ // typewriterSplit - optional true. Per-part "typed" reveal (see playText)
33
+ //
34
+ // build - (el, ctx) => tween|timeline. A looping animation. When present
35
+ // the entry is ALSO treated as a "loop": it runs `.repeat(-1)` on
36
+ // load and enables `hover-<name>` / `click-<name>` triggers.
37
+ // key - optional. Storage key on the element (defaults to `sel`).
38
+ //
39
+ // loop - optional boolean. Set false to keep `build` but skip the
40
+ // always-on repeat (hover/click only).
41
+ //
42
+ // text - optional boolean (default true). Set false to skip generating
43
+ // the `.spawn-text-<name>` SplitText variant.
44
+ //
45
+ // setup - optional (el, ctx) => void | teardownFn. A "special abilities"
46
+ // hook called once for every matching element when it's first
47
+ // wired up. Use it for custom behaviour (observers, listeners,
48
+ // timers, DOM state) that doesn't fit the scroll/order machinery.
49
+ // If it RETURNS a function, that function is invoked during
50
+ // engine teardown to clean up side-effects.
51
+ //
52
+ // Add an entry -> it just works. Remove an entry -> it disappears everywhere.
53
+ // ---------------------------------------------------------------------------
54
+
55
+ export const defaults = {
56
+ orderDivide: 5,
57
+ spawnDelayMultiplier: 0.2,
58
+ spawnOffset: 20,
59
+ clickOffset: 10,
60
+ clickExpandOffset: 15,
61
+ clickDuration: 0.2,
62
+ ease: "back",
63
+ effectDelay: 0.5,
64
+ effectDuration: 1,
65
+ effectOffset: 20,
66
+ progressStart: "top bottom",
67
+ progressEnd: "center center",
68
+ textStagger: 0.03,
69
+ typewriterSplitCharDuration: 0.05,
70
+ minTextPartDuration: 0.3,
71
+ }
72
+
73
+ export const animations = [
74
+ // --- Spawn / entrance (from + play) --------------------------------------
75
+ { sel: ".spawn-down", from: { opacity: 0, y: -defaults.spawnOffset }, play: (el, delay, dur, ease) => SpawnV(el, delay, -defaults.spawnOffset, dur, ease) },
76
+ { sel: ".spawn-up", from: { opacity: 0, y: defaults.spawnOffset }, play: (el, delay, dur, ease) => SpawnV(el, delay, defaults.spawnOffset, dur, ease) },
77
+ { sel: ".spawn-left", from: { opacity: 0, x: -defaults.spawnOffset }, play: (el, delay, dur, ease) => SpawnH(el, delay, -defaults.spawnOffset, dur, ease) },
78
+ { sel: ".spawn-right", from: { opacity: 0, x: defaults.spawnOffset }, play: (el, delay, dur, ease) => SpawnH(el, delay, defaults.spawnOffset, dur, ease) },
79
+ { sel: ".spawn-cw", from: { scale: 0, rotation: -360 }, play: (el, delay, dur, ease) => spawnSpinCW(el, delay, dur, ease) },
80
+ { sel: ".spawn-ccw", from: { scale: 0, rotation: 360 }, play: (el, delay, dur, ease) => spawnSpinCCW(el, delay, dur, ease) },
81
+ { sel: ".spawn-fade", from: { opacity: 0 }, play: (el, delay, dur, ease) => spawnFade(el, delay, dur, ease) },
82
+ { sel: ".spawn-blur", from: { opacity: 0, filter: "blur(20px)" }, play: (el, delay, dur, ease) => spawnBlur(el, delay, dur, ease) },
83
+ { sel: ".spawn-x-down", from: { scale: 0, rotationX: -360 }, play: (el, delay, dur, ease) => spawnXDown(el, delay, dur, ease) },
84
+ { sel: ".spawn-x-up", from: { scale: 0, rotationX: 360 }, play: (el, delay, dur, ease) => spawnXUp(el, delay, dur, ease) },
85
+ { sel: ".spawn-y-right", from: { scale: 0, rotationY: -360 }, play: (el, delay, dur, ease) => spawnYRight(el, delay, dur, ease) },
86
+ { sel: ".spawn-y-left", from: { scale: 0, rotationY: 360 }, play: (el, delay, dur, ease) => spawnYLeft(el, delay, dur, ease) },
87
+ { sel: ".expand-vertical", from: { opacity: 0, scaleY: 0 }, play: (el, delay, dur, ease) => expandV(el, delay, dur, ease) },
88
+ { sel: ".expand-horizontal", from: { opacity: 0, scaleX: 0 }, play: (el, delay, dur, ease) => expandH(el, delay, dur, ease) },
89
+ { sel: ".expand-right", from: { opacity: 0, scaleX: 0 }, play: (el, delay, dur, ease) => expandRight(el, delay, dur, ease) },
90
+ { sel: ".expand-left", from: { opacity: 0, scaleX: 0 }, play: (el, delay, dur, ease) => expandLeft(el, delay, dur, ease) },
91
+ { sel: ".expand-up", from: { opacity: 0, scaleY: 0 }, play: (el, delay, dur, ease) => expandUp(el, delay, dur, ease) },
92
+ { sel: ".expand-down", from: { opacity: 0, scaleY: 0 }, play: (el, delay, dur, ease) => expandDown(el, delay, dur, ease) },
93
+ { sel: ".expand-all", from: { opacity: 0, scale: 0 }, play: (el, delay, dur, ease) => expandA(el, delay, dur, ease) },
94
+ { sel: ".typewriter", typewriter: true, from: { text: "" }, play: (el, delay, dur, ease) => typewriter(el, el.innerHTML, dur, delay, ease) },
95
+ { sel: ".typewriter-split", typewriter: true, typewriterSplit: true, from: { opacity: 0 }, play: (el, delay, dur, ease) => null },
96
+
97
+ // Custom-function animation: counts from the `.spawn-num-N` value (N = the
98
+ // starting number) up to whatever number is in the element (falling back to 0
99
+ // when no `.spawn-num-N` class is present). `play` just wraps a helper from
100
+ // Animations.js — nothing else is special, so it still gets
101
+ // order/scroll/leave/appear automatically.
102
+ { sel: ".count", count: true, text: false, from: { opacity: 0 }, play: (el, delay, dur, ease) => countUp(el, delay, dur, ease) },
103
+
104
+ // Pure clip-path reveals. `text:false` so the SplitText per-char variant is
105
+ // skipped (these are meant for media/containers). The `from` inset is mirrored
106
+ // in each helper so scroll/scroll-progress/appear/leave all know the hidden state.
107
+ { sel: ".clip-reveal-up", text: false, from: { clipPath: "inset(0% 0% 100% 0%)" }, play: (el, delay, dur, ease) => spawnClipReveal(el, delay, dur, ease, "up") },
108
+ { sel: ".clip-reveal-down", text: false, from: { clipPath: "inset(100% 0% 0% 0%)" }, play: (el, delay, dur, ease) => spawnClipReveal(el, delay, dur, ease, "down") },
109
+ { sel: ".clip-reveal-left", text: false, from: { clipPath: "inset(0% 0% 0% 100%)" }, play: (el, delay, dur, ease) => spawnClipReveal(el, delay, dur, ease, "left") },
110
+ { sel: ".clip-reveal-right", text: false, from: { clipPath: "inset(0% 100% 0% 0%)" }, play: (el, delay, dur, ease) => spawnClipReveal(el, delay, dur, ease, "right") },
111
+ // Backwards-compatible alias for the original class: reveals from the bottom
112
+ // edge upward (same as `.clip-reveal-up`).
113
+ { sel: ".clip-reveal", text: false, from: { clipPath: "inset(0% 0% 100% 0%)" }, play: (el, delay, dur, ease) => spawnClipReveal(el, delay, dur, ease, "up") },
114
+ { sel: ".curtain-horizontal", text: false, from: { clipPath: "inset(0% 50% 0% 50%)" }, play: (el, delay, dur, ease) => curtainHorizontal(el, delay, dur, ease) },
115
+ { sel: ".curtain-vertical", text: false, from: { clipPath: "inset(50% 0% 50% 0%)" }, play: (el, delay, dur, ease) => curtainVertical(el, delay, dur, ease) },
116
+
117
+
118
+ // --- Loops (build + key). Also usable via hover-<name>/click-<name> ---------
119
+ { sel: ".shake", build: (el, { edelay, amount, etime, ease }) => shake(edelay, el, amount, etime, ease), key: "shakeanim" },
120
+ { sel: ".spin-cw", build: (el, { edelay, etime, ease }) => spinCW(el, edelay, etime, ease), key: "spinCW" },
121
+ { sel: ".spin-ccw", build: (el, { edelay, etime, ease }) => spinCCW(el, edelay, etime, ease), key: "spinCW" },
122
+ { sel: ".bounce", build: (el, { edelay, amount, etime, ease }) => bounce(edelay, el, amount, etime, ease), key: "bounce" },
123
+ { sel: ".bell", build: (el, { edelay, amount, etime, ease }) => bell(edelay, el, amount, etime, ease), key: "bell" },
124
+ { sel: ".pulse", build: (el, { edelay, amount, etime, ease }) => pulse(edelay, el, amount, etime, ease), key: "pulse" },
125
+ { sel: ".radiate", build: (el, { edelay, amount, etime, ease, radiateZ }) => radiate(edelay, el, amount, etime, ease, radiateZ), key: "radiate" },
126
+ { sel: ".float", build: (el, { edelay, amount, etime, ease }) => hover(edelay, el, amount, etime, ease), key: "float" },
127
+ { sel: ".marquee-left", build: (el, ctx) => marquee(el, "left", ctx.time, ctx.mH, ctx.mV, el.classList.contains("marquee-no-repeat")), key: "marquee" },
128
+ { sel: ".marquee-right", build: (el, ctx) => marquee(el, "right", ctx.time, ctx.mH, ctx.mV, el.classList.contains("marquee-no-repeat")), key: "marquee" },
129
+ { sel: ".marquee-up", build: (el, ctx) => marquee(el, "up", ctx.time, ctx.mH, ctx.mV, el.classList.contains("marquee-no-repeat")), key: "marquee" },
130
+ { sel: ".marquee-down", build: (el, ctx) => marquee(el, "down", ctx.time, ctx.mH, ctx.mV, el.classList.contains("marquee-no-repeat")), key: "marquee" },
131
+ ]
132
+
133
+ // The engine needs a couple of derived views of the config. Rather than
134
+ // hardcode two parallel arrays, it normalises once here:
135
+ // spawnConfigs - entries with a `play` (entrance/spawn machinery)
136
+ // loopConfigs - entries with a `build` (loop machinery)
137
+ // `extra` is any user-supplied array merged in (see CustomAnims.js).
138
+ export function normalize(extra = []) {
139
+ const all = animations.concat(extra)
140
+ const spawnConfigs = all
141
+ .filter((a) => a.play)
142
+ .map((a) => ({
143
+ sel: a.sel,
144
+ from: a.from,
145
+ play: a.play,
146
+ typewriter: a.typewriter,
147
+ typewriterSplit: a.typewriterSplit,
148
+ text: a.text !== false,
149
+ count: a.count,
150
+ }))
151
+ const loopConfigs = all
152
+ .filter((a) => a.build)
153
+ .map((a) => ({
154
+ sel: a.sel,
155
+ build: a.build,
156
+ key: a.key || a.sel.slice(1),
157
+ loop: a.loop !== false,
158
+ }))
159
+ return { all, spawnConfigs, loopConfigs }
160
+ }
package/CustomAnims.js ADDED
@@ -0,0 +1,56 @@
1
+ import gsap from "gsap";
2
+
3
+ // A custom animation is just an entry with the SAME shape as one in
4
+ // Listeners.js' `spawnConfigs`. Give it:
5
+ //
6
+ // sel - the className you'll put on elements (e.g. ".whirl")
7
+ // from - the hidden starting state (opacity/scale/x/y/filter/...). This is
8
+ // required if you want `.leave` reverse + `.scroll` / `scroll-progress`
9
+ // to work automatically. Skip it for a one-shot timeline.
10
+ // play - (el, delay, dur, ease) => a GSAP tween OR timeline to run.
11
+ //
12
+ // Because Listeners.js reuses its existing machinery, anything you add here
13
+ // gets the full feature set (scroll, leave, order, delays, ease-*, time-*, ...)
14
+ // with zero extra code.
15
+
16
+ export const customAnims = [
17
+ // --------------------------------------------------------------------------
18
+ // 1. A simple custom tween. `from` + `computeTo` give you leave/scroll reverse.
19
+ // Works just like `.spawn-up` but with a custom transform.
20
+ // --------------------------------------------------------------------------
21
+ {
22
+ sel: ".whirl",
23
+ from: { opacity: 0, rotation: 90, scale: 0.7 },
24
+ play: (el, delay, dur, ease) =>
25
+ gsap.fromTo(
26
+ el,
27
+ { opacity: 0, rotation: 90, scale: 0.7 },
28
+ { ease, duration: dur, delay, rotation: 0, scale: 1, opacity: 1, transformOrigin: "center" }
29
+ ),
30
+ },
31
+
32
+ // --------------------------------------------------------------------------
33
+ // 2. A timeline-based custom animation. Build a gsap.timeline and return it.
34
+ // Add a `from` too if you want leave/scroll reversal to look right.
35
+ // --------------------------------------------------------------------------
36
+ {
37
+ sel: ".bounce-in",
38
+ from: { opacity: 0, scale: 0 },
39
+ play: (el, delay, dur, ease) => {
40
+ const tl = gsap.timeline({
41
+ delay,
42
+ defaults: { ease, duration: dur / 3 },
43
+ });
44
+ tl.fromTo(el, { scale: 0, opacity: 0 }, { scale: 1.1, opacity: 1 })
45
+ .to(el, { scale: 0.95 })
46
+ .to(el, { scale: 1 });
47
+ return tl;
48
+ },
49
+ },
50
+ ];
51
+
52
+ // Example: how one would expose a manual helper (no listener integration,
53
+ // call it directly from your own code).
54
+ export function Example(target, customVars) {
55
+ return gsap.to(target, customVars);
56
+ }
package/LICENSE ADDED
@@ -0,0 +1,35 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Saturn-sepehr
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---
24
+
25
+ Third-party notice
26
+
27
+ This project depends on GSAP (GreenSock Animation Platform), which is NOT
28
+ covered by the MIT license above and is distributed separately.
29
+
30
+ GSAP is used under the Webflow Standard No-Charge GSAP License and is installed
31
+ as a dependency from npm. GSAP remains the property of Webflow, Inc. / GreenSock
32
+ and is subject to its own license terms, which take precedence over this MIT
33
+ license with respect to GSAP itself.
34
+
35
+ See https://gsap.com/standard-license/ for the applicable GSAP terms.