saltfish
Version:
An interactive video-guided tour system for web applications
301 lines • 10.4 kB
TypeScript
import type { CursorAnimation } from '../types';
/**
* Manager class for handling virtual cursor animations and flashlight effect
*/
export declare class CursorManager {
private cursor;
private animationFrameId;
private animationStartTime;
private currentAnimation;
private flashlightOverlay;
private startX;
private startY;
private targetX;
private targetY;
private shouldShowCursor;
private lastCursorX;
private lastCursorY;
private isFirstAnimation;
private currentTargetElement;
private boundScrollHandler;
private scrollRafId;
private scrollUpdatePending;
private scrollableParents;
private parentScrollHandlers;
private selectionElement;
private isSelectionMode;
private selectionPadding;
private labelElement;
private labelText;
private dragStartX;
private dragStartY;
private dragEndX;
private dragEndY;
private dragPhase;
private dragAnimationStartTime;
private readonly TARGET_SPEED;
private readonly MIN_ANIMATION_DURATION;
private readonly MAX_ANIMATION_DURATION;
private animationDuration;
private totalDistance;
private controlPointX;
private controlPointY;
private targetMutationObserver;
private readonly POINTER_HORIZONTAL_OFFSET;
private readonly POINTER_VERTICAL_OFFSET;
private readonly SELECTION_HORIZONTAL_OFFSET;
private readonly SELECTION_VERTICAL_OFFSET;
private animationUtils;
/**
* Extracts padding value from selection styles
* @param styles - Optional selection styles
* @returns Padding value in pixels
*/
private getPaddingFromStyles;
/**
* Calculates distance between two points
* @param x1 - Start X coordinate
* @param y1 - Start Y coordinate
* @param x2 - End X coordinate
* @param y2 - End Y coordinate
* @returns Distance in pixels
*/
private calculateDistance;
/**
* Calculates animation duration based on distance for consistent, human-like speed
* Uses speed-clamped approach: maintains ~350px/s speed within 600-2000ms bounds
* @param distance - Distance to travel in pixels
* @returns Duration in milliseconds
*/
private calculateAnimationDuration;
/**
* Gets the current cursor position from lastCursorX/Y
* @returns Current cursor coordinates
*/
private getCurrentCursorPosition;
/**
* Checks if cursor can be shown (not blocked by autoplay and should show)
* @returns Whether cursor can be shown
*/
private canShowCursor;
/**
* Waits for a scroll operation to complete with timeout
* @param scrollable - Element or window that is scrolling
* @param onComplete - Callback when scroll completes
* @param maxTimeout - Maximum time to wait in milliseconds
*/
private waitForScrollComplete;
/**
* Sets up a MutationObserver to wait for an element to appear in the DOM
* @param selector - CSS selector to wait for
* @param callback - Callback to execute when element is found
* @param expectedElement - Optional expected tag+text for validation
* @param expectedSize - Optional expected size for validation
*/
private waitForElement;
/**
* Finds all scrollable parent containers of an element
* @param element - The element to find scrollable parents for
* @returns Array of scrollable parent elements
*/
private findScrollableParents;
/**
* Adds scroll event listeners to scrollable parent containers
* @param element - The target element whose parents should be monitored
*/
private addScrollListenersToParents;
/**
* Removes scroll event listeners from all tracked parent containers
*/
private removeScrollListenersFromParents;
/**
* Helper function to find an element in the document
* Uses tag+text validation first (if provided), then size validation
* Falls back to viewport-based selection when no validation criteria or when validation passes
* @param selector - CSS selector
* @param expectedElement - Optional expected tag+text for validation
* @param expectedSize - Optional expected size for validation
* @returns - The found element or null
*/
private findElement;
/**
* Checks if an element is completely visible in the viewport and within all scrollable parent containers
* @param element - The element to check
* @returns - Whether the entire element is visible in viewport and all scrollable parents
*/
private isElementInViewport;
/**
* Scrolls an element into view smoothly, handling both window and parent container scrolling
* @param element - The element to scroll into view
* @returns - Promise that resolves when scrolling is complete
*/
private scrollElementIntoView;
/**
* Scrolls parent containers to make the element visible
* @param element - The target element
* @param scrollableParents - Array of scrollable parent containers
* @returns Promise that resolves when scrolling is complete
*/
private scrollParentContainersToShowElement;
/**
* Finds an element and scrolls it into view if necessary
* @param selector - CSS selector
* @param expectedElement - Optional expected tag+text for validation
* @param expectedSize - Optional expected size for validation
* @returns - Promise that resolves with the element or null
*/
private findElementAndScrollIntoView;
/**
* Cleans up any existing cursor elements from the DOM
* This prevents duplicate elements when switching playlists
*/
private cleanupExistingElements;
/**
* Creates the virtual cursor element
*/
create(): void;
/**
* Injects cursor styles into the main document for CSP compliance
* Uses adoptedStyleSheets API when available, falls back to <style> element
*/
private injectCursorStyles;
/**
* Handles scrolling to keep the cursor positioned on the target element
* Uses requestAnimationFrame for smooth 60fps updates
*/
private handleScroll;
/**
* Updates cursor and selection positions during scroll
* Called via requestAnimationFrame for smooth updates
*/
private updateCursorPositionOnScroll;
/**
* Checks if autoplay is blocked and cursor should be disabled
* @returns - Whether autoplay is blocked
*/
private isAutoplayBlocked;
/**
* Sets whether the cursor should be shown based on step configuration
* @param shouldShow - Whether the cursor should be shown
*/
setShouldShowCursor(shouldShow: boolean): void;
/**
* Shows the cursor and flashlight at a specific position
* Note: Will only show if shouldShowCursor is true and autoplay is not blocked
* @param x - X coordinate
* @param y - Y coordinate
*/
show(x: number, y: number): void;
/**
* Internal method to hide cursor elements without affecting shouldShowCursor state
*/
private hideCursorElements;
/**
* Resets the flashlight overlay to its original state without cutouts
*/
private resetFlashlightOverlay;
/**
* Animates the cursor along a path
* @param animation - Animation configuration
*/
animate(animation: CursorAnimation): Promise<void>;
/**
* Handles selection mode setup and animation
*/
private handleSelectionMode;
/**
* Updates drag coordinates from current element position
*/
private updateDragCoordinatesFromElement;
/**
* Updates selection rectangle dimensions during drag
*/
private updateSelectionRectangle;
/**
* Validates pointer animation state
*/
private validatePointerState;
/**
* Validates selection animation state
*/
private validateSelectionState;
/**
* Completes pointer animation
*/
private completePointerAnimation;
/**
* Completes move-to-start phase of selection animation
*/
private completeMoveToStartPhase;
/**
* Completes dragging phase of selection animation
*/
private completeDraggingPhase;
/**
* Handles move-to-start phase of selection animation
*/
private handleMoveToStartPhase;
/**
* Handles dragging phase of selection animation
*/
private handleDraggingPhase;
/**
* Handles pointer mode animation
*/
private handlePointerAnimation;
/**
* Handles selection mode animation with phases
*/
private handleSelectionAnimation;
/**
* Unified animation frame handler that dispatches to appropriate mode
*/
private unifiedAnimationFrame;
/**
* Updates the flashlight overlay to exclude the selection area
*/
private updateFlashlightWithCutout;
/**
* Calculates a control point for curved cursor movement
*/
private calculateControlPoint;
/**
* Moves the cursor to a DOM element
* @param selector - DOM element selector
* @param mode - Optional mode for cursor (pointer or selection)
* @param selectionStyles - Optional styles for selection mode
*/
moveToElement(selector: string, mode?: 'pointer' | 'selection', selectionStyles?: CursorAnimation['selectionStyles']): Promise<void>;
/**
* Simulates a click action with the cursor
*/
click(): void;
/**
* Stops the current animation
*/
stopAnimation(): void;
/**
* Resets cursor state for first animation
*/
resetFirstAnimation(): void;
/**
* Cleans up resources used by the cursor manager
*/
/**
* Reset the CursorManager to a clean state for new playlist
* Stops animations and clears state but keeps DOM elements for reuse
*/
reset(): void;
destroy(): Promise<void>;
/**
* Sets the color of the cursor SVG, selection highlight, and label
* @param color - The color to set (hex, rgb, etc)
*/
setColor(color: string): void;
/**
* Sets the label text to display beside the cursor
* @param label - The label text to display (e.g., avatar name), or null to hide
*/
setLabel(label: string | null): void;
}
//# sourceMappingURL=CursorManager.d.ts.map