@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,447 lines (1,397 loc) • 71 kB
TypeScript
/**
* 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;
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;
}
/**
* 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;
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;
}
/**
* 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;
}
/**
* 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 ValidateInput {
rules: RuleParserResult[];
value: any;
type?: "input" | "beforeinput";
}
interface ValidationResult {
valid: boolean;
errors: string[];
}
declare class ValidationTool implements IStringTool<ValidateInput, ValidationResult> {
process({ rules, value, type }: ValidateInput): ValidationResult;
inputValidators: Record<string, (value: any, ...params: string[]) => boolean>;
beforeInputValidators: Record<string, (value: any, ...params: string[]) => boolean>;
getErrorMessage(key: string, params?: string[]): string;
}
/**
* 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;
}
interface ModuleLifecyclePermissionsItem {
rebuild: {
width: boolean;
height: boolean;
scrollHeight: boolean;
};
}
declare class ModuleLifecyclePermissions {
desktop: ModuleLifecyclePermissionsItem;
mobile: ModuleLifecyclePermissionsItem;
}
/**
* 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;
/**
* 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;
}
/**
* 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 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 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;
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;
/**
* 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): 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;
/** 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;
}
declare class StringCursor extends StringModule {
protected enterObjectsMap: Map<string, StringObject>;
protected enterObjects: Array<StringObject>;
cursor: any;
cursorContent: any;
overCount: number;
constructor(context: StringContext);
initializeObject(globalId: number, object: StringObject, element: HTMLElement, attributes: Record<string, any>): void;
onFrame(data: StringData): void;
onObjectConnected(object: StringObject): void;
getCursorClass(object: StringObject): string | null;
onMouseEnter(object: StringObject): void;
onMouseLeave(object: StringObject): void;
private onEnterObject;
private onLeaveObject;
private setMouseCoordinates;
private calculateOffset;
}
declare class StringMagnetic extends StringModule {
constructor(context: StringContext);
initializeObject(globalId: number, object: StringObject, element: HTMLElement, attributes: Record<string, any>): void;
onMouseMove(e: MouseEvent): void;
onFrame(data: StringData): void;
}
/**
* Module that handles lazy-loading of images with `string-lazy` attribute.
* It loads the image only once, calculates its aspect-ratio to prevent layout shift,
* and then displays it.
*/
declare class StringLazy extends StringModule {
private isStartLoaded;
private loadingCount;
constructor(context: StringContext);
onInit(): void;
onObjectConnected(object: StringObject): void;
private loadImage;
private handleLoadingCompletion;
}
/**
* Represents a module responsible for handling loading-related functionality.
* Extends the `StringModule` class and provides additional behavior for managing
* loading states and timeouts.
*/
declare class StringLoading extends StringModule {
loadingTimeout: number;
constructor(context: StringContext);
onInit(): void;
}
declare class StringResponsive extends StringModule {
private queries;
private isMobileMedia;
private isTabletMedia;
private isLaptopMedia;
private isDesktopMedia;
private matchMedias;
constructor(context: StringContext);
onConnect(): void;
onInit(): void;
onResize(): void;
private updateElements;
}
/**
* The `StringAnchor` class extends the `StringModule` class and is responsible for
* managing anchor-related functionality within the string module system.
*
* This class maps an `anchor` attribute to a tuple containing x and y coordinates,
* processes these coordinates using the `originParser` tool, and applies the resulting
* values to the connected object's element as a CSS `transform-origin` style.
*/
declare class StringAnchor extends StringModule {
constructor(context: StringContext);
onObjectConnected(object: StringObject): void;
}
/**
* The `StringGlide` class is a module that handles the glide effect for string objects
* based on scroll events. It calculates displacement, acceleration, and velocity
* to create a smooth scrolling effect for objects.
*/
declare class StringGlide extends StringModule {
private previousLerp;
private displacement;
private acceleration;
private velocityMultiplier;
private isInitialScroll;
private baseVelocityMultiplier;
private reducedVelocityMultiplier;
private negativeVelocityMultiplier;
private maxDisplacementValue;
constructor(context: StringContext);
private setupItem;
private onUpdateDesktopEvent;
private onUpdateMobileEvent;
private onUpdateEvent;
private calcExpanderFactor;
onStart(): void;
onResize(): void;
private resetState;
onScrollStart(): void;
onScrollStop(): void;
onFrame(data: StringData): void;
}
/**
* Module that updates the `--lerp` CSS variable on elements
* based on current scroll velocity.
*/
declare class StringLerp extends StringModule {
constructor(context: StringContext);
/**
* Resets the `--lerp` value to 0 when scroll stops.
*/
onScrollStop(): void;
/**
* Updates `--lerp` value for each connected object during scroll.
*/
onFrame(data: StringData): void;
/**
* Sets the `--lerp` CSS variable on the object.
*/
private setLerpValue;
}
/**
* The `StringProgress` class extends the `StringModule` class and is responsible for
* managing progress-based behavior for elements during scroll events. It maps specific
* attributes, initializes objects, and updates their progress based on scroll data.
*/
declare class StringProgress extends StringModule {
constructor(context: StringContext);
/**
* Called when an object is initialized.
*/
initializeObject(globalId: number, object: StringObject, element: HTMLElement, attributes: Record<string, any>): void;
/**
* Called on scroll.
*/
onScroll(data: StringData): void;
onObjectConnected(object: StringObject): void;
private setUpObject;
}
/**
* The `StringParallax` class extends the `StringProgress` class to provide
* functionality for handling parallax effects on scrollable elements.
* It maps specific attributes related to parallax and calculates the
* necessary transformations based on scroll progress and viewport size.
*/
declare class