UNPKG

scroll-seamless

Version:

A seamless scroll library for JS, Vue, and React.

713 lines (702 loc) 17.2 kB
type ScrollDirection = 'up' | 'down' | 'left' | 'right'; type ScrollSeamlessEvent = | 'start' | 'stop' | 'destroy' | 'update' | 'reach-end' | 'reach-start'; interface PerformancePluginOptions { enabled?: boolean; fps?: boolean; memory?: boolean; timing?: boolean; onUpdate?: (metrics: any) => void; } interface AccessibilityPluginOptions { enabled?: boolean; ariaLabel?: string; keyboardNavigation?: boolean; screenReader?: boolean; focusable?: boolean; } interface ScrollSeamlessPlugin { id: string; apply: (instance: ScrollSeamlessController) => void; destroy?: () => void; } interface ScrollSeamlessOptions { data: string[]; direction?: ScrollDirection; minCountToScroll?: number; step?: number; stepWait?: number; delay?: number; bezier?: [number, number, number, number]; hoverStop?: boolean; wheelEnable?: boolean; singleLine?: boolean; rows?: number; cols?: number; onEvent?: (event: ScrollSeamlessEvent, data?: any) => void; plugins?: ScrollSeamlessPlugin[]; performance?: PerformancePluginOptions; accessibility?: AccessibilityPluginOptions; } interface ScrollSeamlessController { start: () => void; stop: () => void; destroy: () => void; updateData: () => void; setOptions: (options: Partial<ScrollSeamlessOptions>) => void; isRunning: () => boolean; getPosition?: () => number; setPosition?: (position: number) => void; addPlugin?: (plugin: ScrollSeamlessPlugin) => void; removePlugin?: (pluginId: string) => void; getPerformance?: () => any; } /** * 扩展选项接口,添加 renderItem */ interface ExtendedScrollSeamlessOptions extends ScrollSeamlessOptions { renderItem?: (item: string, index: number, rowIndex?: number, colIndex?: number) => HTMLElement; } /** * 滚动引擎类 - 重构后的核心实现 * 提供更好的可扩展性、健壮性和性能 */ declare class ScrollEngine implements ScrollSeamlessController { private container; private options; private memoryManager; private domCache; private elementPool; private pluginManager; private running; private rowStates; private colStates; private seamlessData; private seamlessColData; constructor(container: HTMLElement | null, options: ExtendedScrollSeamlessOptions); /** * 合并默认选项和用户选项 */ private mergeOptions; /** * 初始化滚动引擎 */ private initialize; /** * 设置容器样式 */ private setupContainer; /** * 创建滚动元素 */ private createScrollElements; /** * 创建水平滚动元素 */ private createHorizontalElements; /** * 创建垂直滚动元素 */ private createVerticalElements; /** * 创建元素的辅助方法 */ private createElement; /** * 设置元素样式的辅助方法 */ private setElementStyle; /** * 设置内容样式 */ private setContentStyle; /** * 绑定事件 */ private bindEvents; /** * 布局计算 */ private layout; /** * 水平布局计算 */ private layoutHorizontal; /** * 垂直布局计算 */ private layoutVertical; /** * 计算无缝滚动所需的项目 */ private calculateSeamlessItems; /** * 渲染内容 */ private renderContent; /** * 渲染水平内容 */ private renderHorizontalContent; /** * 渲染垂直内容 */ private renderVerticalContent; /** * 渲染状态内容 */ private renderStateContent; /** * 判断是否应该滚动 */ private shouldScroll; /** * 开始滚动 */ start(): void; /** * 创建滚动动画 */ private createScrollAnimation; /** * 停止滚动 */ stop(): void; /** * 销毁实例 */ destroy(): void; /** * 更新数据并重新布局 */ updateData(): void; /** * 设置选项 */ setOptions(options: Partial<ExtendedScrollSeamlessOptions>): void; /** * 获取运行状态 */ isRunning(): boolean; /** * 获取渲染矩阵(用于数据驱动模式) */ getRenderMatrix(): string[][]; /** * 获取变换样式(用于数据驱动模式) */ getTransforms(): string[]; /** * 添加插件 * @param plugin 插件实例 */ addPlugin(plugin: ScrollSeamlessPlugin): void; /** * 移除插件 * @param pluginId 插件ID */ removePlugin(pluginId: string): void; /** * 获取当前位置 * @returns 当前位置 */ getPosition(): number; /** * 设置当前位置 * @param position 位置 */ setPosition(position: number): void; /** * 获取性能数据 * @returns 性能数据 */ getPerformance(): any; /** * 事件处理器 */ private onMouseEnter; private onMouseLeave; private onWheel; /** * 错误处理 */ private handleError; } /** * 通用对象池实现,用于复用对象以减少垃圾回收 */ declare class ObjectPool<T> { private pool; private factory; private reset; private maxSize; private created; constructor(factory: () => T, reset: (item: T) => void, initialSize?: number, maxSize?: number); /** * 从池中获取对象 */ acquire(): T; /** * 将对象归还到池中 */ release(item: T): void; /** * 清空池 */ clear(): void; /** * 获取池状态 */ getStats(): { poolSize: number; totalCreated: number; maxSize: number; }; } /** * DOM元素对象池 */ declare class DOMElementPool { private spanPool; private divPool; constructor(); acquireSpan(): HTMLSpanElement; releaseSpan(span: HTMLSpanElement): void; acquireDiv(): HTMLDivElement; releaseDiv(div: HTMLDivElement): void; clear(): void; } /** * 动画接口定义 */ interface Animation { id: string; callback: (timestamp: number) => boolean; priority: number; startTime?: number; lastFrameTime?: number; } /** * 性能监控接口 */ interface PerformanceMetrics$1 { fps: number; frameTime: number; droppedFrames: number; activeAnimations: number; } /** * 统一的requestAnimationFrame调度器 * 解决多实例时的动画性能问题 */ declare class RAFScheduler { private static instance; private animations; private isRunning; private rafId; private lastTimestamp; private frameCount; private droppedFrames; private fpsHistory; private maxFPSHistory; private frameTimeThreshold; private constructor(); /** * 获取单例实例 */ static getInstance(): RAFScheduler; /** * 添加动画到调度队列 */ schedule(animation: Animation): void; /** * 移除动画 */ unschedule(animationId: string): void; /** * 暂停特定动画 */ pause(animationId: string): void; /** * 恢复特定动画 */ resume(animationId: string): void; /** * 暂停所有动画 */ pauseAll(): void; /** * 恢复所有动画 */ resumeAll(): void; /** * 开始调度循环 */ private start; /** * 停止调度循环 */ private stop; /** * 主要的动画循环 */ private tick; /** * 更新FPS统计 */ private updateFPS; /** * 获取当前性能指标 */ getPerformanceMetrics(): PerformanceMetrics$1; /** * 获取调度器状态 */ getStatus(): { fps: number; frameTime: number; droppedFrames: number; activeAnimations: number; isRunning: boolean; frameCount: number; }; /** * 重置性能统计 */ resetStats(): void; /** * 销毁调度器 */ destroy(): void; } /** * 动画辅助函数 */ declare class AnimationHelper { private static idCounter; /** * 生成唯一动画ID */ static generateId(prefix?: string): string; /** * 创建简单的位移动画 */ static createTransformAnimation(element: HTMLElement, from: { x: number; y: number; }, to: { x: number; y: number; }, duration: number, easing?: (t: number) => number): Animation; /** * 创建无限滚动动画 */ static createScrollAnimation(element: HTMLElement, direction: 'left' | 'right' | 'up' | 'down', speed: number, contentSize: number): Animation; } declare const rafScheduler: RAFScheduler; /** * 内存管理器 - 负责资源清理和内存泄漏防护 */ declare class MemoryManager { private cleanupTasks; private eventListeners; private observers; private timers; private intervals; private rafIds; private isDestroyed; /** * 添加清理任务 */ addCleanupTask(task: () => void): void; /** * 安全的事件监听器添加 */ addEventListener(element: HTMLElement, event: string, listener: EventListener, options?: AddEventListenerOptions): void; /** * 移除事件监听器 */ removeEventListener(element: HTMLElement, event: string, listener: EventListener): void; /** * 创建并管理 MutationObserver */ createMutationObserver(callback: MutationCallback, target: Node, options?: MutationObserverInit): MutationObserver; /** * 管理定时器 */ setTimeout(callback: () => void, delay: number): number; setInterval(callback: () => void, delay: number): number; clearTimeout(id: number): void; clearInterval(id: number): void; /** * 管理 requestAnimationFrame */ requestAnimationFrame(callback: FrameRequestCallback): number; cancelAnimationFrame(id: number): void; /** * 获取内存使用统计 */ getMemoryStats(): { cleanupTasks: number; eventListeners: number; observers: number; timers: number; intervals: number; rafIds: number; isDestroyed: boolean; }; /** * 完全清理所有资源 */ destroy(): void; } /** * DOM测量结果接口 */ interface ElementMeasurement { width: number; height: number; offsetWidth: number; offsetHeight: number; scrollWidth: number; scrollHeight: number; timestamp: number; } /** * DOM测量缓存管理器 */ declare class DOMCache { private measurementCache; private textSizeCache; private resizeObserver; private observedElements; private cacheTimeout; constructor(cacheSize?: number); /** * 生成元素的唯一键 */ private getElementKey; /** * 生成文本测量的键 */ private getTextKey; /** * 实际测量元素 */ private measureElement; /** * 获取元素测量结果(带缓存) */ getElementMeasurement(element: HTMLElement, forceRefresh?: boolean): ElementMeasurement; /** * 测量文本尺寸(带缓存) */ measureText(text: string, className?: string, styles?: Partial<CSSStyleDeclaration>): { width: number; height: number; }; /** * 批量测量文本 */ measureTextBatch(texts: string[], className?: string, styles?: Partial<CSSStyleDeclaration>): { width: number; height: number; }[]; /** * 清除过期缓存 */ clearExpiredCache(): void; /** * 获取缓存统计 */ getCacheStats(): { measurementCacheSize: number; textCacheSize: number; observedElements: string | number; hasResizeObserver: boolean; }; /** * 销毁缓存 */ destroy(): void; } /** * 插件管理器类 * 负责管理和协调插件的生命周期 */ declare class PluginManager { private plugins; private controller; constructor(controller: ScrollSeamlessController); /** * 注册插件 * @param plugin 插件实例 */ register(plugin: ScrollSeamlessPlugin): void; /** * 注销插件 * @param pluginId 插件ID */ unregister(pluginId: string): void; /** * 获取插件实例 * @param pluginId 插件ID * @returns 插件实例或null */ getPlugin(pluginId: string): ScrollSeamlessPlugin | null; /** * 获取所有已注册的插件 * @returns 插件列表 */ getPlugins(): ScrollSeamlessPlugin[]; /** * 销毁所有插件 */ destroyAll(): void; } /** * 性能指标接口 */ interface PerformanceMetrics { fps: number; memory: { jsHeapSizeLimit: number; totalJSHeapSize: number; usedJSHeapSize: number; } | null; timing: { renderTime: number; animationTime: number; }; elements: { total: number; visible: number; }; } /** * 性能监控插件 * 用于监控滚动性能并提供性能指标 */ declare class PerformancePlugin { id: string; private controller; private options; private metrics; private monitoringInterval; constructor(options?: PerformancePluginOptions); /** * 应用插件 * @param controller 滚动控制器 */ apply(controller: ScrollSeamlessController): void; /** * 销毁插件 */ destroy(): void; /** * 开始监控 */ private startMonitoring; /** * 停止监控 */ private stopMonitoring; /** * 更新性能指标 */ private updateMetrics; /** * 获取性能指标 * @returns 性能指标 */ getMetrics(): PerformanceMetrics; } /** * 合法的滚动方向 */ declare const legalDirections: readonly ["left", "right", "up", "down"]; /** * 获取合法的滚动方向,如果不合法则返回默认值 'left' * @param direction 滚动方向 * @returns 合法的滚动方向 */ declare function getLegalDirection(direction: string): ScrollDirection; /** * 获取内容的变换样式 * @param direction 滚动方向 * @param position 当前位置 * @param totalLength 内容总长度 * @param isSecondContent 是否是第二个内容元素 * @returns 变换样式字符串 */ declare function getContentTransform(direction: ScrollDirection, position: number, totalLength: number, isSecondContent: boolean): string; /** * 计算下一个位置 * @param direction 滚动方向 * @param position 当前位置 * @param step 步长 * @param totalLength 内容总长度 * @returns 下一个位置 */ declare function getNextPosition(direction: ScrollDirection, position: number, step: number, totalLength: number): number; /** * 获取内容样式 * @param direction 滚动方向 * @returns CSS样式对象 */ declare function getContentStyle(direction: ScrollDirection): Record<string, string | number>; /** * 触发事件 * @param handler 事件处理函数 * @param event 事件名称 * @param payload 事件数据 */ declare function fireEvent(handler: ((event: string, payload?: any) => void) | undefined, event: string, payload?: any): void; /** * 获取渲染数据 * @param data 原始数据 * @param direction 滚动方向 * @returns 处理后的数据 */ declare function getRenderData<T>(data: T[], direction: ScrollDirection): T[]; /** * 防抖函数 * @param fn 要执行的函数 * @param delay 延迟时间 * @returns 防抖后的函数 */ declare function debounce<T extends (...args: any[]) => any>(fn: T, delay: number): (...args: Parameters<T>) => void; /** * 节流函数 * @param fn 要执行的函数 * @param limit 时间限制 * @returns 节流后的函数 */ declare function throttle<T extends (...args: any[]) => any>(fn: T, limit: number): (...args: Parameters<T>) => void; /** * 检查浏览器支持的特性 * @returns 支持的特性对象 */ declare function detectBrowserFeatures(): Record<string, boolean>; /** * 安全地执行DOM操作 * @param callback DOM操作回调 * @returns 操作结果 */ declare function safeDOM<T>(callback: () => T): T | null; declare const DEFAULT_OPTIONS: Required<Omit<ScrollSeamlessOptions, 'data'>>; /** * 创建无缝滚动实例 * @param container 容器元素 * @param options 配置选项 * @returns 滚动控制器 */ declare function createScrollSeamless(container: HTMLElement, options: ScrollSeamlessOptions): ScrollSeamlessController; declare const ScrollSeamless: typeof ScrollEngine; export { AnimationHelper, DEFAULT_OPTIONS, DOMCache, DOMElementPool, MemoryManager, ObjectPool, PerformancePlugin, PluginManager, RAFScheduler, createScrollSeamless, debounce, ScrollSeamless as default, detectBrowserFeatures, fireEvent, getContentStyle, getContentTransform, getLegalDirection, getNextPosition, getRenderData, legalDirections, rafScheduler, safeDOM, throttle }; export type { Animation, ElementMeasurement, PerformanceMetrics$1 as PerformanceMetrics };