gclass-anims 1.0.0-beta.20 → 1.0.0-beta.21
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/AnimToggle.js +77 -5
- package/Animations.js +2 -2
- package/CHANGELOG.md +3 -0
- package/Listeners.js +118 -46
- package/index.d.ts +27 -3
- package/index.js +1 -1
- package/package.json +1 -1
package/AnimToggle.js
CHANGED
|
@@ -118,6 +118,57 @@ let bootTimeout = null
|
|
|
118
118
|
let bootStyle = null
|
|
119
119
|
let hasBooted = false // true after first hard-load boot, skips boot on SPA path changes (remains false until first boot, resets on hard reload)
|
|
120
120
|
|
|
121
|
+
// Runtime config for gclassOpts — 0 = defaults (no throttle, default GSAP ticker)
|
|
122
|
+
let currentThrottle = 0
|
|
123
|
+
let currentFps = 0
|
|
124
|
+
const configSubscribers = new Set()
|
|
125
|
+
function getConfigSnapshot() { return { throttlePerFrame: currentThrottle, fps: currentFps } }
|
|
126
|
+
function emitConfig() { configSubscribers.forEach(fn => fn(getConfigSnapshot())) }
|
|
127
|
+
function applyFps(fps) {
|
|
128
|
+
const v = Number(fps) || 0
|
|
129
|
+
currentFps = v
|
|
130
|
+
if (v > 0) gsap.ticker.fps(v)
|
|
131
|
+
else gsap.ticker.fps(0) // 0 = remove cap, fallback to rAF (GSAP default)
|
|
132
|
+
emitConfig()
|
|
133
|
+
}
|
|
134
|
+
function normalizeGclassArgs(throttlePerFrame, fps) {
|
|
135
|
+
// support gclassOpts({throttlePerFrame, fps}) object overload
|
|
136
|
+
if (typeof throttlePerFrame === 'object' && throttlePerFrame !== null) {
|
|
137
|
+
fps = throttlePerFrame.fps
|
|
138
|
+
throttlePerFrame = throttlePerFrame.throttlePerFrame
|
|
139
|
+
}
|
|
140
|
+
const nextThrottle = throttlePerFrame == null ? 0 : Number(throttlePerFrame) || 0
|
|
141
|
+
const nextFps = fps == null ? 0 : Number(fps) || 0
|
|
142
|
+
return { nextThrottle, nextFps }
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Change GClass runtime options on the fly without reload.
|
|
147
|
+
* gclassOpts(throttlePerFrame, fps) — both optional numbers.
|
|
148
|
+
* gclassOpts() or gclassOpts(undefined, undefined) resets to defaults (no throttle, default ticker).
|
|
149
|
+
* Also accepts gclassOpts({throttlePerFrame, fps}).
|
|
150
|
+
* Example low-end button: onClick={() => gclassOpts(1, 30)}
|
|
151
|
+
* Example reset: onClick={() => gclassOpts()} // 0, 60fps rAF
|
|
152
|
+
*/
|
|
153
|
+
export function gclassOpts(throttlePerFrame, fps) {
|
|
154
|
+
const { nextThrottle, nextFps } = normalizeGclassArgs(throttlePerFrame, fps)
|
|
155
|
+
currentThrottle = nextThrottle
|
|
156
|
+
applyFps(nextFps)
|
|
157
|
+
// re-wire observers with new throttle without full boot reload (if already running)
|
|
158
|
+
if (typeof window !== 'undefined' && cleanup && !bootTimeout) {
|
|
159
|
+
try { cleanup() } catch {}
|
|
160
|
+
cleanup = null
|
|
161
|
+
if (getEnabled()) cleanup = initListeners(document, currentThrottle)
|
|
162
|
+
}
|
|
163
|
+
// if boot is in progress we just store for next initAnimations; if not running, next initAnimations will use stored values
|
|
164
|
+
return getConfigSnapshot()
|
|
165
|
+
}
|
|
166
|
+
export function getGClassConfig() { return getConfigSnapshot() }
|
|
167
|
+
export function subscribeGClassConfig(cb) {
|
|
168
|
+
configSubscribers.add(cb)
|
|
169
|
+
return () => configSubscribers.delete(cb)
|
|
170
|
+
}
|
|
171
|
+
|
|
121
172
|
const readBootTime = (els, fallback) => {
|
|
122
173
|
let max = null
|
|
123
174
|
for (const el of els) {
|
|
@@ -136,7 +187,28 @@ const readBootTime = (els, fallback) => {
|
|
|
136
187
|
// Now also handles boot screen: any HTML/JSX with `.boot-up` anywhere is treated as the boot overlay.
|
|
137
188
|
// No separate initBoot needed - just call initAnimations().
|
|
138
189
|
// Boot stops all DOM rendering for defaults.bootTime (overwritten by boot-time-N class).
|
|
139
|
-
|
|
190
|
+
// throttlePerFrame / fps: forwarded to gclassOpts-equivalent runtime.
|
|
191
|
+
// initAnimations(throttlePerFrame, fps) — positional numbers, 0/undefined = defaults
|
|
192
|
+
// initAnimations({throttlePerFrame, fps}) — object overload
|
|
193
|
+
// initAnimations() — uses last gclassOpts values (defaults on first call)
|
|
194
|
+
export function initAnimations(throttlePerFrame, fps) {
|
|
195
|
+
// gclassOpts-style normalization: (throttle, fps) positional or {throttlePerFrame, fps} object
|
|
196
|
+
// no args -> fallback to last gclassOpts values (defaults 0 = no throttle, default ticker)
|
|
197
|
+
let effThrottle = currentThrottle
|
|
198
|
+
let effFps = currentFps
|
|
199
|
+
if (throttlePerFrame !== undefined || fps !== undefined) {
|
|
200
|
+
const { nextThrottle, nextFps } = normalizeGclassArgs(throttlePerFrame, fps)
|
|
201
|
+
effThrottle = nextThrottle
|
|
202
|
+
effFps = nextFps
|
|
203
|
+
currentThrottle = effThrottle
|
|
204
|
+
currentFps = effFps
|
|
205
|
+
if (effFps > 0) gsap.ticker.fps(effFps)
|
|
206
|
+
else gsap.ticker.fps(0)
|
|
207
|
+
emitConfig()
|
|
208
|
+
} else {
|
|
209
|
+
if (effFps > 0) gsap.ticker.fps(effFps)
|
|
210
|
+
else gsap.ticker.fps(0)
|
|
211
|
+
}
|
|
140
212
|
if (typeof window === 'undefined' || !getEnabled()) return
|
|
141
213
|
// boot already in progress (first mount in StrictMode) - ignore second mount
|
|
142
214
|
if (bootTimeout) {
|
|
@@ -194,7 +266,7 @@ export function initAnimations() {
|
|
|
194
266
|
bootEls.forEach(el => { el.style.visibility = 'visible' })
|
|
195
267
|
|
|
196
268
|
// animations inside boot screen must play while rest of DOM is hidden - init scoped to boot-up
|
|
197
|
-
bootCleanup = initListeners(bootEl)
|
|
269
|
+
bootCleanup = initListeners(bootEl, effThrottle)
|
|
198
270
|
|
|
199
271
|
bootTimeout = setTimeout(() => {
|
|
200
272
|
const bootEndCls = [...bootEl.classList].find(c => c.startsWith('boot-end-'))
|
|
@@ -205,7 +277,7 @@ export function initAnimations() {
|
|
|
205
277
|
bootStyle?.remove(); bootStyle = null
|
|
206
278
|
hideBootEls(bootEls)
|
|
207
279
|
bootTimeout = null
|
|
208
|
-
cleanup = initListeners()
|
|
280
|
+
cleanup = initListeners(document, effThrottle)
|
|
209
281
|
return
|
|
210
282
|
}
|
|
211
283
|
const name = bootEndCls.slice('boot-end-'.length) // e.g. spawn-blur
|
|
@@ -224,7 +296,7 @@ export function initAnimations() {
|
|
|
224
296
|
bootStyle?.remove(); bootStyle = null
|
|
225
297
|
hideBootEls(bootEls)
|
|
226
298
|
bootTimeout = null
|
|
227
|
-
cleanup = initListeners()
|
|
299
|
+
cleanup = initListeners(document, effThrottle)
|
|
228
300
|
}
|
|
229
301
|
|
|
230
302
|
if (!cfg || !from) {
|
|
@@ -238,5 +310,5 @@ export function initAnimations() {
|
|
|
238
310
|
return
|
|
239
311
|
}
|
|
240
312
|
|
|
241
|
-
cleanup = initListeners()
|
|
313
|
+
cleanup = initListeners(document, effThrottle)
|
|
242
314
|
}
|
package/Animations.js
CHANGED
|
@@ -591,7 +591,7 @@ export function radiate (delay , target , amount , dur , ease , zIndex){
|
|
|
591
591
|
tick = true
|
|
592
592
|
requestAnimationFrame(() => { tick = false; applyRect() })
|
|
593
593
|
}
|
|
594
|
-
// Don't animate detached targets
|
|
594
|
+
// Don't animate detached targets - return inert tween
|
|
595
595
|
if (!target.isConnected) {
|
|
596
596
|
return gsap.fromTo(clone, {}, { duration: 0 })
|
|
597
597
|
}
|
|
@@ -609,7 +609,7 @@ export function radiate (delay , target , amount , dur , ease , zIndex){
|
|
|
609
609
|
if (observer) observer.disconnect()
|
|
610
610
|
}
|
|
611
611
|
// If target is removed from DOM (React unmount, .remove(), SPA navigation),
|
|
612
|
-
// kill the tween and remove the clone
|
|
612
|
+
// kill the tween and remove the clone - mirrors React useEffect cleanup
|
|
613
613
|
const observer = new MutationObserver(() => {
|
|
614
614
|
if (!target.isConnected) {
|
|
615
615
|
if (tween) tween.kill()
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `gclass-anims` will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.0.0-beta.21] - 2026-9-3
|
|
6
|
+
- Added a `gclassOpts()` function that controls the animation fps and observer throttling
|
|
7
|
+
|
|
5
8
|
## [1.0.0-beta.20] - 2026-9-2
|
|
6
9
|
- Fix ESM strict import: `AnimToggle.js` and `Listeners.js` now use `.js` extensions (`Remix`/`Qwik` Node ESM `Cannot find module` fix)
|
|
7
10
|
- Fix `Lit` shadow DOM `works.txt` `no` → light DOM default (`createRenderRoot(){return this}`) + `initListeners(shadowRoot)` docs
|
package/Listeners.js
CHANGED
|
@@ -93,7 +93,13 @@ const invokePlay = (config, el, delay, dur, ease) => {
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
export default function initListeners(root = document) {
|
|
96
|
+
export default function initListeners(root = document, throttlePerFrame) {
|
|
97
|
+
// overload: initListeners(1) -> throttle only, root defaults to document
|
|
98
|
+
if (typeof root === 'number') {
|
|
99
|
+
throttlePerFrame = root
|
|
100
|
+
root = document
|
|
101
|
+
}
|
|
102
|
+
throttlePerFrame = Number(throttlePerFrame) || 0 // 0 = no throttling (default)
|
|
97
103
|
gsap.registerPlugin(TextPlugin, ScrollTrigger, SplitText)
|
|
98
104
|
|
|
99
105
|
// helper to scope queries to root (for boot screen: only boot-up subtree animates during boot)
|
|
@@ -1539,38 +1545,28 @@ export default function initListeners(root = document) {
|
|
|
1539
1545
|
// stops the observer<->morph feedback loop.
|
|
1540
1546
|
let flipRoots = new Set()
|
|
1541
1547
|
let flipPendingRaf = null
|
|
1542
|
-
const
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
.forEach((el) => { if (el.isConnected) toFlip.add(el) })
|
|
1565
|
-
})
|
|
1566
|
-
toFlip.forEach(playFlip)
|
|
1567
|
-
// Refresh baselines for any .flip that settled this frame.
|
|
1568
|
-
gsap.utils.toArray(document.body.querySelectorAll?.(".flip") || []).forEach(captureFlip)
|
|
1569
|
-
flipRoots = new Set()
|
|
1570
|
-
})
|
|
1571
|
-
}
|
|
1572
|
-
})
|
|
1573
|
-
flipObserver.observe(document.body, { childList: true, subtree: true })
|
|
1548
|
+
const flushFlipRoots = () => {
|
|
1549
|
+
if (!flipRoots.size) return
|
|
1550
|
+
// A single frame can register several scopes for the SAME
|
|
1551
|
+
// element: removing a `.leave` node re-attaches a fixed ghost
|
|
1552
|
+
// to <body>, which adds `body` as a second scope alongside the
|
|
1553
|
+
// node's former parent. Running animateFlip per scope re-enters
|
|
1554
|
+
// playFlip on the same element, killing the in-flight tween and
|
|
1555
|
+
// clearing its transform - snapping the element into place.
|
|
1556
|
+
// Dedupe across scopes so each element flips exactly once.
|
|
1557
|
+
const toFlip = new Set()
|
|
1558
|
+
flipRoots.forEach((scope) => {
|
|
1559
|
+
if (!scope) return
|
|
1560
|
+
gsap.utils.toArray(scope.querySelectorAll?.(".flip") || [])
|
|
1561
|
+
.forEach((el) => { if (el.isConnected) toFlip.add(el) })
|
|
1562
|
+
})
|
|
1563
|
+
toFlip.forEach(playFlip)
|
|
1564
|
+
// Refresh baselines for any .flip that settled this frame.
|
|
1565
|
+
gsap.utils.toArray(document.body.querySelectorAll?.(".flip") || []).forEach(captureFlip)
|
|
1566
|
+
flipRoots = new Set()
|
|
1567
|
+
}
|
|
1568
|
+
let flipObserver = null
|
|
1569
|
+
// flipObserver is created conditionally below (hub vs direct)
|
|
1574
1570
|
|
|
1575
1571
|
|
|
1576
1572
|
|
|
@@ -1609,7 +1605,23 @@ export default function initListeners(root = document) {
|
|
|
1609
1605
|
}
|
|
1610
1606
|
}
|
|
1611
1607
|
|
|
1612
|
-
|
|
1608
|
+
let appearObserver = null
|
|
1609
|
+
let leaveObserver = null
|
|
1610
|
+
let hubObserver = null
|
|
1611
|
+
let hubRaf = null
|
|
1612
|
+
let hubQueue = []
|
|
1613
|
+
let hubCurrentBatch = null
|
|
1614
|
+
let hubCursor = 0
|
|
1615
|
+
|
|
1616
|
+
const handleFlipBatch = (mutations) => {
|
|
1617
|
+
for (const mutation of mutations) {
|
|
1618
|
+
if (mutation.type !== "childList") continue
|
|
1619
|
+
const target = mutation.target
|
|
1620
|
+
if (target.nodeType !== 1) continue
|
|
1621
|
+
flipRoots.add(target)
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
const handleAppearBatch = (mutations) => {
|
|
1613
1625
|
mutations.forEach((mutation) => {
|
|
1614
1626
|
mutation.addedNodes.forEach((node) => {
|
|
1615
1627
|
if (node.nodeType !== 1) return
|
|
@@ -1639,20 +1651,77 @@ export default function initListeners(root = document) {
|
|
|
1639
1651
|
if (pinned) ScrollTrigger.refresh()
|
|
1640
1652
|
})
|
|
1641
1653
|
})
|
|
1642
|
-
}
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
// Capture any .leave elements already present so they can exit later
|
|
1646
|
-
qAll(".leave").forEach(captureLeave)
|
|
1647
|
-
|
|
1648
|
-
const leaveObserver = new MutationObserver((mutations) => {
|
|
1654
|
+
}
|
|
1655
|
+
const handleLeaveBatch = (mutations) => {
|
|
1649
1656
|
mutations.forEach((mutation) => {
|
|
1650
1657
|
if (mutation.type !== "childList") return
|
|
1651
1658
|
mutation.addedNodes.forEach((n) => collectLeave(n).forEach(captureLeave))
|
|
1652
1659
|
mutation.removedNodes.forEach((n) => collectLeave(n).forEach(playLeave))
|
|
1653
1660
|
})
|
|
1654
|
-
}
|
|
1655
|
-
|
|
1661
|
+
}
|
|
1662
|
+
const hubHandlers = [handleFlipBatch, handleAppearBatch, handleLeaveBatch]
|
|
1663
|
+
const hubDrain = () => {
|
|
1664
|
+
hubRaf = null
|
|
1665
|
+
if (!hubCurrentBatch) {
|
|
1666
|
+
if (!hubQueue.length) return
|
|
1667
|
+
hubCurrentBatch = hubQueue.splice(0, hubQueue.length)
|
|
1668
|
+
hubCursor = 0
|
|
1669
|
+
}
|
|
1670
|
+
const end = Math.min(hubCursor + throttlePerFrame, hubHandlers.length)
|
|
1671
|
+
for (let i = hubCursor; i < end; i++) {
|
|
1672
|
+
hubHandlers[i](hubCurrentBatch)
|
|
1673
|
+
if (hubHandlers[i] === handleFlipBatch) flushFlipRoots()
|
|
1674
|
+
}
|
|
1675
|
+
hubCursor = end
|
|
1676
|
+
if (hubCursor < hubHandlers.length) {
|
|
1677
|
+
hubRaf = requestAnimationFrame(hubDrain)
|
|
1678
|
+
} else {
|
|
1679
|
+
hubCurrentBatch = null
|
|
1680
|
+
hubCursor = 0
|
|
1681
|
+
if (hubQueue.length) hubRaf = requestAnimationFrame(hubDrain)
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
const scheduleHub = () => {
|
|
1685
|
+
if (hubRaf) return
|
|
1686
|
+
hubRaf = requestAnimationFrame(hubDrain)
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
if (throttlePerFrame > 0) {
|
|
1690
|
+
hubObserver = new MutationObserver((mutations) => {
|
|
1691
|
+
hubQueue.push(...mutations)
|
|
1692
|
+
scheduleHub()
|
|
1693
|
+
})
|
|
1694
|
+
hubObserver.observe(document.body, { childList: true, subtree: true })
|
|
1695
|
+
} else {
|
|
1696
|
+
flipObserver = new MutationObserver((mutations) => {
|
|
1697
|
+
handleFlipBatch(mutations)
|
|
1698
|
+
if (!flipPendingRaf) {
|
|
1699
|
+
flipPendingRaf = requestAnimationFrame(() => {
|
|
1700
|
+
flipPendingRaf = null
|
|
1701
|
+
flushFlipRoots()
|
|
1702
|
+
})
|
|
1703
|
+
}
|
|
1704
|
+
})
|
|
1705
|
+
flipObserver.observe(document.body, { childList: true, subtree: true })
|
|
1706
|
+
|
|
1707
|
+
appearObserver = new MutationObserver((mutations) => {
|
|
1708
|
+
handleAppearBatch(mutations)
|
|
1709
|
+
})
|
|
1710
|
+
appearObserver.observe(document.body, { childList: true, subtree: true })
|
|
1711
|
+
|
|
1712
|
+
// Capture any .leave elements already present so they can exit later
|
|
1713
|
+
qAll(".leave").forEach(captureLeave)
|
|
1714
|
+
|
|
1715
|
+
leaveObserver = new MutationObserver((mutations) => {
|
|
1716
|
+
handleLeaveBatch(mutations)
|
|
1717
|
+
})
|
|
1718
|
+
leaveObserver.observe(document.body, { childList: true, subtree: true })
|
|
1719
|
+
// leave capture for throttled path is done below after branch
|
|
1720
|
+
}
|
|
1721
|
+
if (throttlePerFrame > 0) {
|
|
1722
|
+
// capture for throttled path (was inside else branch above for non-throttled)
|
|
1723
|
+
qAll(".leave").forEach(captureLeave)
|
|
1724
|
+
}
|
|
1656
1725
|
|
|
1657
1726
|
// Keep the captured position fresh (throttled to one pass per frame)
|
|
1658
1727
|
let positionTick = false
|
|
@@ -1671,9 +1740,12 @@ export default function initListeners(root = document) {
|
|
|
1671
1740
|
window.addEventListener("resize", refreshLeavePositions, { passive: true })
|
|
1672
1741
|
|
|
1673
1742
|
return () => {
|
|
1674
|
-
appearObserver
|
|
1675
|
-
leaveObserver
|
|
1676
|
-
flipObserver
|
|
1743
|
+
appearObserver?.disconnect()
|
|
1744
|
+
leaveObserver?.disconnect()
|
|
1745
|
+
flipObserver?.disconnect()
|
|
1746
|
+
if (hubObserver) hubObserver.disconnect()
|
|
1747
|
+
if (hubRaf) cancelAnimationFrame(hubRaf)
|
|
1748
|
+
if (flipPendingRaf) cancelAnimationFrame(flipPendingRaf)
|
|
1677
1749
|
window.removeEventListener("scroll", refreshLeavePositions)
|
|
1678
1750
|
window.removeEventListener("resize", refreshLeavePositions)
|
|
1679
1751
|
window.removeEventListener("load", ScrollTrigger.refresh)
|
package/index.d.ts
CHANGED
|
@@ -4,8 +4,28 @@
|
|
|
4
4
|
|
|
5
5
|
// --- AnimToggle ------------------------------------------------------------
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
export interface GClassConfig {
|
|
8
|
+
throttlePerFrame: number
|
|
9
|
+
fps: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Boots the GSAP animation system (idempotent).
|
|
14
|
+
* @param throttlePerFrame - number of observer handlers allowed per rAF frame (0 = no throttling, default).
|
|
15
|
+
* Also accepts initAnimations({throttlePerFrame, fps}) object overload.
|
|
16
|
+
* @param fps - GSAP ticker fps cap (0 = default rAF, e.g. 30 for low-end). 0/undefined = no cap.
|
|
17
|
+
*/
|
|
18
|
+
export function initAnimations(throttlePerFrame?: number | GClassConfig, fps?: number): void
|
|
19
|
+
/**
|
|
20
|
+
* Change GClass runtime options on the fly without reload.
|
|
21
|
+
* gclassOpts(throttlePerFrame, fps) — both optional numbers, missing -> defaults (0).
|
|
22
|
+
* gclassOpts() resets to defaults (no throttle, default ticker).
|
|
23
|
+
* Also accepts gclassOpts({throttlePerFrame, fps}).
|
|
24
|
+
* Example low-end button: onClick={() => gclassOpts(1, 30)}
|
|
25
|
+
*/
|
|
26
|
+
export function gclassOpts(throttlePerFrame?: number | GClassConfig, fps?: number): GClassConfig
|
|
27
|
+
export function getGClassConfig(): GClassConfig
|
|
28
|
+
export function subscribeGClassConfig(cb: (cfg: GClassConfig) => void): () => void
|
|
9
29
|
/** Toggle animations on/off and reload the page. */
|
|
10
30
|
export function toggleAnimations(): void
|
|
11
31
|
/** Force animations off (wins over any stored preference) and reload. */
|
|
@@ -28,8 +48,12 @@ export function registerComplete(name: string, fn: CompleteHandler): CompleteHan
|
|
|
28
48
|
* Boot the engine directly, bypassing AnimToggle. Returns a teardown function
|
|
29
49
|
* that removes all listeners/observers/tweens created by this run.
|
|
30
50
|
* Pass a root to scope to that subtree (used for .boot-up).
|
|
51
|
+
* @param root - scope root (Document or HTMLElement)
|
|
52
|
+
* @param throttlePerFrame - number of observer handlers allowed per rAF frame.
|
|
53
|
+
* 0/undefined = no throttling (default). 1 = 1 observer per frame round-robin.
|
|
54
|
+
* Overload: initListeners(throttlePerFrame) is also supported (root defaults to document).
|
|
31
55
|
*/
|
|
32
|
-
export default function initListeners(root?: Document | HTMLElement): () => void
|
|
56
|
+
export default function initListeners(root?: Document | HTMLElement | number, throttlePerFrame?: number): () => void
|
|
33
57
|
|
|
34
58
|
// --- onComplete config -----------------------------------------------------
|
|
35
59
|
|
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { initAnimations, toggleAnimations, enableReducedMotion, disableReducedMotion } from './AnimToggle.js'
|
|
1
|
+
export { initAnimations, gclassOpts, getGClassConfig, subscribeGClassConfig, toggleAnimations, enableReducedMotion, disableReducedMotion } from './AnimToggle.js'
|
|
2
2
|
export { default as initListeners, registerComplete } from './Listeners.js'
|
|
3
3
|
export { customAnims } from './CustomAnims.js'
|
|
4
4
|
export { defaults, animations, normalize } from './Config.js'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gclass-anims",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.21",
|
|
4
4
|
"description": "A Tailwind-style utility layer on top of GSAP. Framework-agnostic - works in vanilla JS, React, Vue, Svelte, or any bundler.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|