@fiddle-digital/string-tune 1.1.27 → 1.1.29

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.d.ts CHANGED
@@ -129,6 +129,11 @@ declare class ScrollState {
129
129
  speedAccelerate: number;
130
130
  }
131
131
 
132
+ declare class SystemState {
133
+ fpsTracker: boolean;
134
+ positionTracker: boolean;
135
+ }
136
+
132
137
  /**
133
138
  * Represents the time-related state of the current and previous animation frames.
134
139
  *
@@ -207,12 +212,13 @@ declare class StringData {
207
212
  */
208
213
  render: RenderState;
209
214
  /**
210
- * Time-related state object.
211
- * Tracks frame timings, including current timestamp, delta between frames,
212
- * and total elapsed time since animation start.
213
- * Useful for time-based animations, easing, frame consistency, and syncing logic.
214
- */
215
+ * Time-related state object.
216
+ * Tracks frame timings, including current timestamp, delta between frames,
217
+ * and total elapsed time since animation start.
218
+ * Useful for time-based animations, easing, frame consistency, and syncing logic.
219
+ */
215
220
  time: TimeState;
221
+ system: SystemState;
216
222
  }
217
223
 
218
224
  /**
@@ -390,6 +396,30 @@ declare class EventManager {
390
396
  clearAll(): void;
391
397
  }
392
398
 
399
+ type MirrorEasingFn = (value: number) => number;
400
+ /**
401
+ * Lightweight wrapper that mirrors a primary StringObject while keeping
402
+ * its own easing and state. Intended for elements linked via
403
+ * `[string-copy-from]`.
404
+ */
405
+ declare class StringMirrorObject {
406
+ private parent;
407
+ readonly id: string;
408
+ readonly htmlElement: HTMLElement;
409
+ private properties;
410
+ private easingFn?;
411
+ constructor(id: string, element: HTMLElement, parent: StringObject);
412
+ get parentObject(): StringObject;
413
+ setProperty<T>(key: string, value: T): void;
414
+ getProperty<T>(key: string): T;
415
+ setEasing(easing: MirrorEasingFn | null | undefined): void;
416
+ getEasing(): MirrorEasingFn | undefined;
417
+ /**
418
+ * Returns eased progress using mirror easing (if set) or fallback.
419
+ */
420
+ applyProgress(rawProgress: number, fallback?: MirrorEasingFn): number;
421
+ }
422
+
393
423
  /**
394
424
  * Internal class representing a DOM-bound interactive object.
395
425
  * Connected to modules and holds its own internal state.
@@ -408,9 +438,9 @@ declare class StringObject {
408
438
  */
409
439
  keys: string[];
410
440
  /**
411
- * A list of elements that should be affected in sync with this one.
441
+ * Mirror objects linked via `string-copy-from`.
412
442
  */
413
- connects: HTMLElement[];
443
+ private mirrors;
414
444
  /**
415
445
  * Internal key-value store of dynamic object properties (like offsets, progress, etc.).
416
446
  */
@@ -466,6 +496,10 @@ declare class StringObject {
466
496
  * @param module - The module to connect
467
497
  */
468
498
  connect(module: IStringModule): void;
499
+ addMirror(mirror: StringMirrorObject): void;
500
+ removeMirror(id: string): void;
501
+ get mirrorObjects(): StringMirrorObject[];
502
+ get connects(): HTMLElement[];
469
503
  }
470
504
 
