@unseenco/theatre-gsap 0.4.3 → 0.5.0

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/dist/index.mjs CHANGED
@@ -522,11 +522,11 @@ function validateAndSanitiseSlashedPathOrThrow(unsanitisedPath, fnName) {
522
522
  Please replace the path with the sanitized one, otherwise it will likely break in the future.`,
523
523
  [
524
524
  {
525
- url: "https://www.theatrejs.com/docs/latest/manual/objects#creating-sheet-objects",
525
+ url: "https://unseen-theatre.netlify.app/docs/guide/manual/objects#creating-objects",
526
526
  title: "Sheet Objects"
527
527
  },
528
528
  {
529
- url: "https://www.theatrejs.com/docs/latest/api/core#sheet.object",
529
+ url: "https://unseen-theatre.netlify.app/docs/api/theatre-core#sheet.object",
530
530
  title: "API"
531
531
  }
532
532
  ]
@@ -595,6 +595,21 @@ function linkGsapTimelineChildAnimations(animation) {
595
595
  return map;
596
596
  }
597
597
 
598
+ // ../../theatre/shared/src/gsap/gsapAnimationLabel.ts
599
+ function readGsapAnimationVarsId(animation) {
600
+ const id = animation.vars?.id;
601
+ if (typeof id === "string" && id.trim().length > 0) {
602
+ return id.trim();
603
+ }
604
+ return void 0;
605
+ }
606
+ function resolveGsapAnimationRegistrationLabel(animation, optionsLabel, fallback = "GSAP animation") {
607
+ if (typeof optionsLabel === "string" && optionsLabel.length > 0) {
608
+ return optionsLabel;
609
+ }
610
+ return readGsapAnimationVarsId(animation) ?? fallback;
611
+ }
612
+
598
613
  // ../../theatre/shared/src/gsap/gsapSheetObjectKey.ts
599
614
  var GSAP_NAMESPACE_STORE_KEY = "__unseenco_theatre_gsap_configuredNamespace__";
600
615
  function setConfiguredGsapSheetObjectNamespace(namespace) {
@@ -2193,22 +2208,136 @@ function listAnimationEntries() {
2193
2208
  return entries;
2194
2209
  }
2195
2210
 
2211
+ // ../../theatre/shared/src/sheets/pageScrollContext.ts
2212
+ var defaultPageScrollContext = {
2213
+ scroller: null,
2214
+ axis: "vertical"
2215
+ };
2216
+ var activePageScrollContext = defaultPageScrollContext;
2217
+ function setActivePageScrollContext(context) {
2218
+ activePageScrollContext = {
2219
+ scroller: context.scroller,
2220
+ axis: context.axis ?? "vertical"
2221
+ };
2222
+ }
2223
+ function resolvePageScrollAxis(context = defaultPageScrollContext) {
2224
+ return context.axis ?? "vertical";
2225
+ }
2226
+ function resolvePageScrollScroller(st, defaultsScroller) {
2227
+ const surface = st;
2228
+ const fromSt = surface.scroller ?? surface.vars?.scroller;
2229
+ if (fromSt != null) {
2230
+ return fromSt;
2231
+ }
2232
+ if (defaultsScroller !== void 0) {
2233
+ return defaultsScroller;
2234
+ }
2235
+ return null;
2236
+ }
2237
+ function isWindowLike(value) {
2238
+ return typeof Window !== "undefined" && (value === window || value instanceof Window);
2239
+ }
2240
+ function isNativeDocumentScroller(scroller) {
2241
+ if (scroller == null)
2242
+ return true;
2243
+ if (isWindowLike(scroller))
2244
+ return true;
2245
+ if (typeof document === "undefined")
2246
+ return false;
2247
+ return scroller === document.documentElement || scroller === document.body;
2248
+ }
2249
+ function pageScrollScrollersMatch(a, b) {
2250
+ if (a === b)
2251
+ return true;
2252
+ if (isNativeDocumentScroller(a) && isNativeDocumentScroller(b))
2253
+ return true;
2254
+ return false;
2255
+ }
2256
+ function isScrollTriggerHorizontal(st) {
2257
+ const surface = st;
2258
+ return surface.horizontal === true || surface.vars?.horizontal === true;
2259
+ }
2260
+ function isPageScrollTrigger(st, context = defaultPageScrollContext) {
2261
+ const axis = resolvePageScrollAxis(context);
2262
+ const stHorizontal = isScrollTriggerHorizontal(st);
2263
+ if (stHorizontal !== (axis === "horizontal")) {
2264
+ return false;
2265
+ }
2266
+ const stScroller = resolvePageScrollScroller(st, context.scroller);
2267
+ return pageScrollScrollersMatch(stScroller, context.scroller);
2268
+ }
2269
+
2270
+ // src/gsapScrollTriggerPlugin.ts
2271
+ import { ScrollTrigger as scrollTriggerFromGsap } from "gsap/ScrollTrigger";
2272
+ var boundScrollTrigger;
2273
+ function bindGsapScrollTriggerPlugin(scrollTrigger) {
2274
+ boundScrollTrigger = scrollTrigger;
2275
+ }
2276
+ function getGsapScrollTriggerPlugin() {
2277
+ if (boundScrollTrigger) {
2278
+ return boundScrollTrigger;
2279
+ }
2280
+ const g = globalThis;
2281
+ return g.ScrollTrigger ?? scrollTriggerFromGsap;
2282
+ }
2283
+ function requireGsapScrollTriggerPlugin() {
2284
+ const plugin = getGsapScrollTriggerPlugin();
2285
+ if (!plugin) {
2286
+ throw new Error(
2287
+ 'ScrollTrigger is not available. Import ScrollTrigger from "gsap/ScrollTrigger", call gsap.registerPlugin(ScrollTrigger), and optionally bindGsapScrollTriggerPlugin(ScrollTrigger) before registering scroll triggers with Theatre.'
2288
+ );
2289
+ }
2290
+ return plugin;
2291
+ }
2292
+ function refreshGsapScrollTriggers() {
2293
+ getGsapScrollTriggerPlugin()?.refresh();
2294
+ }
2295
+
2196
2296
  // src/config.ts
2197
2297
  var activeConfig = {
2198
2298
  namespace: "GSAP",
2199
2299
  outlineNamespace: { defaultCollapsed: false }
2200
2300
  };
2201
2301
  setConfiguredGsapSheetObjectNamespace(activeConfig.namespace);
2302
+ function pageScrollContextFromConfig(pageScroll) {
2303
+ return {
2304
+ scroller: pageScroll.scroller ?? defaultPageScrollContext.scroller,
2305
+ axis: pageScroll.axis ?? defaultPageScrollContext.axis ?? "vertical"
2306
+ };
2307
+ }
2308
+ function applyScrollTriggerDefaultsForPageScroll(pageScroll) {
2309
+ const ScrollTrigger = getGsapScrollTriggerPlugin();
2310
+ const { scroller, axis } = pageScrollContextFromConfig(pageScroll);
2311
+ ScrollTrigger?.defaults?.({
2312
+ scroller: scroller ?? void 0,
2313
+ ...axis === "horizontal" ? { horizontal: true } : {}
2314
+ });
2315
+ }
2202
2316
  function configureTheatreGsap(config) {
2203
2317
  const prev = activeConfig;
2204
2318
  activeConfig = {
2205
2319
  namespace: config.namespace ?? prev.namespace ?? "GSAP",
2206
- outlineNamespace: config.outlineNamespace ?? prev.outlineNamespace
2320
+ outlineNamespace: config.outlineNamespace ?? prev.outlineNamespace,
2321
+ suppressGsapTickerRafWarning: config.suppressGsapTickerRafWarning ?? prev.suppressGsapTickerRafWarning,
2322
+ pageScroll: config.pageScroll ?? prev.pageScroll
2207
2323
  };
2208
2324
  setConfiguredGsapSheetObjectNamespace(activeConfig.namespace ?? "GSAP");
2325
+ if (config.pageScroll !== void 0) {
2326
+ const ctx = pageScrollContextFromConfig(config.pageScroll);
2327
+ setActivePageScrollContext(ctx);
2328
+ applyScrollTriggerDefaultsForPageScroll(config.pageScroll);
2329
+ }
2209
2330
  return {
2210
2331
  reset() {
2211
2332
  activeConfig = prev;
2333
+ setConfiguredGsapSheetObjectNamespace(prev.namespace ?? "GSAP");
2334
+ if (prev.pageScroll !== void 0) {
2335
+ const ctx = pageScrollContextFromConfig(prev.pageScroll);
2336
+ setActivePageScrollContext(ctx);
2337
+ applyScrollTriggerDefaultsForPageScroll(prev.pageScroll);
2338
+ } else {
2339
+ setActivePageScrollContext(defaultPageScrollContext);
2340
+ }
2212
2341
  }
2213
2342
  };
2214
2343
  }
@@ -2265,11 +2394,56 @@ function formatOutlineNamespacePathKey(pathSegments) {
2265
2394
  return pathSegments.join(" / ");
2266
2395
  }
2267
2396
 
2397
+ // src/gsapTickerRafBridge.ts
2398
+ import { getTheatreCoreRafDriver } from "@unseenco/theatre-core/privateAPIs";
2399
+ var gsapTickerDrivenDriverIds = /* @__PURE__ */ new Set();
2400
+ function bindGsapTickerToRafDriver(rafDriver, gsap) {
2401
+ const onTick = (time) => {
2402
+ rafDriver.tick(time * 1e3);
2403
+ };
2404
+ gsapTickerDrivenDriverIds.add(rafDriver.id);
2405
+ gsap.ticker.add(onTick);
2406
+ return () => {
2407
+ gsap.ticker.remove(onTick);
2408
+ gsapTickerDrivenDriverIds.delete(rafDriver.id);
2409
+ };
2410
+ }
2411
+ function isRafDriverDrivenByGsapTicker(rafDriver) {
2412
+ return gsapTickerDrivenDriverIds.has(rafDriver.id);
2413
+ }
2414
+ var hasWarnedGsapTickerRaf = false;
2415
+ var gsapTickerRafWarningMicrotaskQueued = false;
2416
+ function scheduleGsapTickerRafWarningCheck() {
2417
+ if (gsapTickerRafWarningMicrotaskQueued)
2418
+ return;
2419
+ gsapTickerRafWarningMicrotaskQueued = true;
2420
+ queueMicrotask(() => {
2421
+ gsapTickerRafWarningMicrotaskQueued = false;
2422
+ warnIfGsapTickerNotDrivingTheatreRaf();
2423
+ });
2424
+ }
2425
+ function warnIfGsapTickerNotDrivingTheatreRaf() {
2426
+ if (typeof window === "undefined")
2427
+ return;
2428
+ if (getTheatreGsapConfig().suppressGsapTickerRafWarning)
2429
+ return;
2430
+ if (hasWarnedGsapTickerRaf)
2431
+ return;
2432
+ const coreDriver = getTheatreCoreRafDriver();
2433
+ if (!isRafDriverDrivenByGsapTicker(coreDriver)) {
2434
+ hasWarnedGsapTickerRaf = true;
2435
+ console.warn(
2436
+ "[theatre-gsap] Theatre is not driven by gsap.ticker. After setCoreRafDriver(), call bindGsapTickerToRafDriver(rafDriver, gsap) so GSAP and Theatre share one clock. See the GSAP extension guide."
2437
+ );
2438
+ }
2439
+ }
2440
+
2268
2441
  // src/registerGsapAnimation.ts
2269
2442
  function registerGsapAnimation(animation, sheet, options) {
2270
2443
  const config = getTheatreGsapConfig();
2271
2444
  const namespace = options.namespace ?? config.namespace ?? "GSAP";
2272
- const objectKey = buildGsapSheetObjectKey(namespace, options.label);
2445
+ const label = resolveGsapAnimationRegistrationLabel(animation, options.label);
2446
+ const objectKey = buildGsapSheetObjectKey(namespace, label);
2273
2447
  const id = options.id ?? objectKey;
2274
2448
  animation.pause();
2275
2449
  const sheetObjectPublic = sheet.object(objectKey, {}, { reconfigure: false });
@@ -2283,25 +2457,441 @@ function registerGsapAnimation(animation, sheet, options) {
2283
2457
  }
2284
2458
  registerAnimationInRegistry2({
2285
2459
  id,
2286
- label: options.label,
2460
+ label,
2287
2461
  animation,
2288
2462
  sheetObject: sheetObjectInternal,
2289
- defaultDuration: options.defaultDuration,
2463
+ defaultDuration: options.defaultDuration ?? (sheet.getSequenceMode() === "page" ? 10 : void 0),
2290
2464
  onRebuildTimeline: options.onRebuildTimeline
2291
2465
  });
2466
+ scheduleGsapTickerRafWarningCheck();
2292
2467
  return { id, sheetObject: sheetObjectPublic };
2293
2468
  }
2294
2469
 
2470
+ // src/registerGsapScrollTrigger.ts
2471
+ import { privateAPI as privateAPI2 } from "@unseenco/theatre-core/privateAPIs";
2472
+
2473
+ // ../../theatre/shared/src/gsap/scrollTriggerGuards.ts
2474
+ function resolveScrollTriggerAnimation(st) {
2475
+ const surface = st;
2476
+ if (surface.animation != null)
2477
+ return surface.animation;
2478
+ if (surface.vars?.animation != null)
2479
+ return surface.vars.animation;
2480
+ return void 0;
2481
+ }
2482
+ function defaultScrollTriggerLabel(st, fallbackIndex) {
2483
+ const surface = st;
2484
+ const id = surface.vars?.id;
2485
+ if (typeof id === "string" && id.length > 0)
2486
+ return id;
2487
+ const trigger = surface.trigger;
2488
+ if (trigger && typeof trigger === "object" && "id" in trigger) {
2489
+ const elementId = trigger.id;
2490
+ if (typeof elementId === "string" && elementId.length > 0) {
2491
+ return elementId;
2492
+ }
2493
+ }
2494
+ return `ScrollTrigger ${fallbackIndex + 1}`;
2495
+ }
2496
+ function readAnimationSpanSeconds(animation) {
2497
+ return Math.max(readGsapTweenTimelineDuration(animation), MIN_ANIMATION_SPAN);
2498
+ }
2499
+ var MIN_ANIMATION_SPAN = 0.01;
2500
+
2501
+ // ../../theatre/shared/src/gsap/scrollTriggerLayout.ts
2502
+ var MIN_SEQUENCE_DURATION = 0.01;
2503
+ function scrollPixelsToPageUnits(startPx, endPx, maxScrollPx, sequenceLength) {
2504
+ const length = Math.max(sequenceLength, MIN_SEQUENCE_DURATION);
2505
+ if (maxScrollPx <= 0) {
2506
+ return { start: 0, duration: length };
2507
+ }
2508
+ const startProgress = Math.max(0, Math.min(1, startPx / maxScrollPx));
2509
+ const endProgress = Math.max(0, Math.min(1, endPx / maxScrollPx));
2510
+ const lo = Math.min(startProgress, endProgress);
2511
+ const hi = Math.max(startProgress, endProgress);
2512
+ let start = lo * length;
2513
+ let duration = Math.max((hi - lo) * length, MIN_SEQUENCE_DURATION);
2514
+ if (start + duration > length) {
2515
+ start = Math.max(0, length - duration);
2516
+ }
2517
+ if (start < 0)
2518
+ start = 0;
2519
+ return { start, duration };
2520
+ }
2521
+ function getNativeDocumentMaxScroll(axis = "vertical") {
2522
+ if (typeof document === "undefined" || typeof window === "undefined") {
2523
+ return 0;
2524
+ }
2525
+ const el = document.documentElement;
2526
+ if (axis === "horizontal") {
2527
+ const scrolling = document.scrollingElement ?? el;
2528
+ return Math.max(0, scrolling.scrollWidth - scrolling.clientWidth);
2529
+ }
2530
+ return Math.max(0, el.scrollHeight - window.innerHeight);
2531
+ }
2532
+ function getMaxScrollForScroller(scroller, axis = "vertical") {
2533
+ if (typeof document === "undefined" || typeof window === "undefined") {
2534
+ return 0;
2535
+ }
2536
+ if (isNativeDocumentScroller(scroller)) {
2537
+ return getNativeDocumentMaxScroll(axis);
2538
+ }
2539
+ const el = scroller;
2540
+ if (axis === "horizontal") {
2541
+ return Math.max(0, el.scrollWidth - el.clientWidth);
2542
+ }
2543
+ return Math.max(0, el.scrollHeight - el.clientHeight);
2544
+ }
2545
+ function getMaxScrollForPageScrollContext(scroller, axis = "vertical") {
2546
+ return getMaxScrollForScroller(scroller, axis);
2547
+ }
2548
+
2549
+ // ../../theatre/shared/src/sheets/remotePageScrollMetrics.ts
2550
+ var remoteMetrics;
2551
+ function resolveMaxScrollPxForPageLayout(localMaxScrollPx, axis) {
2552
+ if (localMaxScrollPx > 0) {
2553
+ return localMaxScrollPx;
2554
+ }
2555
+ const remote = remoteMetrics;
2556
+ if (remote && remote.axis === axis && remote.maxScroll > 0) {
2557
+ return remote.maxScroll;
2558
+ }
2559
+ return localMaxScrollPx;
2560
+ }
2561
+
2562
+ // ../../theatre/shared/src/gsap/extractScrollTriggerLayout.ts
2563
+ function extractScrollTriggerLayout(st, options) {
2564
+ const pageScrollContext = options.pageScrollContext ?? defaultPageScrollContext;
2565
+ if (!isPageScrollTrigger(st, pageScrollContext)) {
2566
+ return { ok: false, reason: "unsupported_scroller" };
2567
+ }
2568
+ const surface = st;
2569
+ const animation = resolveScrollTriggerAnimation(st);
2570
+ if (!animation) {
2571
+ return { ok: false, reason: "missing_animation" };
2572
+ }
2573
+ const axis = resolvePageScrollAxis(pageScrollContext);
2574
+ const localMaxScroll = getMaxScrollForPageScrollContext(
2575
+ pageScrollContext.scroller,
2576
+ axis
2577
+ );
2578
+ const maxScroll = resolveMaxScrollPxForPageLayout(localMaxScroll, axis);
2579
+ const layout = scrollPixelsToPageUnits(
2580
+ surface.start,
2581
+ surface.end,
2582
+ maxScroll,
2583
+ options.sequenceLength
2584
+ );
2585
+ const fallbackIndex = options.fallbackIndex ?? 0;
2586
+ const label = options.label ?? defaultScrollTriggerLabel(st, fallbackIndex);
2587
+ const id = options.id ?? (typeof surface.vars?.id === "string" && surface.vars.id.length > 0 ? surface.vars.id : `st_${label.replace(/\s+/g, "_")}_${fallbackIndex}`);
2588
+ const kind = isGsapTimeline(animation) ? "timeline" : "tween";
2589
+ const animationSpanSeconds = readAnimationSpanSeconds(animation);
2590
+ const timelineChildren = kind === "timeline" ? introspectGsapTimelineChildren(animation) : [];
2591
+ return {
2592
+ ok: true,
2593
+ value: {
2594
+ id,
2595
+ label,
2596
+ layout,
2597
+ kind,
2598
+ animationSpanSeconds,
2599
+ timelineChildren
2600
+ }
2601
+ };
2602
+ }
2603
+
2604
+ // ../../theatre/shared/src/gsap/scrollTriggerRegistry.ts
2605
+ var DEFAULT_SHEET_INSTANCE_ID2 = "default";
2606
+ var REGISTRY_KEY2 = "__unseenco_theatre_gsap_scrollTriggerRegistry__";
2607
+ function sheetAddressKey(address) {
2608
+ const sheetInstanceId = address.sheetInstanceId ?? DEFAULT_SHEET_INSTANCE_ID2;
2609
+ return `${address.projectId}|${address.sheetId}|${sheetInstanceId}`;
2610
+ }
2611
+ function getStore3() {
2612
+ const g = globalThis;
2613
+ if (!g[REGISTRY_KEY2]) {
2614
+ g[REGISTRY_KEY2] = { bySheetAddress: /* @__PURE__ */ new Map() };
2615
+ }
2616
+ return g[REGISTRY_KEY2];
2617
+ }
2618
+ function getSheetMap(key) {
2619
+ const store = getStore3();
2620
+ let map = store.bySheetAddress.get(key);
2621
+ if (!map) {
2622
+ map = /* @__PURE__ */ new Map();
2623
+ store.bySheetAddress.set(key, map);
2624
+ }
2625
+ return map;
2626
+ }
2627
+ function registerScrollTriggerInRegistry(sheetKey, entry) {
2628
+ const map = getSheetMap(sheetKey);
2629
+ for (const existing of map.values()) {
2630
+ if (existing.scrollTrigger === entry.scrollTrigger) {
2631
+ return "duplicate";
2632
+ }
2633
+ if (existing.id === entry.id) {
2634
+ return "duplicate";
2635
+ }
2636
+ }
2637
+ map.set(entry.id, entry);
2638
+ bumpGsapStudioRegistryRevision();
2639
+ return "registered";
2640
+ }
2641
+ function findScrollTriggerEntryByInstance(sheetKey, scrollTrigger) {
2642
+ const map = getStore3().bySheetAddress.get(sheetKey);
2643
+ if (!map)
2644
+ return void 0;
2645
+ for (const entry of map.values()) {
2646
+ if (entry.scrollTrigger === scrollTrigger) {
2647
+ return entry;
2648
+ }
2649
+ }
2650
+ return void 0;
2651
+ }
2652
+ function updateScrollTriggerLayoutInRegistry(sheetKey, id, patch) {
2653
+ const existing = getSheetMap(sheetKey).get(id);
2654
+ if (!existing)
2655
+ return;
2656
+ getSheetMap(sheetKey).set(id, { ...existing, ...patch });
2657
+ bumpGsapStudioRegistryRevision();
2658
+ }
2659
+ function listScrollTriggerEntriesForSheet(sheetKey) {
2660
+ const map = getStore3().bySheetAddress.get(sheetKey);
2661
+ if (!map)
2662
+ return [];
2663
+ return [...map.values()].sort((a, b) => a.layout.start - b.layout.start);
2664
+ }
2665
+
2666
+ // src/attachTheatrePageScroll.ts
2667
+ import {
2668
+ attachTheatrePageScroll as attachTheatrePageScrollCore,
2669
+ createDefaultPageScrollDriver as createDefaultPageScrollDriverCore,
2670
+ getTheatrePageScrollContext as getTheatrePageScrollContextCore
2671
+ } from "@unseenco/theatre-core";
2672
+ function applyScrollTriggerDefaultsFromGsapConfig() {
2673
+ const { pageScroll } = getTheatreGsapConfig();
2674
+ if (!pageScroll)
2675
+ return;
2676
+ const ScrollTrigger = getGsapScrollTriggerPlugin();
2677
+ if (!ScrollTrigger?.defaults)
2678
+ return;
2679
+ const axis = pageScroll.axis ?? defaultPageScrollContext.axis ?? "vertical";
2680
+ ScrollTrigger.defaults({
2681
+ scroller: pageScroll.scroller ?? void 0,
2682
+ ...axis === "horizontal" ? { horizontal: true } : {}
2683
+ });
2684
+ }
2685
+ function getTheatrePageScrollContext() {
2686
+ applyScrollTriggerDefaultsFromGsapConfig();
2687
+ const pageScroll = getTheatreGsapConfig().pageScroll;
2688
+ if (pageScroll) {
2689
+ const ctx = {
2690
+ scroller: pageScroll.scroller ?? defaultPageScrollContext.scroller,
2691
+ axis: pageScroll.axis ?? defaultPageScrollContext.axis
2692
+ };
2693
+ setActivePageScrollContext(ctx);
2694
+ return ctx;
2695
+ }
2696
+ return getTheatrePageScrollContextCore();
2697
+ }
2698
+ function createDefaultPageScrollDriver(scroller = getTheatrePageScrollContext().scroller) {
2699
+ const ctx = getTheatrePageScrollContext();
2700
+ return createDefaultPageScrollDriverCore(scroller, resolvePageScrollAxis(ctx));
2701
+ }
2702
+ function attachTheatrePageScroll(sheet, options = {}) {
2703
+ applyScrollTriggerDefaultsFromGsapConfig();
2704
+ return attachTheatrePageScrollCore(sheet, options);
2705
+ }
2706
+
2707
+ // ../../theatre/shared/src/gsap/scrollTriggerGlobal.ts
2708
+ function refreshGsapScrollTriggersFromGlobal() {
2709
+ const ScrollTrigger = globalThis.ScrollTrigger;
2710
+ ScrollTrigger?.refresh?.();
2711
+ }
2712
+
2713
+ // ../../theatre/shared/src/gsap/refreshScrollTriggerLayoutsForSheet.ts
2714
+ function refreshScrollTriggerLayoutsForSheet(sheetKey, sequenceLength, pageScrollContext = defaultPageScrollContext) {
2715
+ refreshGsapScrollTriggersFromGlobal();
2716
+ for (const entry of listScrollTriggerEntriesForSheet(sheetKey)) {
2717
+ const extracted = extractScrollTriggerLayout(entry.scrollTrigger, {
2718
+ sequenceLength,
2719
+ id: entry.id,
2720
+ label: entry.label,
2721
+ pageScrollContext
2722
+ });
2723
+ if (!extracted.ok)
2724
+ continue;
2725
+ updateScrollTriggerLayoutInRegistry(sheetKey, entry.id, {
2726
+ layout: extracted.value.layout,
2727
+ kind: extracted.value.kind,
2728
+ animationSpanSeconds: extracted.value.animationSpanSeconds,
2729
+ timelineChildren: extracted.value.timelineChildren
2730
+ });
2731
+ }
2732
+ }
2733
+
2734
+ // src/registerGsapScrollTrigger.ts
2735
+ function assertPageMode(sheet) {
2736
+ if (sheet.getSequenceMode() !== "page") {
2737
+ throw new Error(
2738
+ 'registerGsapScrollTrigger() requires the sheet to use sequenceMode "page".'
2739
+ );
2740
+ }
2741
+ }
2742
+ function sequenceLengthForSheet(sheet) {
2743
+ return privateAPI2(sheet).getSequence().length;
2744
+ }
2745
+ function scrollTriggerObjectKey(namespace, label) {
2746
+ return buildGsapSheetObjectKey(namespace, `ScrollTriggers / ${label}`);
2747
+ }
2748
+ function registerOneGsapScrollTriggerOnSheet(sheet, st, options, fallbackIndex) {
2749
+ const config = getTheatreGsapConfig();
2750
+ const namespace = options.namespace ?? config.namespace ?? "GSAP";
2751
+ const sheetInternal = privateAPI2(sheet);
2752
+ const sheetKey = sheetAddressKey(sheetInternal.address);
2753
+ const sequenceLength = sequenceLengthForSheet(sheet);
2754
+ const existingByInstance = findScrollTriggerEntryByInstance(sheetKey, st);
2755
+ if (existingByInstance?.sheetObject) {
2756
+ console.warn(
2757
+ `[theatre-gsap] ScrollTrigger "${options.label}" is already registered for this sheet (id "${existingByInstance.id}"). Skipping duplicate registration.`
2758
+ );
2759
+ return {
2760
+ id: existingByInstance.id,
2761
+ sheetObject: existingByInstance.sheetObject.publicApi
2762
+ };
2763
+ }
2764
+ refreshGsapScrollTriggers();
2765
+ const pageScrollContext = getTheatrePageScrollContext();
2766
+ const extracted = extractScrollTriggerLayout(st, {
2767
+ sequenceLength,
2768
+ id: options.id,
2769
+ label: options.label,
2770
+ fallbackIndex,
2771
+ pageScrollContext
2772
+ });
2773
+ if (!extracted.ok) {
2774
+ if (extracted.reason === "unsupported_scroller") {
2775
+ console.warn(
2776
+ `[theatre-gsap] Skipped ScrollTrigger "${options.label}": scroller or scroll axis does not match configured page scroll (see configureTheatreGsap pageScroll scroller and axis).`
2777
+ );
2778
+ } else {
2779
+ console.warn(
2780
+ `[theatre-gsap] Skipped ScrollTrigger "${options.label}": no linked tween or timeline found.`
2781
+ );
2782
+ }
2783
+ return null;
2784
+ }
2785
+ const { value } = extracted;
2786
+ const objectKey = scrollTriggerObjectKey(namespace, value.label);
2787
+ const id = options.id ?? value.id;
2788
+ const sheetObjectPublic = sheet.object(objectKey, {}, { reconfigure: false });
2789
+ const sheetObjectInternal = privateAPI2(sheetObjectPublic);
2790
+ if (config.outlineNamespace) {
2791
+ privateAPI2(sheet).template.setOutlineNamespaceConfig(
2792
+ formatOutlineNamespacePathKey([namespace]),
2793
+ config.outlineNamespace
2794
+ );
2795
+ }
2796
+ const entry = {
2797
+ id,
2798
+ label: value.label,
2799
+ scrollTrigger: st,
2800
+ sheetObject: sheetObjectInternal,
2801
+ layout: value.layout,
2802
+ kind: value.kind,
2803
+ animationSpanSeconds: value.animationSpanSeconds,
2804
+ timelineChildren: value.timelineChildren
2805
+ };
2806
+ registerScrollTriggerInRegistry(sheetKey, entry);
2807
+ return { id, sheetObject: sheetObjectPublic };
2808
+ }
2809
+ function registerGsapScrollTrigger(scrollTrigger, sheet, options) {
2810
+ assertPageMode(sheet);
2811
+ requireGsapScrollTriggerPlugin();
2812
+ const result = registerOneGsapScrollTriggerOnSheet(
2813
+ sheet,
2814
+ scrollTrigger,
2815
+ options,
2816
+ 0
2817
+ );
2818
+ if (!result) {
2819
+ throw new Error(
2820
+ `Could not register ScrollTrigger "${options.label}". See console warnings for details.`
2821
+ );
2822
+ }
2823
+ scheduleGsapTickerRafWarningCheck();
2824
+ return result;
2825
+ }
2826
+ function refreshRegisteredGsapScrollTriggerLayouts(sheet) {
2827
+ if (sheet.getSequenceMode() !== "page")
2828
+ return;
2829
+ const sheetInternal = privateAPI2(sheet);
2830
+ const sheetKey = sheetAddressKey(sheetInternal.address);
2831
+ refreshScrollTriggerLayoutsForSheet(
2832
+ sheetKey,
2833
+ sequenceLengthForSheet(sheet),
2834
+ getTheatrePageScrollContext()
2835
+ );
2836
+ }
2837
+
2838
+ // src/registerAllGsapScrollTriggers.ts
2839
+ import { privateAPI as privateAPI3 } from "@unseenco/theatre-core/privateAPIs";
2840
+ function registerAllGsapScrollTriggers(sheet) {
2841
+ if (sheet.getSequenceMode() !== "page") {
2842
+ throw new Error(
2843
+ 'registerAllGsapScrollTriggers() requires the sheet to use sequenceMode "page".'
2844
+ );
2845
+ }
2846
+ const ScrollTrigger = requireGsapScrollTriggerPlugin();
2847
+ refreshGsapScrollTriggers();
2848
+ const all = ScrollTrigger.getAll();
2849
+ const sheetKey = sheetAddressKey(privateAPI3(sheet).address);
2850
+ const registered = [];
2851
+ let skipped = 0;
2852
+ all.forEach((st, index) => {
2853
+ const already = findScrollTriggerEntryByInstance(sheetKey, st);
2854
+ const label = defaultScrollTriggerLabel(st, index);
2855
+ const id = typeof st.vars?.id === "string" && st.vars.id.length > 0 ? st.vars.id : void 0;
2856
+ const result = registerOneGsapScrollTriggerOnSheet(
2857
+ sheet,
2858
+ st,
2859
+ { label, id },
2860
+ index
2861
+ );
2862
+ if (!result) {
2863
+ skipped += 1;
2864
+ } else if (already) {
2865
+ skipped += 1;
2866
+ } else {
2867
+ registered.push(result);
2868
+ }
2869
+ });
2870
+ scheduleGsapTickerRafWarningCheck();
2871
+ return { registered, skipped };
2872
+ }
2873
+
2295
2874
  // src/attachGsapSequenceBridge.ts
2296
2875
  import { attachGsapSequenceBridge } from "@unseenco/theatre-core";
2297
2876
  export {
2298
2877
  attachGsapSequenceBridge,
2878
+ attachTheatrePageScroll,
2879
+ bindGsapScrollTriggerPlugin,
2880
+ bindGsapTickerToRafDriver,
2299
2881
  configureTheatreGsap,
2882
+ createDefaultPageScrollDriver,
2300
2883
  getAnimationEntry2 as getAnimationEntry,
2301
2884
  getAnimationEntryById,
2302
2885
  getAnimationEntryForSheetObject2 as getAnimationEntryForSheetObject,
2303
2886
  getTheatreGsapConfig,
2887
+ getTheatrePageScrollContext,
2888
+ isRafDriverDrivenByGsapTicker,
2304
2889
  listAnimationEntries2 as listAnimationEntries,
2305
- registerGsapAnimation
2890
+ refreshRegisteredGsapScrollTriggerLayouts,
2891
+ registerAllGsapScrollTriggers,
2892
+ registerGsapAnimation,
2893
+ registerGsapScrollTrigger,
2894
+ scheduleGsapTickerRafWarningCheck,
2895
+ warnIfGsapTickerNotDrivingTheatreRaf
2306
2896
  };
2307
2897
  //# sourceMappingURL=index.mjs.map