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,413 lines (1,362 loc) 73.5 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; } 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; /** * 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): 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; } /** * 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; } /** * 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; } /** * 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; } /** * 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; } /** * 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 }: 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; } /** * Tool that parses origin strings. * Allows static values like `'center'`, or expressions like `'random(...)'` to select one randomly. */ declare class OriginParserTool implements IStringTool<OriginInput, string> { /** * @returns Parsed string value (static or randomly chosen). */ process({ value }: OriginInput): string; } 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; } type ValidationErrorCode = "required" | "invalid-email" | "too-short" | "too-long"; type ValidationRule = "required" | "email" | { type: "minLength"; value: number; } | { type: "maxLength"; value: number; }; interface ValidationInput { /** Value to validate. */ value: string; /** List of rules to apply. */ rules: ValidationRule[]; /** * Optional message map: key = errorCode, value = string or function returning a message. */ messages?: Partial<Record<ValidationErrorCode, string | ((args: { value: string; rule: ValidationRule; }) => string)>>; } interface ValidationOutput { /** `true` if valid, `false` if error found. */ valid: boolean; /** One of the known error codes (or null if no error). */ error: ValidationErrorCode | null; /** Final message (either default or user-defined). */ message: string | null; } /** * Tool for validating strings using rules like `required`, `minLength`, etc. * Allows custom error messages (as string or generator function). */ declare class ValidationTool implements IStringTool<ValidationInput, ValidationOutput> { /** * Validates input value and returns error code + message. */ process({ value, rules, messages }: ValidationInput): ValidationOutput; private defaultMessage; } /** * 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[]; } /** * Represents a single word identified during layout calculation. */ interface LayoutWord { /** The text content of the word. */ text: string; } /** * Represents a line of text as determined by layout calculations. */ interface LayoutLine { /** The full text content of the line as a single string. */ text: string; /** An array of word objects that make up this line. */ words: LayoutWord[]; } /** * Holds the final calculated numerical value resulting from applying * a specific ISplitOptionItem rule to a word or character, along with * context about the rule itself (type, alignment). * This is used by the SplitDomBuilderTool to set CSS variables. */ interface CalculatedValue { /** * The final numerical result after applying the alignment ('start', 'center', 'end', 'random') * and absolute value ('abs') logic based on the specific option rule. * This is the value that will be set for the CSS variable. */ value: number; /** * Indicates which type of split option definition this value originated from. * Crucial for generating the correct CSS variable name prefix (e.g., '--word-', '--charLine-'). */ type: 'line' | 'word' | 'char' | 'wordLine' | 'charLine' | 'charWord'; /** * Stores the specific alignment ('start', 'center', 'end', 'random') * defined in the option rule that produced this value. * Used for generating the CSS variable name suffix (e.g., '-center', '-end'). */ align: string; } /** * Represents a processed word, containing its text, contextual indices * (global, line, word-in-line), and an array of calculated values * based on the applicable 'word' and 'wordLine' options. */ interface ProcessedWord { /** The text content of the word. */ text: string; /** The zero-based index of the word across all words in all lines. */ globalIndex: number; /** The zero-based index of the line this word belongs to. */ lineIndex: number; /** The zero-based index of this word within its line. */ wordIndexInLine: number; /** An array of calculated values based on ISplitOptions ('word', 'wordLine'). */ calculatedValues: CalculatedValue[]; } /** * Input for the CharIndexerTool. */ interface CharIndexerInput { /** The array of processed words from WordIndexerTool. */ processedWords: ProcessedWord[]; /** The array of layout lines (needed to calculate total line characters). */ lines: LayoutLine[]; /** The parsed split options relevant for characters ('char', 'charLine', 'charWord'). */ options: Pick<ISplitOptions, 'char' | 'charLine' | 'charWord'>; /** The total number of non-whitespace characters in the original text. */ totalChars: number; } /** * Represents a processed character, containing its text, contextual indices * (global, line, word, plus parent info), and an array of calculated values * based on the applicable 'char', 'charLine', and 'charWord' options. */ interface ProcessedChar { /** The character itself. */ text: string; /** The zero-based index of the character across all non-whitespace characters. */ globalCharIndex: number; /** The zero-based index of the character within its line (excluding spaces between words). */ lineCharIndex: number; /** The zero-based index of the character within its word. */ wordCharIndex: number; /** Index of the parent word across all words. */ parentGlobalWordIndex: number; /** Index of the line this character belongs to. */ parentLineIndex: number; /** Index of the parent word within its line. */ parentWordIndexInLine: number; /** An array of calculated index values based on ISplitOptions ('char', 'charLine', 'charWord'). */ calculatedValues: CalculatedValue[]; } /** * Tool to process words split by layout, breaking them into characters * and assigning relevant indices (global, line, word) for each character. * Calculates index values based on ISplitOptions for characters ('char', 'charLine', 'charWord'). * Produces an array of ProcessedChar objects. */ declare class CharIndexerTool implements IStringTool<CharIndexerInput, ProcessedChar[]> { /** * Iterates through processed words, splits them into characters, assigns * global, line, and word character indices, and calculates index values * based on the provided character options ('char', 'charLine', 'charWord'). * * @param input.processedWords - Array of ProcessedWord objects from WordIndexerTool. * @param input.lines - Array of LayoutLine objects (needed for calculating total characters per line). * @param input.options - The relevant ISplitOptions ('char', 'charLine', 'charWord'). * @param input.totalChars - Total number of non-whitespace characters in the original text. * @returns An array of ProcessedChar objects, ready for DOM building/styling. */ process({ processedWords, lines, options, totalChars }: CharIndexerInput): ProcessedChar[]; /** * Calculates the final numerical index value based on alignment options, context indices, and parent length. * (Identical helper function as in WordIndexerTool - could be extracted to a common utility). * * @param option - The specific option item definition ({ align, random, abs }). * @param primaryIndex - The main index used for calculation (global, line, or word char index). * @param localIndex - The secondary index (e.g., index within word). * @param parentLength - The total count in the relevant context (total chars, line chars, or word chars). * @returns The calculated numerical index value. */ private calculateIndex; } /** * Input interface for the LayoutLineSplitterTool. * Requires both the text and the element it will be rendered within. */ interface LayoutSplitInput { /** The raw text content to be split into lines based on layout. */ text: string; /** The HTML element whose width and styles determine line breaks. */ targetElement: HTMLElement; } /** * Tool to split a text string into structured lines and words based on how * the text would visually wrap within a given target HTML element. * This simulates browser rendering by measuring word widths. * Returns an array of LayoutLine objects. */ declare class LayoutLineSplitterTool implements IStringTool<LayoutSplitInput, LayoutLine[]> { /** * Processes the input text and splits it into lines containing words, * simulating word wrapping within the boundaries of the targetElement. * * @param input.text - The text content to split. * @param input.targetElement - The HTMLElement used as a reference for width and font styles. * @returns An array of LayoutLine objects, each containing the line's text and an array of its words. * Returns an empty array on error or invalid input. */ process({ text, targetElement }: LayoutSplitInput): LayoutLine[]; /** * Measures the width of a given text string using the provided temporary span. * @param text - The text to measure. * @param tempSpan - The pre-styled temporary span element used for measurement. * @returns The width of the text in pixels. */ private measureWidth; /** * Decodes basic HTML entities (currently just &amp;). * Can be expanded if more entities need handling. * @param str - The string potentially containing HTML entities. * @returns The string with '&amp;' decoded to '&'. */ private decodeHtmlEntity; } /** * Defines the input structure required by the SplitDomBuilderTool. */ interface DomBuilderInput { /** Array of lines determined by layout. */ lines: LayoutLine[]; /** Array of words with calculated indices and values. */ words: ProcessedWord[]; /** Array of characters with calculated indices and values. */ chars: ProcessedChar[]; /** The original parsed split options. */ options: ISplitOptions; } /** * Tool to build the final innerHTML string with nested spans (-s-line, -s-word, -s-char) * and apply calculated CSS variables based on processed data from indexer tools. * Implements the IStringTool interface. */ declare class SplitDomBuilderTool implements IStringTool<DomBuilderInput, string> { /** * Generates the innerHTML string for the split text by creating nested spans * (-s-line, -s-word, -s-char) based on options and applying styles from calculated index values. * * @param input An object containing layout lines, processed words, processed characters, and the original split options. * @returns The generated HTML string representing the split content. */ process({ lines, words, chars, options }: DomBuilderInput): string; /** * Creates and styles a character span. * @param pChar - The processed character data. * @returns The styled HTMLSpanElement for the character. * @private */ private createCharSpan; /** * Checks if any line-level splitting options (line, wordLine, charLine) are present. * @param options - The ISplitOptions object. * @returns True if any line-level options exist and have definitions, false otherwise. * @private */ private hasLineOptions; /** * Checks if any word-level splitting options (word, wordLine) are present. * @param options - The ISplitOptions object. * @returns True if any word-level options exist and have definitions, false otherwise. * @private */ private hasWordOptions; /** * Checks if any character-level splitting options (char, charLine, charWord) are present. * @param options - The ISplitOptions object. * @returns True if any character-level options exist and have definitions, false otherwise. * @private */ private hasCharOptions; /** * Applies the pre-calculated index values as CSS custom properties to the element's style. * @param span - The HTMLElement (line, word, or char span) to apply styles to. * @param calculatedValues - An array of calculated values from the indexer tool. * @private */ private applyStyles; /** * Generates a CSS custom property name based on the split type and alignment. * @param type - The type of split element ('line', 'word', 'char', etc.). * @param align - The alignment option ('start', 'center', 'end', 'random'). * @returns The generated CSS variable name string (e.g., '--word-center'). * @private */ private generateVariableName; } /** * Input for the WordIndexerTool. */ interface WordIndexerInput { /** The array of layout lines produced by LayoutLineSplitterTool. */ lines: LayoutLine[]; /** The parsed split options relevant for words ('word', 'wordLine'). */ options: Pick<ISplitOptions, 'word' | 'wordLine'>; } /** * Tool to process layout lines and words, assigning relevant indices * and calculating index values based on ISplitOptions ('word', 'wordLine'). * Produces an array of ProcessedWord objects. */ declare class WordIndexerTool implements IStringTool<WordIndexerInput, ProcessedWord[]> { /** * Iterates through lines and words, assigning global and local indices, * and calculating index values based on the provided options ('word', 'wordLine'). * * @param input.lines - Array of LayoutLine objects from LayoutLineSplitterTool. * @param input.options - The relevant ISplitOptions ('word', 'wordLine'). * @returns An array of ProcessedWord objects, each containing word text, indices, * and an array of calculated values based on options. */ process({ lines, options }: WordIndexerInput): ProcessedWord[]; /** * Calculates the final numerical index value based on alignment options, context indices, and parent length. * This logic determines the value eventually set as a CSS variable. * * @param option - The specific option item definition ({ align, random, abs }). * @param primaryIndex - The main index used for calculation (global index for 'word', index within line for 'wordLine'). * @param localIndex - The secondary index (e.g., index within the line), potentially useful for some alignment logic. * @param parentLength - The total count in the relevant context (total words for 'word', words in the current line for 'wordLine'). * @returns The calculated numerical index value. */ private calculateIndex; } /** * 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 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; layoutSplitter: LayoutLineSplitterTool; wordIndexer: WordIndexerTool; charIndexer: CharIndexerTool; domBuilder: SplitDomBuilderTool; optionsParser: SplitOptionsParserTool; } /** * 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; } /** * 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[]; /** * A list of elements that should be affected in sync with this one. */ connects: HTMLElement[]; /** * 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; /** * 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; } /** * Base interface for scroll/interaction modules in the StringScroll system. */ interface IStringModule { /** 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 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; } type AttributeType = "string" | "number" | "boolean" | "json" | "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 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. */ pr