471
505
  declare class CenterCache {
@@ -1298,7 +1332,7 @@ declare class StringModule implements IStringModule {
1298
1332
  * @param object The object whose elements to update.
1299
1333
  * @param applyFn The function that receives an HTMLElement and performs any update.
1300
1334
  */
1301
- protected applyToElementAndConnects(object: StringObject, applyFn: (el: HTMLElement) => void): void;
1335
+ protected applyToElementAndConnects(object: StringObject, applyFn: (el: HTMLElement) => void, copyFn?: (el: HTMLElement, mirror?: StringMirrorObject) => void): void;
1302
1336
  /**
1303
1337
  * Cleans up internal state and detaches the module from the system.
1304
1338
  */
@@ -1307,6 +1341,9 @@ declare class StringModule implements IStringModule {
1307
1341
  onInit(): void;
1308
1342
  /** Called on each frame with current scroll and state data. */
1309
1343
  onFrame(data: StringData): void;
1344
+ onMutate(data: StringData): void;
1345
+ onScrollMeasure(data: StringData): void;
1346
+ onMouseMoveMeasure(data: StringData): void;
1310
1347
  /** Called when the window or layout is resized. */
1311
1348
  onResize(): void;
1312
1349
  /** Called when the layout is resized width. */
@@ -1341,25 +1378,53 @@ declare class StringModule implements IStringModule {
1341
1378
  onDOMMutate(added: NodeList, removed: NodeList): void;
1342
1379
  }
1343
1380
 
1381
+ /**
1382
+ * StringCursor Module
1383
+ *
1384
+ * Handles cursor tracking and hover states for StringTune objects.
1385
+ *
1386
+ * Safari Navigation Fix:
1387
+ * Safari has an issue where mouseleave events are not fired when navigation occurs
1388
+ * (especially with NuxtLink/router navigation). This module includes several
1389
+ * workarounds to ensure proper cleanup:
1390
+ *
1391
+ * 1. MutationObserver - detects when elements are removed from DOM
1392
+ * 2. beforeunload/pagehide - captures traditional navigation
1393
+ * 3. visibilitychange - captures modern SPA navigation
1394
+ * 4. DOM existence checks - prevents operations on removed elements
1395
+ */
1344
1396
  declare class StringCursor extends StringModule {
1345
1397
  protected enterObjectsMap: Map<string, StringObject>;
1346
1398
  protected enterObjects: Array<StringObject>;
1347
1399
  cursor: any;
1348
1400
  cursorContent: any;
1349
1401
  overCount: number;
1402
+ private cursorPrev;
1350
1403
  constructor(context: StringContext);
1351
1404
  initializeObject(globalId: number, object: StringObject, element: HTMLElement, attributes: Record<string, any>): void;
1352
- onFrame(data: StringData): void;
1405
+ onMutate(data: StringData): void;
1353
1406
  onObjectConnected(object: StringObject): void;
1354
1407
  getCursorClass(object: StringObject): string | null;
1355
1408
  onMouseEnter(object: StringObject): void;
1356
1409
  onMouseLeave(object: StringObject): void;
1357
1410
  private onEnterObject;
1358
1411
  private onLeaveObject;
1412
+ private safariNavigationCleanup;
1413
+ private onElementRemovedFromDOM;
1414
+ onObjectDisconnected(object: StringObject): void;
1359
1415
  private setMouseCoordinates;
1360
1416
  private calculateOffset;
1361
1417
  }
1362
1418
 
1419
+ declare class StringImpulse extends StringModule {
1420
+ constructor(context: StringContext);
1421
+ onObjectConnected(object: StringObject): void;
1422
+ onObjectDisconnected(object: StringObject): void;
1423
+ onMouseMove(_e?: MouseEvent): void;
1424
+ private getElementsAtPoint;
1425
+ onFrame(_: StringData): void;
1426
+ }
1427
+
1363
1428
  declare class StringMagnetic extends StringModule {
1364
1429
  constructor(context: StringContext);
1365
1430
  initializeObject(globalId: number, object: StringObject, element: HTMLElement, attributes: Record<string, any>): void;
@@ -1367,19 +1432,57 @@ declare class StringMagnetic extends StringModule {
1367
1432
  onFrame(data: StringData): void;
1368
1433
  }
1369
1434
 
1435
+ declare abstract class CursorReactiveModule extends StringModule {
1436
+ protected nearOnly: boolean;
1437
+ protected useAllObjects: boolean;
1438
+ protected maxDistanceMultiplier: number;
1439
+ protected updateThreshold: number;
1440
+ private objectDeltaData;
1441
+ constructor(context: StringContext);
1442
+ onObjectConnected(object: StringObject): void;
1443
+ removeObject(id: string): void;
1444
+ onScroll(): void;
1445
+ onMouseMoveMeasure(data: StringData): void;
1446
+ onMutate(data: StringData): void;
1447
+ protected getCursorTargets(): StringObject[];
1448
+ protected refreshPointerState(target?: StringObject): void;
1449
+ private scrollUpdateScheduled;
1450
+ protected scheduleCursorUpdate(): void;
1451
+ protected onCursorScrollUpdate(): void;
1452
+ }
1453
+
1454
+ declare class StringSpotlight extends CursorReactiveModule {
1455
+ protected onCursorFrame(data: StringData, frame: number): void;
1456
+ private updateScheduledSpotlight;
1457
+ constructor(context: any);
1458
+ initializeObject(id: number, obj: StringObject, el: HTMLElement, attrs: Record<string, any>): void;
1459
+ protected onPointerDelta(obj: StringObject, dx: number, dy: number, dist: number): void;
1460
+ onMouseMoveMeasure(data: StringData): void;
1461
+ onMutate(data: StringData): void;
1462
+ private ensurePointerState;
1463
+ private updateSpotlightState;
1464
+ protected onCursorScrollUpdate(): void;
1465
+ }
1466
+
1370
1467
  /**
1371
1468
  * Module that handles lazy-loading of images with `string-lazy` attribute.
1372
- * It loads the image only once, calculates its aspect-ratio to prevent layout shift,
1373
- * and then displays it.
1469
+ * Aspect ratios are precomputed before the real source is revealed in view.
1374
1470
  */
1375
1471
  declare class StringLazy extends StringModule {
1376
1472
  private isStartLoaded;
1377
1473
  private loadingCount;
1474
+ private imageStates;
1378
1475
  constructor(context: StringContext);
1379
1476
  onInit(): void;
1380
1477
  onObjectConnected(object: StringObject): void;
1381
- private loadImage;
1382
- private handleLoadingCompletion;
1478
+ onObjectDisconnected(object: StringObject): void;
1479
+ private ensureState;
1480
+ private readSource;
1481
+ private prepareAspectRatio;
1482
+ private loadIntrinsicSize;
1483
+ private handleInView;
1484
+ private maybeActivateImage;
1485
+ private activateImage;
1383
1486
  }
1384
1487
 
1385
1488
  /**
@@ -1469,23 +1572,21 @@ declare class StringLerp extends StringModule {
1469
1572
  private setLerpValue;
1470
1573
  }
1471
1574
 
1472
- /**
1473
- * The `StringProgress` class extends the `StringModule` class and is responsible for
1474
- * managing progress-based behavior for elements during scroll events. It maps specific
1475
- * attributes, initializes objects, and updates their progress based on scroll data.
1476
- */
1477
1575
  declare class StringProgress extends StringModule {
1576
+ protected updateScheduled: boolean;
1577
+ private static readonly PROGRESS_EPSILON;
1478
1578
  constructor(context: StringContext);
1479
- /**
1480
- * Called when an object is initialized.
1481
- */
1482
1579
  initializeObject(globalId: number, object: StringObject, element: HTMLElement, attributes: Record<string, any>): void;
1483
- /**
1484
- * Called on scroll.
1485
- */
1580
+ private recomputeProgress;
1581
+ private applyProgressValue;
1582
+ calculatePositions(object: StringObject, windowSize: number): void;
1486
1583
  onScroll(data: StringData): void;
1487
1584
  onObjectConnected(object: StringObject): void;
1488
- private setUpObject;
1585
+ onScrollMeasure(data: StringData): void;
1586
+ onMutate(): void;
1587
+ private updateObjectProgress;
1588
+ private hasProgressChanged;
1589
+ onObjectDisconnected(object: StringObject): void;
1489
1590
  }
1490
1591
 
1491
1592
  /**
@@ -1495,22 +1596,20 @@ declare class StringProgress extends StringModule {
1495
1596
  * necessary transformations based on scroll progress and viewport size.
1496
1597
  */
1497
1598
  declare class StringParallax extends StringProgress {
1599
+ private updateScheduledTransform;
1600
+ private calculateParallaxForObject;
1498
1601
  constructor(context: StringContext);
1499
1602
  /**
1500
1603
  * Called when an object is initialized.
1501
1604
  */
1502
1605
  initializeObject(globalId: number, object: StringObject, element: HTMLElement, attributes: Record<string, any>): void;
1503
- /**
1504
- * Called on scroll.
1505
- */
1606
+ calculatePositions(object: StringObject, windowSize: number): void;
1506
1607
  onScroll(data: StringData): void;
1507
- /**
1508
- * Called on resize.
1509
- */
1510
1608
  onResize(): void;
1511
- private handleScrollDesktop;
1512
- private handleScrollMobile;
1513
- private scrollHandler;
1609
+ onScrollMeasure(data: StringData): void;
1610
+ onMutate(): void;
1611
+ private calculateDesktopParallax;
1612
+ private calculateMobileParallax;
1514
1613
  }
1515
1614
 
1516
1615
  declare class StringScrollbar extends StringModule {
@@ -1551,6 +1650,7 @@ declare class StringSplit extends StringModule {
1551
1650
  split(element: HTMLElement, options: ISplitOptions): {
1552
1651
  fragment: DocumentFragment;
1553
1652
  result: DocumentFragment;
1653
+ extraProps: Map<string, string>;
1554
1654
  };
1555
1655
  /**
1556
1656
  * Computes a numeric value based on the provided split option, index, and total count.
@@ -1825,41 +1925,45 @@ declare class StringForm extends StringModule {
1825
1925
  getFieldValue(field: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): any;
1826
1926
  }
1827
1927
 
1828
- declare abstract class CursorReactiveModule extends StringModule {
1829
- protected nearOnly: boolean;
1830
- protected emitEveryN: number;
1831
- protected updateThreshold: number;
1832
- private rafFrame;
1833
- constructor(context: StringContext);
1834
- onObjectConnected(object: StringObject): void;
1835
- removeObject(id: string): void;
1836
- onScroll(): void;
1837
- onMouseMove(e: MouseEvent): void;
1838
- onFrame(data: StringData): void;
1839
- protected abstract onPointerDelta(obj: StringObject, dx: number, dy: number, dist: number): void;
1840
- protected abstract onCursorFrame(data: StringData, frame: number): void;
1841
- }
1842
-
1843
1928
  declare class StringScroller extends StringModule {
1844
1929
  constructor(context: StringContext);
1845
1930
  onObjectConnected(object: StringObject): void;
1846
1931
  onObjectDisconnected(object: StringObject): void;
1847
1932
  }
1848
1933
 
1849
- declare class StringImpulse extends StringModule {
1850
- constructor(context: StringContext);
1851
- onObjectConnected(object: StringObject): void;
1852
- onObjectDisconnected(object: StringObject): void;
1853
- onMouseMove(_e?: MouseEvent): void;
1854
- onFrame(_: StringData): void;
1855
- }
1856
-
1857
1934
  declare class StringProgressPart extends StringModule {
1858
1935
  constructor(context: StringContext);
1859
1936
  onObjectConnected(object: StringObject): void;
1860
1937
  onObjectDisconnected(object: StringObject): void;
1861
1938
  }
1862
1939
 
1940
+ type Job = () => void;
1941
+ declare class FrameDOM {
1942
+ private measureQueue;
1943
+ private mutateQueue;
1944
+ private scheduled;
1945
+ measure(fn: Job): void;
1946
+ mutate(fn: Job): void;
1947
+ private schedule;
1948
+ }
1949
+ declare const frameDOM: FrameDOM;
1950
+
1951
+ type StyleValue = string | number;
1952
+ type StyleVars = Record<string, StyleValue>;
1953
+ type StyleProps = Record<string, StyleValue>;
1954
+ declare class StyleTxn {
1955
+ private pendingVars;
1956
+ private pendingProps;
1957
+ private isOpen;
1958
+ begin(): void;
1959
+ setVars(el: Element, vars: StyleVars): void;
1960
+ setProps(el: Element, props: StyleProps): void;
1961
+ run(fn: () => void): void;
1962
+ commit(): void;
1963
+ cancel(): void;
1964
+ }
1965
+ declare const styleTxn: StyleTxn;
1966
+
1863
1967
  declare class StringTune {
1864
1968
  /** Bound handler for the scroll start event */
1865
1969
  private onScrollStartBind;
@@ -1876,6 +1980,7 @@ declare class StringTune {
1876
1980
  /** Bound mouse move handler */
1877
1981
  private onMouseMoveBind;
1878
1982
  private onContainerTransitionEndBind;
1983
+ private onResizeObserverBind;
1879
1984
  /** Singleton instance of StringTune */
1880
1985
  private static i;
1881
1986
  /** Root scrollable element (typically <body>) */
@@ -1908,6 +2013,8 @@ declare class StringTune {
1908
2013
  private centers;
1909
2014
  /** Tracks hover states of string objects. */
1910
2015
  private hoverManager;
2016
+ private observerContainerResize;
2017
+ canRebuild: boolean;
1911
2018
  /**
1912
2019
  * Sets the scroll position manually.
1913
2020
  * This overrides all internal scroll states including target and lerped values.
@@ -1930,7 +2037,9 @@ declare class StringTune {
1930
2037
  * Gets the current scroll position in pixels.
1931
2038
  * This is typically updated every frame.
1932
2039
  */
1933
- get speed(): number;
2040
+ get scrollPosition(): number;
2041
+ get scrollHeight(): number;
2042
+ get containerHeight(): number;
1934
2043
  /**
1935
2044
  * Sets the base scroll speed for smooth scrolling.
1936
2045
  * Typically a value between 0 and 1.
@@ -2037,6 +2146,7 @@ declare class StringTune {
2037
2146
  * @param settings A key-value map of default settings (e.g. 'offset-top': '-10%').
2038
2147
  */
2039
2148
  setupSettings(settings: StringSettings): void;
2149
+ private onResizeObserverEvent;
2040
2150
  private onContainerTransitionEnd;
2041
2151
  /**
2042
2152
  * Handles mouse move event and dispatches it to cursor and modules.
@@ -2096,6 +2206,12 @@ declare class StringTune {
2096
2206
  * @param offset - Optional. The number of pixels to offset from the target element's top position. Defaults to 0.
2097
2207
  */
2098
2208
  scrollToElement(selector: string, offset?: number): void;
2209
+ scrollTo(position: number): void;
2210
+ /**
2211
+ * Forces center cache recalculation for all tracked objects.
2212
+ * Useful when DOM geometry changes outside of StringTune's control.
2213
+ */
2214
+ invalidateCenters(): void;
2099
2215
  /**
2100
2216
  * Cleans up the system, removes all event listeners, stops the loop,
2101
2217
  * and destroys modules and event subscriptions.
@@ -2103,4 +2219,4 @@ declare class StringTune {
2103
2219
  destroy(): void;
2104
2220
  }
2105
2221
 
2106
- export { CursorReactiveModule, type ScrollMarkRule as ScrollTriggerRule, StringAnchor, type StringContext, StringCursor, StringData, StringDelayLerpTracker, StringFPSTracker, StringForm, StringGlide, StringImpulse, StringLazy, StringLerp, StringLerpTracker, StringLoading, StringMagnetic, StringModule, StringObject, StringParallax, StringPositionTracker, StringProgress, StringProgressPart, StringResponsive, StringScrollbar, StringScroller, StringSequence, StringSplit, StringTune, StringVideoAutoplay, StringTune as default };
2222
+ export { CursorReactiveModule, type ScrollMarkRule as ScrollTriggerRule, StringAnchor, type StringContext, StringCursor, StringData, StringDelayLerpTracker, StringFPSTracker, StringForm, StringGlide, StringImpulse, StringLazy, StringLerp, StringLerpTracker, StringLoading, StringMagnetic, StringModule, StringObject, StringParallax, StringPositionTracker, StringProgress, StringProgressPart, StringResponsive, StringScrollbar, StringScroller, StringSequence, StringSplit, StringSpotlight, StringTune, StringVideoAutoplay, StringTune as default, frameDOM, styleTxn };