UNPKG

saltfish

Version:

An interactive video-guided tour system for web applications

301 lines 10.4 kB
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