UNPKG

@fiddle-digital/string-tune

Version:

StringTune is a cutting-edge JavaScript library designed to deliver high-performance, modular web effects. Whether you're looking to add smooth parallax scrolling, dynamic cursor interactions, progress tracking, or autoplay videos, StringTune empowers dev

1,456 lines (1,410 loc) 83.7 kB
/** * Represents a map of configurable settings for the StringTune system. * Each key corresponds to a setting name (e.g. 'offset-top', 'parallax', etc.). * * These settings can be used as: * - Global fallbacks via `setupSettings` * - Module-specific overrides via `use(MyModule, settings)` * * The values are typically string-based, but can also be numbers or booleans. */ interface StringSettings { [key: string]: string | number | boolean; } interface ModuleLifecyclePermissionsItem { rebuild: { width: boolean; height: boolean; scrollHeight: boolean; }; } declare class ModuleLifecyclePermissions { desktop: ModuleLifecyclePermissionsItem; mobile: ModuleLifecyclePermissionsItem; } /** * Reactive cursor data for raw, target, smoothed and step deltas. */ declare class CursorState { /** * Target X position of the cursor (e.g., from `mousemove`) */ targetX: number; /** * Target Y position of the cursor. */ targetY: number; /** * Smoothed X position after applying lerp. */ smoothedX: number; /** * Smoothed Y position after applying lerp. */ smoothedY: number; /** * Delta step between current and target X (used internally for lerp). */ stepX: number; /** * Delta step between current and target Y. */ stepY: number; /** * Velocity in X direction, calculated from smoothed position. */ velocityX: number; /** * Velocity in Y direction, calculated from smoothed position. */ velocityY: number; } /** * Global Three.js or rendering context reference. */ declare class RenderState { /** Instance of Three.js or another render context */ threeInstance: any; } type ScrollDirection = 'vertical' | 'horizontal'; type ScrollMode = 'smooth' | 'disable' | 'default'; /** * Describes current scroll-related state for all calculations and modules. */ declare class ScrollState { /** Target scroll value — where we want to scroll to (used in smooth scroll) */ target: number; /** Current scroll value (actual scroll position) */ current: number; /** Transformed current scroll value (with transform by scroll container) */ transformedCurrent: number; /** Delta between frames (used for animation / velocity) */ delta: number; /** Interpolated scroll value for smooth transitions */ lerped: number; /** Displacement value (similar to lerped, but used for other animations) */ displacement: number; /** Whether scroll direction is downward */ isScrollingDown: boolean; /** Top screen scroll position */ topPosition: number; /** Bottom screen scroll position */ bottomPosition: number; /** Scroll direction (vertical / horizontal) */ direction: ScrollDirection; /** Scroll container element */ elementContainer: HTMLElement; /** Scroll container element */ scrollContainer: HTMLElement | Window; /** Scroll container element */ container: HTMLElement; /** * Currently active scroll mode. * Can be 'smooth', 'default', or 'disable'. */ mode: ScrollMode; /** * Scroll mode to use on mobile devices. * Can be 'smooth', 'default', or 'disable'. */ modeMobile: ScrollMode; /** * Scroll mode to use on desktop devices. * Can be 'smooth', 'default', or 'disable'. */ modeDesktop: ScrollMode; /** * Base scroll speed used for calculating smooth scrolling. * Typically a small value between 0 and 1. */ speed: number; /** * Acceleration factor used for scroll easing or velocity-based animations. * Also typically a value between 0 and 1. */ speedAccelerate: number; } declare class SystemState { fpsTracker: boolean; positionTracker: boolean; } /** * Represents the time-related state of the current and previous animation frames. * * Useful for calculating delta time, total elapsed time, and implementing * time-based animations or physics. */ declare class TimeState { /** * Timestamp of the current animation frame in milliseconds. * This value is typically obtained via `performance.now()`. */ now: number; /** * Timestamp of the previous animation frame in milliseconds. */ previous: number; /** * Time difference between the current and previous frames in milliseconds. * Commonly used to calculate animation progress. */ delta: number; /** * Total time elapsed since the start of the animation or system in milliseconds. */ elapsed: number; } /** * Describes current viewport size and scaling. */ declare class ViewportState { /** Width of the visible window */ windowWidth: number; /** Height of the visible window */ windowHeight: number; /** Full scroll width (content width inside scroll container) */ contentWidth: number; /** Full scroll height (content height inside scroll container) */ contentHeight: number; /** Screen scale ratio for width (e.g. device pixel ratio or zoom level) */ scaleWidth: number; /** Screen scale ratio for height */ scaleHeight: number; transformScale: number; baseRem: number; } /** * Container for global dynamic state used throughout the string-tune system. * Provides access to live scroll, viewport, cursor, and render states, * which are updated each frame and shared across modules and tools. */ declare class StringData { /** * Scroll-related state object. * Contains live values like `target`, `current`, `delta`, `direction`, and more. * Used for scroll-based animations, transitions, and effects. */ scroll: ScrollState; /** * Viewport-related state object. * Holds dimensions like window size, content size, aspect ratios, and more. * Useful for layout calculations, unit parsing, and element positioning. */ viewport: ViewportState; /** * Cursor-related state object. * Tracks cursor position, velocity, movement, and derived values. * Can be used for pointer interactions, proximity effects, and hover states. */ cursor: CursorState; /** * Render-related state object. * Stores data related to rendering context (e.g. WebGL, Three.js), * such as shared materials, textures, or active render frame data. */ render: RenderState; /** * Time-related state object. * Tracks frame timings, including current timestamp, delta between frames, * and total elapsed time since animation start. * Useful for time-based animations, easing, frame consistency, and syncing logic. */ time: TimeState; system: SystemState; } /** * Base interface for scroll/interaction modules in the StringScroll system. */ interface IStringModule { permissions: ModuleLifecyclePermissions; /** Cleans up all internal state and detaches from the system. */ destroy(): void; /** Called once when the module is initialized. */ onInit(): void; /** Called on each frame with current scroll and state data. */ onFrame(data: StringData): void; /** Called when the window or layout is resized. */ onResize(): void; /** Called when the layout is resize width. */ onResizeWidth(): void; /** Called when the system rebuilds the DOM (e.g. after mutations). */ onDOMRebuild(): void; /** Called when scroll position changes. */ onScroll(data: StringData): void; /** Called when scroll change diraction. */ onDirectionChange(): void; /** Called when scrolling starts (user begins scroll). */ onScrollStart(): void; /** Called when scrolling ends (user stops scroll). */ onScrollStop(): void; /** Called when scroll direction changes (e.g. up → down). */ onScrollDirectionChange(): void; /** Called when overall scroll axis changes (vertical ↔ horizontal). */ onAxisChange(): void; /** Called when device type changes (e.g. desktop ↔ mobile). */ onDeviceChange(): void; /** Called when scroll-related system settings or params are updated. */ onScrollConfigChange(): void; /** * Called when global system settings are updated via `setupSettings`. * Modules can override this to re-read default values, refresh configs, * or reapply any cached parameters that depend on settings. * * This method is triggered after global fallback settings are merged into context. * * Example use cases: * - Recalculating default lerp, anchor, radius, etc. * - Updating internal thresholds or animation values. * - Reacting to system-wide design changes. */ onSettingsChange(): void; /** Called on mouse move (for interaction-based modules). */ onMouseMove(event: MouseEvent): void; /** Called on wheel scroll (separate from general scroll). */ onWheel(event: WheelEvent): void; /** * Called when the DOM mutates — useful for detecting new or removed elements. */ onDOMMutate(added: NodeList, removed: NodeList): void; /** * Triggered when an object was successfully connected. */ onObjectConnected(object: StringObject): void; /** * Called when a DOM element is detected as a potential interactive object. */ initializeObject(globalId: number, object: StringObject, element: HTMLElement, attributes: Record<string, any>): void; calculatePositions(object: StringObject, windowSize: number): void; /** * Check if a module should connect to a given object. */ canConnect(object: StringObject): boolean; /** * Called to connect this module to the object. */ connectObject(object: StringObject): void; /** * Called when the cursor or interaction enters an object's area. */ enterObject(id: string, object: StringObject): void; /** * Called when the interaction leaves the object's area. */ exitObject(id: string): void; addObject(id: string, object: StringObject): void; removeObject(id: string): void; } type EventCallback<T = any> = (payload: T) => void; /** * Manages custom event subscriptions and dispatching. * Allows multiple listeners per event and supports optional `id` suffixing. */ declare class EventManager { private listeners; private stateEvents; private lastPayloads; constructor(); /** * Subscribes to an event. * Optionally appends an `id` to the event name for namespacing. * * @param eventName The base event name (e.g. "scroll", "update"). * @param callback The function to call when the event is emitted. * @param id Optional unique identifier to scope the event (e.g. element ID). */ on<T = any>(eventName: string, callback: EventCallback<T>, id?: string | null): void; /** * Unsubscribes from a specific event listener. * Must match the original `eventName`, `callback`, and optional `id`. * * @param eventName The base event name to unsubscribe from. * @param callback The callback function to remove. * @param id Optional identifier used when subscribing. */ off<T = any>(eventName: string, callback: EventCallback<T>, id?: string): void; /** * Emits an event with an optional payload. * All matching listeners will be called. * * @param eventName The full event name (must include `id` if used). * @param payload Optional data passed to event listeners. */ emit<T = any>(eventName: string, payload?: T): void; /** * Subscribes to a per-object progress event. * @param id The object ID. * @param callback The callback to handle progress value. */ onProgress(id: string, callback: EventCallback<number>): void; /** * Emits a per-object progress event. * @param id The object ID. * @param value The progress value. */ emitProgress(id: string, value: number): void; /** * Subscribes to a per-object in-view event. * @param id The object ID. * @param callback The callback to handle visibility. */ onInview(id: string, callback: EventCallback<boolean>): void; /** * Emits a per-object in-view event. * @param id The object ID. * @param visible Whether the object is visible. */ emitInview(id: string, visible: boolean): void; /** * Subscribes to the global scroll event. * @param callback The callback to handle scroll value. */ onScroll(callback: EventCallback<number>): void; /** * Emits the global scroll event. * @param value The scroll value. */ emitScroll(value: number): void; /** * Subscribes to the global update event. * @param callback The callback to handle update. */ onUpdate(callback: EventCallback<void>): void; /** * Emits the global update event. */ emitUpdate(): void; /** * Clears all listeners for a specific event. * * @param eventName The full event name (including optional `id`). */ clear(eventName: string): void; /** * Clears all registered events. */ clearAll(): void; } type MirrorEasingFn = (value: number) => number; /** * Lightweight wrapper that mirrors a primary StringObject while keeping * its own easing and state. Intended for elements linked via * `[string-copy-from]`. */ declare class StringMirrorObject { private parent; readonly id: string; readonly htmlElement: HTMLElement; private properties; private easingFn?; constructor(id: string, element: HTMLElement, parent: StringObject); get parentObject(): StringObject; setProperty<T>(key: string, value: T): void; getProperty<T>(key: string): T; setEasing(easing: MirrorEasingFn | null | undefined): void; getEasing(): MirrorEasingFn | undefined; /** * Returns eased progress using mirror easing (if set) or fallback. */ applyProgress(rawProgress: number, fallback?: MirrorEasingFn): number; } /** * Internal class representing a DOM-bound interactive object. * Connected to modules and holds its own internal state. */ declare class StringObject { /** * The DOM element this object wraps. */ htmlElement: HTMLElement; /** * Unique global ID assigned by the system. */ id: string; /** * Space-separated list of all attribute keys associated with this object. */ keys: string[]; /** * Mirror objects linked via `string-copy-from`. */ private mirrors; /** * Internal key-value store of dynamic object properties (like offsets, progress, etc.). */ private properties; /** * Modules currently connected to this object. */ private modules; /** * Manages and handles events for the object. * Provides functionality to register, trigger, and manage event listeners. */ events: EventManager; constructor(id: string, element: HTMLElement); /** * Stores a property value for this object. * @param key - Property name * @param value - Value to store */ setProperty<T>(key: string, value: T): void; /** * Retrieves a previously stored property value. * @param key - Property name * @returns The value or null if not set */ getProperty<T>(key: string): T; /** * Marks this object as "active" (usually on intersection/scroll enter). */ enter(): void; /** * Marks this object as "inactive" (usually on intersection/scroll leave). */ leave(): void; /** * Removes the current object by iterating through all associated modules * and invoking their `removeObject` method with the object's ID. * * This method ensures that the object is properly removed from all * modules it is associated with. */ remove(): void; /** * Shows the object, applies visual class and notifies connected modules. */ show(): void; /** * Hides the object, removes visual class (if repeat is enabled), and notifies modules. */ hide(): void; /** * Connects a module to this object if not already connected. * @param module - The module to connect */ connect(module: IStringModule): void; addMirror(mirror: StringMirrorObject): void; removeMirror(id: string): void; get mirrorObjects(): StringMirrorObject[]; get connects(): HTMLElement[]; } declare class CenterCache { private map; private all; attach(obj: StringObject): void; detach(obj: StringObject): void; invalidate(id: string): void; invalidateAll(): void; getCenter(obj: StringObject): { cx: number; cy: number; }; } declare class HoverTracker { private active; private subs; track(obj: StringObject): void; untrack(obj: StringObject): void; isActive(obj: StringObject): boolean; activeObjects(): StringObject[]; } /** * Base interface for injectable core tools in the String system. * Each tool takes input and returns output (transform, extract, calculate). */ interface IStringTool<Input = any, Output = any> { /** * Process input and return result. * Can be a transformation, extraction, interpolation, etc. * * @param input - Any input relevant to the tool. * @returns Output result from the tool. */ process(input: Input): Output; } /** * Input for `BoundingClientRectTool`. */ interface BoundingClientRectInput { /** The DOM element to retrieve bounding rect from. */ element: HTMLElement; } /** * Tool for accessing `getBoundingClientRect()` in a consistent, testable way. */ declare class BoundingClientRectTool implements IStringTool<BoundingClientRectInput, DOMRect> { /** * @returns The bounding client rect of the provided element. */ process({ element }: BoundingClientRectInput): DOMRect; } interface DOMAttributeInput { element: HTMLElement; key: string; fallback?: string | null; } declare class DOMAttributeTool implements IStringTool<DOMAttributeInput, string | null> { /** * Retrieves the value of either `string-${key}` or `data-string-${key}` attribute. * * @example key = "offset-tom" → tries: * - element.getAttribute("string-offset-tom") * - element.getAttribute("data-string-offset-tom") */ process({ element, key, fallback }: DOMAttributeInput): string | null; } /** * Input for retrieving a value from a key-value object or dataset-like structure. */ interface RecordAttributeInput { /** Source object to read from (e.g. dataset or plain record). */ record: Record<string, any>; /** Key to look up (without `"data-"` prefix). */ name: string; /** Fallback value if both keys are missing. */ fallback?: any; } /** * Retrieves a value from an object or dataset-like structure. * Tries `record[name]` first, then `record["data-" + name]`, or returns fallback. */ declare class RecordAttributeTool implements IStringTool<RecordAttributeInput, any> { /** * @returns Value from the record or fallback. */ process({ record, name, fallback }: RecordAttributeInput): any; } /** * Input for removing transform effects from an element's bounding box. */ interface TransformNullifyInput { /** The DOM element whose CSS transform should be nullified. */ element: HTMLElement; } /** * Output with corrected bounding box values. */ interface TransformNullifyOutput { /** Top position without transform effects. */ top: number; /** Left position without transform effects. */ left: number; /** Width without transform scaling. */ width: number; /** Height without transform scaling. */ height: number; } /** * Computes the true bounding box of a DOM element, * nullifying CSS `transform: matrix(...)` effects. */ declare class TransformNullifyTool implements IStringTool<TransformNullifyInput, TransformNullifyOutput> { /** * @returns Element position and size without transform influence. */ process({ element }: TransformNullifyInput): TransformNullifyOutput; } /** * Input for calculating the position of an element relative to a container. */ interface RelativePositionInput { /** The DOM element whose position should be calculated. */ element: HTMLElement; /** Optional container to measure against. Defaults to `document.body`. */ container?: HTMLElement; } /** * Output: relative position in pixels. */ interface RelativePositionOutput { /** Distance from the top of the container. */ top: number; /** Distance from the left of the container. */ left: number; } /** * Calculates an element's position relative to a container. * Uses `TransformNullifyTool` to account for CSS transforms. */ declare class RelativePositionTool implements IStringTool<RelativePositionInput, RelativePositionOutput> { /** Optional tool for CSS transform-neutral measurements. */ private transformTool; constructor( /** Optional tool for CSS transform-neutral measurements. */ transformTool?: TransformNullifyTool); /** * @returns Relative top/left position of element within container. */ process({ element, container }: RelativePositionInput): RelativePositionOutput; } interface LerpInput { /** Starting value of the interpolation. */ from: number; /** Target value to interpolate towards. */ to: number; /** Interpolation progress between 0 (start) and 1 (end). */ progress: number; } declare class LerpTool implements IStringTool<LerpInput, number> { /** * Calculates the linear interpolation between two values. * @returns Interpolated value. */ process({ from, to, progress }: LerpInput): number; } /** * Input for parsing unit-based strings into numeric pixel values. */ interface UnitParserInput { /** Unit string, e.g. `"20px"`, `"50%"`, `"1.5rem"`, or `"selfHeight"` */ value: string; /** DOM element used for `"selfHeight"` calculation */ element: HTMLElement; /** Viewport height in pixels (for percentage conversion) */ viewportHeight: number; /** Root font size in pixels (for rem conversion) */ baseRem: number; boundingRect: DOMRect; } /** * Converts unit-based strings to numeric pixel values. * Supports `px`, `%`, `rem`, and `"selfHeight"` keyword. Handles negatives. */ declare class UnitParserTool implements IStringTool<UnitParserInput, number> { /** * @returns Numeric value in pixels (positive or negative). */ process({ value, element, viewportHeight, baseRem, boundingRect }: UnitParserInput): number; } /** * Input for adaptive lerp factor calculation. * Maps a speed-like value to a lerp factor, where: * - lower speed ⇒ slower smoothing (higher lerp factor) * - higher speed ⇒ faster response (lower lerp factor) */ interface AdaptiveLerpInput { /** Current value (e.g., speed or delta). */ value: number; /** Minimum input threshold (default: 0.1) */ inMin?: number; /** Maximum input threshold (default: 1.0) */ inMax?: number; /** Output when input is at minimum (default: 0.65) */ outMax?: number; /** Output when input is at maximum (default: 0.05) */ outMin?: number; } /** * Converts a numeric input (like velocity) into an adaptive lerp factor. * Useful for scroll or speed-based smoothing effects. */ declare class AdaptiveLerpTool implements IStringTool<AdaptiveLerpInput, number> { /** * @returns A remapped lerp factor from `outMax` to `outMin`. */ process({ value, inMin, inMax, outMin, outMax }: AdaptiveLerpInput): number; } /** * Input for origin parser. * Supports static values or `random(...)` expressions. */ interface OriginInput { /** Raw origin string, e.g. `'center'` or `'random(top, bottom)'`. */ value: string; } /** * Input for parsing origin to normalized coordinates. * Supports formats like `'left top'`, `'center center'`, `'50% 50%'`, `'35% 76%'`. */ interface OriginToNormalizedInput { /** Raw origin string, e.g. `'left top'`, `'center'`, `'50% 25%'`. */ value: string; } /** * Output: normalized origin coordinates (0-1 range). */ interface NormalizedOrigin { /** Normalized X coordinate (0 = left, 0.5 = center, 1 = right). */ x: number; /** Normalized Y coordinate (0 = top, 0.5 = center, 1 = bottom). */ y: number; } /** * Tool that parses origin strings. * Allows static values like `'center'`, or expressions like `'random(...)'` to select one randomly. * Also provides `toNormalized()` method to convert origin strings to `{ x, y }` coordinates. */ declare class OriginParserTool implements IStringTool<OriginInput, string> { /** * @returns Parsed string value (static or randomly chosen). */ process({ value }: OriginInput): string; /** * Parses an origin string to normalized `{ x, y }` coordinates (0-1 range). * * Supported formats: * - Single keyword: `'center'`, `'top'`, `'left'`, etc. * - Two keywords: `'left top'`, `'right bottom'`, `'center center'` * - Percentages: `'50% 50%'`, `'0% 100%'`, `'35% 76%'` * - Mixed: `'left 25%'`, `'50% top'` * * @param input - The origin string to parse. * @returns Normalized `{ x, y }` coordinates. */ toNormalized({ value }: OriginToNormalizedInput): NormalizedOrigin; /** * Parses a single value (keyword or percentage) to a normalized number. */ private parseValue; } interface StringColor { r: number; g: number; b: number; a: number; } /** * Input for parsing color strings into RGBA format. */ interface ColorParserInput { /** Color string in hex, rgb[a], or hsl[a] format. */ value: string; } /** * Parses a CSS color string (`#fff`, `rgb(...)`, `hsl(...)`, etc.) * into an object with `r`, `g`, `b`, `a` values. */ declare class ColorParserTool implements IStringTool<ColorParserInput, StringColor> { /** * @returns RGBA object parsed from color string. */ process({ value }: ColorParserInput): StringColor; private hslToRgb; } /** * Input parameters for EasingFunctionTool. */ interface EasingFunctionInput { /** * The easing string. * Can be: 'linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out', or 'cubic-bezier(...)' */ easing: string; } /** * Output of the easing function: receives t in [0,1] and returns eased value. */ type EasingFunctionOutput = (t: number) => number; /** * Tool for parsing easing strings into easing functions. * Supports standard keywords (`ease-in`, `ease-out`, etc.) and `cubic-bezier(...)` expressions. */ declare class EasingFunctionTool implements IStringTool<EasingFunctionInput, EasingFunctionOutput> { private namedCurves; /** * Parses an easing string and returns a corresponding easing function. */ process({ easing }: EasingFunctionInput): EasingFunctionOutput; /** * Generates a cubic-bezier easing function. * Ported from https://github.com/gre/bezier-easing (MIT) */ private cubicBezier; } /** * Input parameters for calculating magnetic pull factor. */ interface MagneticPullInput { /** Distance between pointer and element center (px). */ distance: number; /** Max distance within which magnetic pull is active. */ radius: number; /** Strength of the magnetic pull (0–1 recommended). */ strength: number; } /** * Output: factor to multiply by direction vector (dx/dy) to get magnetic offset. */ type MagneticPullOutput = number; /** * Tool for calculating magnetic attraction based on distance to element. * Returns a scalar value (0..strength) depending on proximity. */ declare class MagneticPullTool implements IStringTool<MagneticPullInput, MagneticPullOutput> { /** * Returns a pull factor based on distance to target within a radius. * @param input - Magnetic pull parameters. * @returns A multiplier (typically < 1) to apply to dx/dy. */ process({ distance, radius, strength }: MagneticPullInput): number; } /** * Input parameters for `LerpColorTool`. */ interface LerpColorInput { /** * Starting color as an object `{ r, g, b, a }` where each value is in the range `0–1`. */ from: StringColor; /** * Target color as an object `{ r, g, b, a }` where each value is in the range `0–1`. */ to: StringColor; /** * Interpolation progress from `0` (start) to `1` (end). */ progress: number; } /** * Tool for linearly interpolating between two RGBA colors using `StringColor` format. * Each channel (`r`, `g`, `b`, `a`) is interpolated independently. * Returns a new `StringColor` with the interpolated values. */ declare class LerpColorTool implements IStringTool<LerpColorInput, StringColor> { /** * Performs linear interpolation between two `StringColor` values. * * @param input.from - The starting color `{ r, g, b, a }`. * @param input.to - The target color `{ r, g, b, a }`. * @param input.progress - A number from `0` to `1` indicating interpolation progress. * @returns Interpolated color as a new `StringColor`. */ process({ from, to, progress }: LerpColorInput): StringColor; } interface StringVector { x: number; y: number; } /** * Input parameters for LerpVector2Tool. */ interface LerpVector2Input { /** * Starting vector value `{ x, y }`. */ from: StringVector; /** * Target vector value `{ x, y }`. */ to: StringVector; /** * Interpolation progress from `0` (start) to `1` (end). */ progress: number; } /** * Tool for linearly interpolating between two 2D vectors. * Useful for cursor smoothing, UI element animations, and motion blending. */ declare class LerpVector2Tool implements IStringTool<LerpVector2Input, StringVector> { /** * Calculates the interpolated vector between `from` and `to`. * * @param input.from - The starting vector `{ x, y }`. * @param input.to - The target vector `{ x, y }`. * @param input.progress - Interpolation progress from `0` (start) to `1` (end). * @returns Interpolated vector `{ x, y }`. */ process({ from, to, progress }: LerpVector2Input): { x: number; y: number; }; } /** * Input for parsing the transform string to extract scale. */ interface TransformParserInput { /** CSS transform string (e.g., "matrix(0.5, 0, 0, 0.5, 10, 20)", "scale(0.5)", "none"). */ value: string; } /** * Parses a CSS transform string to extract the primary scale factor. * Assumes uniform scale or extracts the X-axis scale factor from matrix/scale functions. */ declare class TransformScaleParserTool implements IStringTool<TransformParserInput, number> { /** * Processes the transform string and extracts the scale factor. * @returns Numeric scale factor (defaults to 1 if no scale transform is found or parsing fails). */ process({ value }: TransformParserInput): number; } /** * Represents a single parsed option item definition * (e.g., the result of parsing '[center]' or '[random(0,10)|abs]'). */ interface ISplitOptionItem { /** The alignment type ('start', 'center', 'end', 'random'). */ align: string; /** Optional parameters for random alignment. */ random?: { min: number; max: number; }; /** Flag indicating if the absolute value should be used. */ abs?: boolean; } /** * Represents the fully parsed options from the string-split attribute. * Holds arrays of option definitions for each split type. */ interface ISplitOptions { line?: ISplitOptionItem[]; word?: ISplitOptionItem[]; char?: ISplitOptionItem[]; charLine?: ISplitOptionItem[]; charWord?: ISplitOptionItem[]; wordLine?: ISplitOptionItem[]; } /** * Input interface for the SplitOptionsParserTool. */ interface SplitOptionsParserInput { /** * The raw string value from the 'string-split' attribute (or similar). * Can be null if the attribute is not present. */ attributeValue: string | null; } /** * Tool responsible for parsing the string value of a split attribute * (e.g., "line[center]|char[random(0,10)|abs]") into a structured * ISplitOptions object. * Implements the IStringTool interface. */ declare class SplitOptionsParserTool implements IStringTool<SplitOptionsParserInput, ISplitOptions> { /** * Parses the attribute string into an ISplitOptions object. * Handles splitting by '|', parsing prefixes (word-, char-), main types (line, word, char), * and parameters within brackets (align, random, abs). * * @param input - An object containing the attributeValue string (can be null). * @returns An ISplitOptions object representing the parsed rules. * Returns an object with empty arrays if the attributeValue is null or empty. */ process({ attributeValue }: SplitOptionsParserInput): ISplitOptions; /** * Parses an array of string parameters (extracted from within brackets `[...]`). * Determines alignment, random settings, and absolute flag. * Example input: ['center'], ['random(0, 10)', 'abs'] * * @param params - An array of string parameters. * @returns An ISplitOptionItem object representing the parsed parameters. */ private parseParamsArray; } interface RuleParserInput { value: string; } interface RuleParserResult { key: string; params?: string[]; } declare class RuleParserTool implements IStringTool<RuleParserInput, RuleParserResult[]> { process({ value }: RuleParserInput): RuleParserResult[]; } interface ValidationContext { fieldKey?: string; values?: Record<string, any>; getValue?: (key: string) => any; } interface ValidateInput { rules: RuleParserResult[]; value: any; type?: "input" | "beforeinput"; context?: ValidationContext; } interface ValidationResult { valid: boolean; errors: string[]; } type ValidatorFn = (value: any, params?: string[], context?: ValidationContext) => boolean; declare class ValidationTool implements IStringTool<ValidateInput, ValidationResult> { process({ rules, value, type, context }: ValidateInput): ValidationResult; inputValidators: Record<string, ValidatorFn>; beforeInputValidators: Record<string, ValidatorFn>; getErrorMessage(key: string, params?: string[]): string; private validateMimes; private validateMaxSize; private extractFiles; private isMimeAllowed; private getFileExtension; private compareDates; private resolveDateReference; private toDate; private testByRegex; private normalizeRegex; private getContextValue; private areValuesEqual; private isIPv4; private isIPv6; } /** * Interface describing all available tools used inside modules. */ interface StringToolsContainer { /** Tool for reading DOM attributes (including data-*). */ domAttribute: DOMAttributeTool; /** Tool for reading attributes from a plain JS object or dataset. */ recordAttribute: RecordAttributeTool; /** Tool for calculating the relative position between two elements. */ relativePosition: RelativePositionTool; /** Tool that nullifies the effect of CSS transform matrix. */ transformNullify: TransformNullifyTool; /** Tool that wraps getBoundingClientRect with consistent output. */ boundingClientRect: BoundingClientRectTool; /** Tool for parsing string-based values like '50%', '2rem', 'selfHeight'. */ unitParser: UnitParserTool; /** Tool for performing linear interpolation (lerp). */ lerp: LerpTool; /** * Tool for adaptive interpolation based on dynamic input value. * Useful when smoothing cursor speed, scroll velocity, etc. */ adaptiveLerp: AdaptiveLerpTool; /** * Tool for parsing origin strings. * Supports values like `'top'`, `'center'`, or random expressions like `'random(top, bottom)'`. */ originParser: OriginParserTool; /** * Tool for parsing CSS color strings into { r, g, b, a } format. * Supports `#hex`, `rgb[a](...)`, `hsl[a](...)` inputs. */ colorParser: ColorParserTool; /** * Tool for validating strings using rules like `required`, `minLength`, `email`, etc. * Returns validation status, error code, and optional message. */ validation: ValidationTool; /** * Tool for parsing CSS-like easing strings into easing functions. * Supports keywords like `'ease'`, `'linear'`, and full `cubic-bezier(...)` expressions. */ easingFunction: EasingFunctionTool; /** * Tool for calculating magnetic offset strength based on proximity to pointer. */ magneticPull: MagneticPullTool; /** * Tool for interpolating between two RGBA colors. * Accepts `from` and `to` colors as `{ r, g, b, a }`, and a `progress` value from `0` to `1`. * Returns an interpolated `StringColor` object. */ lerpColor: LerpColorTool; /** * Tool for interpolating between two 2D vectors. * Accepts `{ x, y }` objects and a `progress` value between `0` and `1`. * Returns a new `{ x, y }` vector. */ lerpVector: LerpVector2Tool; transformScaleParser: TransformScaleParserTool; optionsParser: SplitOptionsParserTool; ruleParser: RuleParserTool; } /** * Shared context object passed to all modules and core controllers. * * Provides access to shared tools, data, settings, and event handling. */ interface StringContext { /** * Collection of utility tools (e.g. lerp, dom parser, unit converter). */ tools: StringToolsContainer; /** * Reactive state container including scroll, viewport, cursor, etc. */ data: StringData; /** * Global configuration settings for modules and system behavior. */ settings: StringSettings; /** * Centralized event emitter and listener system. */ events: EventManager; /** * Caches the center positions of string objects. */ centers: CenterCache; /** * Tracks hover states of string objects. */ hover: HoverTracker; } type AttributeType = "string" | "number" | "boolean" | "json" | "dimension" | "breakpoint-dimension" | "tuple" | "easing" | "color" | { type: "enum"; values: string[]; }; /** * Represents the fallback value for an attribute mapping. * It can either be a static value or a function that dynamically * computes a value based on the element, object, and its bounding rectangle. */ type AttributeFallback = any | ((context: { element: HTMLElement; object: StringObject; boundingRect: DOMRect; }) => any); /** * Describes how a specific attribute should be mapped from an HTML element * to internal module data. Each mapping defines the attribute key, its expected type, * an optional fallback value, and an optional transformation function. */ type AttributeMapping = { /** Attribute name (without `string-` prefix). */ key: string; /** The type used for parsing this attribute (e.g., 'number', 'boolean', 'tuple'). */ type: AttributeType; /** * Optional fallback value if the attribute is not present on the element. * Can be a static value or a dynamic function. */ fallback?: AttributeFallback; /** * Optional transformation function to apply to the parsed attribute value. * Useful for converting parsed data into a more usable format. */ transform?: (value: any) => any; }; /** * Base class for a module used in the string-tune system. * Extend this class to create custom modules that respond to scroll, resize, input, etc. */ declare class StringModule implements IStringModule { /** * List of attribute names this module should automatically read * from the DOM element and assign to the object properties. * Example: ["offset-top", "offset-bottom"] */ protected attributesToMap: AttributeMapping[]; /** * A map that associates string keys with `StringObject` instances. * This map is used to manage and track `StringObject` instances on a page. */ protected objectMapOnPage: Map<string, StringObject>; /** * A protected array that holds the collection of `StringObject` instances * currently present on the page. */ protected objectsOnPage: StringObject[]; /** * A map of all entered objects by their unique ID. */ protected objectMap: Map<string, StringObject>; /** * A flat array of all connected objects. */ protected objects: StringObject[]; /** * The HTML attribute key that identifies objects this module is responsible for. */ protected htmlKey: string; /** * Module type ID used internally to categorize module behavior. */ protected _type: number; /** * Returns the type of the module. * Type 1 = core module, type 2 = UI module. */ get type(): number; /** * Tools container providing utilities for attribute parsing, unit conversion, etc. * Acts as a dependency injection hub for core IStringTool implementations. */ protected tools: StringToolsContainer; /** * Shared global data object containing scroll state, viewport info, cursor position, etc. * Used for calculations within lifecycle hooks like `onScroll`, `onFrame`, and `onResize`. */ protected data: StringData; /** * Configuration object specific to the current module. * Passed in during module registration or initialization. */ protected settings: Record<string, any>; /** * Event hub for communication between modules or systems. * Supports custom event emitting, listening, and unsubscription. */ protected events: EventManager; /** * Cache for storing and managing object centers. */ protected centers: CenterCache; /** * Tracker for managing hover states of objects. */ protected hover: HoverTracker; permissions: ModuleLifecyclePermissions; constructor(context: StringContext); /** * Initializes a `StringObject` by mapping attributes from an HTML element * and applying transformations as needed. * * @param globalId - A unique identifier for the object being initialized. * @param object - The `StringObject` instance to be initialized. * @param element - The HTML element from which attributes are extracted. * @param attributes - A record of additional attributes to be used during initialization. * * The method performs the following steps: * 1. Retrieves the bounding rectangle of the provided HTML element. * 2. Iterates over a predefined list of attributes to map. * 3. Resolves fallback values for attributes, either from the provided attributes, * settings, or a fallback function. * 4. Processes and parses the raw attribute values based on their expected type. * 5. Applies optional transformations to the parsed values. * 6. Sets the processed attributes as properties on the `StringObject` instance. */ initializeObject(globalId: number, object: StringObject, element: HTMLElement, attributes: Record<string, any>): void; /** * Calculates object-specific positions or metrics based on the current layout or scroll state. * This method is intended to be overridden in subclasses if the module needs to precompute * layout-dependent values (e.g. parallax offsets, trigger zones, distances). * * @param object The `StringObject` instance whose positions are being calculated. * @param windowSize The current window height or width (depending on scroll axis). */ calculatePositions(object: StringObject, windowSize: number): void; /** * Parses a raw DOM attribute value into the correct type based on mapping. * Handles fallback resolution, transformation, and special units. * * @param value Raw attribute string from DOM. * @param type The expected attribute type (e.g. number, boolean, dimension). * @param context Optional helper values like element or viewport size. * @returns The parsed and transformed value. */ protected parseAttribute(value: string | null, type: AttributeType, context?: { element?: HTMLElement; boundingRect?: DOMRect; viewportHeight?: number; baseRem?: number; }): any; /** * Determines whether the module should attach to a given object, * based on the presence of the module's `htmlKey` in the object keys. * * @param object The target object to test. * @returns `true` if the module can connect, `false` otherwise. */ canConnect(object: StringObject): boolean; /** * Registers the module on a given object, adds the object to internal list, * and triggers connection logic. * * @param object The object to connect to. */ connectObject(object: StringObject): void; /** * Registers the object internally when it enters the module’s scope. */ enterObject(id: string, object: StringObject): void; /** * Unregisters the object when it leaves the module’s scope. */ exitObject(id: string): void; /** * Adds a `StringObject` to the internal collections if it does not already exist. * * @param id - The unique identifier for the `StringObject`. * @param object - The `StringObject` to be added. * * @remarks * This method ensures that the object is added to both `objectMapOnPage` and * `objectsOnPage` only if the `id` is not already present in `objectMapOnPage`. */ addObject(id: string, object: StringObject): void; /** * Removes an object from the page by its unique identifier. * * This method performs the following steps: * 1. Retrieves the object associated with the given `id` from `objectMapOnPage`. * 2. If the object is not found, the method exits early. * 3. Deletes the object from `objectMapOnPage`. * 4. Finds the index of the object in the `objectsOnPage` array. * 5. If the object exists in the array, it is removed using `splice`. * * @param id - The unique identifier of the object to be removed. */ removeObject(id: string): void; /** * Called when an object is connected. Can be overridden to apply initial styles or logic. * @param object The connected object. */ onObjectConnected(object: StringObject): void; /** * Called when an object is disconnected. Can be overridden to clean up styles or logic. * @param object The disconnected object. */ onObjectDisconnected(object: StringObject): void; /** * Applies a style or callback to both the main element and all its connected elements. * * @param object The object whose elements to update. * @param applyFn The function that receives an HTMLElement and performs any update. */ protected applyToElementAndConnects(object: StringObject, applyFn: (el: HTMLElement) => void, copyFn?: (el: HTMLElement, mirror?: StringMirrorObject) => void): void; /** * Cleans up internal state and detaches the module from the system. */ destroy(): void; /** Called once when the module is initialized. */ onInit(): void; /** Called on each frame with current scroll and state data. */ onFrame(data: StringData): void; onMutate(data: StringData): void; onScrollMeasure(data: StringData): void; onMouseMoveMeasure(data: StringData): void; /** Called when the window or layout is resized. */ onResize(): void; /** Called when the layout is resized width. */ onResizeWidth(): void; /** Called when scroll position changes. */ onScroll(data: StringData): void; /** Called when user changed scroll diraction. */ onDirectionChange(): void; /** Called when user starts scrolling. */ onScrollStart(): void; /** Called when user stops scrolling. */ onScrollStop(): void; /** Called when scroll direction changes (e.g., up ↔ down). */ onScrollDirectionChange(): void; /** Called when scroll axis changes (vertical ↔ horizontal). */ onAxisChange(): void; /** Called when device type changes (e.g., desktop ↔ mobile). */ onDeviceChange(): void; /** Called when scroll-related system settings or parameters change. */ onScrollConfigChange(): void; /** Called when scroll-related system settings or parameters change. */ onSettingsChange(): void; /** Called when the DOM is rebuilt, such as after a major mutation. */ onDOMRebuild(): void; /** Called on every mouse movement. */ onMouseMove(event: MouseEvent): void; /** Called on wheel input (independent of scroll). */ onWheel(event: WheelEvent): void; /** * Called when DOM elements are added or removed. */ onDOMMutate(added: NodeList, removed: NodeList): void; } /** * StringCursor Module * * Handles cursor tracking and hover states for StringTune objects. * * Safari Navigation Fix: * Safari has an issue where mouseleave events are not fired when navigation occurs * (especially with NuxtLink/router navigation). This module includes several * workarounds to ensure proper cleanup: * * 1. MutationObserver - detects when elements are removed from DOM * 2. beforeunload/pagehide - captures traditional navigation * 3. visibilitychange - captures modern SPA navigation * 4. DOM existence checks - prevents operations on removed elements */ declare class StringCursor extends StringModule { private cursorPrev; private cursorPortals;