UNPKG

kinetic-slider

Version:

A WebGL-powered kinetic slider component using PIXI.js

1 lines 19.6 kB
{"version":3,"file":"SlidingWindowManager.cjs","sources":["../../../src/managers/SlidingWindowManager.ts"],"sourcesContent":["import { type EnhancedSprite } from '../types';\nimport ResourceManager from './ResourceManager';\n\n/**\n * Configuration options for the SlidingWindowManager\n */\nexport interface SlidingWindowOptions {\n /** Number of slides to keep loaded on each side of the current slide */\n windowSize?: number;\n\n /** Whether to enable debug logging */\n debug?: boolean;\n\n /** Total number of slides in the slider */\n totalSlides: number;\n\n /** Initial active slide index */\n initialIndex?: number;\n}\n\n/**\n * Slide initialization state\n */\nexport enum SlideState {\n /** Slide is not initialized at all */\n UNINITIALIZED = 'uninitialized',\n\n /** Slide has a lightweight placeholder */\n PLACEHOLDER = 'placeholder',\n\n /** Slide is fully loaded and ready for display */\n LOADED = 'loaded',\n\n /** Slide is currently visible */\n ACTIVE = 'active',\n\n /** Slide failed to load */\n ERROR = 'error'\n}\n\n/**\n * Information about a slide's current state\n */\nexport interface SlideInfo {\n /** Index of the slide */\n index: number;\n\n /** Current state of the slide */\n state: SlideState;\n\n /** Reference to the sprite if available */\n sprite?: EnhancedSprite;\n\n /** Whether the slide is within the current visibility window */\n inWindow: boolean;\n\n /** Last time this slide was active */\n lastActiveTime?: number;\n}\n\n/**\n * Manages a sliding window of initialized slides to optimize memory usage\n * and improve performance by only fully loading slides that are visible\n * or likely to become visible soon.\n */\nexport default class SlidingWindowManager {\n /** Current active slide index */\n private activeIndex: number;\n\n /** Size of the window on each side of the active slide */\n private windowSize: number;\n\n /** Total number of slides */\n private totalSlides: number;\n\n /** Information about each slide */\n private slides: SlideInfo[];\n\n /** Whether debug logging is enabled */\n private debug: boolean;\n\n /** Resource manager for tracking resources */\n private resourceManager?: ResourceManager;\n\n /** Direction of the last navigation (-1 for prev, 1 for next, 0 for initial) */\n private lastDirection: number = 0;\n\n /**\n * Creates a new SlidingWindowManager\n *\n * @param options - Configuration options\n * @param resourceManager - Optional ResourceManager for resource tracking\n */\n constructor(options: SlidingWindowOptions, resourceManager?: ResourceManager) {\n this.windowSize = options.windowSize ?? 2;\n this.totalSlides = options.totalSlides;\n this.activeIndex = options.initialIndex ?? 0;\n this.debug = options.debug ?? false;\n this.resourceManager = resourceManager;\n\n // Initialize slide info array\n this.slides = Array(this.totalSlides).fill(null).map((_, index) => ({\n index,\n state: SlideState.UNINITIALIZED,\n inWindow: this.isInWindow(index, this.activeIndex)\n }));\n\n this.log(`Initialized with ${this.totalSlides} slides, window size ±${this.windowSize}, active index ${this.activeIndex}`);\n this.log(`Initial window: ${this.getWindowIndices().join(', ')}`);\n }\n\n /**\n * Log a message if debug is enabled\n */\n private log(message: string, level: 'info' | 'warn' | 'error' = 'info'): void {\n if (!this.debug) return;\n\n const prefix = `[SlidingWindowManager]`;\n\n switch (level) {\n case 'info':\n console.log(`${prefix} ${message}`);\n break;\n case 'warn':\n console.warn(`${prefix} ${message}`);\n break;\n case 'error':\n console.error(`${prefix} ${message}`);\n break;\n }\n }\n\n /**\n * Check if a slide index is within the current window\n *\n * @param index - Slide index to check\n * @param centerIndex - Center of the window (usually activeIndex)\n * @returns Whether the index is within the window\n */\n private isInWindow(index: number, centerIndex: number): boolean {\n const distance = Math.abs(index - centerIndex);\n return distance <= this.windowSize;\n }\n\n /**\n * Get all slide indices that should be in the current window\n *\n * @returns Array of slide indices in the window\n */\n public getWindowIndices(): number[] {\n const indices: number[] = [];\n\n // Include the active index and windowSize slides on each side\n for (let i = Math.max(0, this.activeIndex - this.windowSize);\n i <= Math.min(this.totalSlides - 1, this.activeIndex + this.windowSize);\n i++) {\n indices.push(i);\n }\n\n return indices;\n }\n\n /**\n * Get all slide indices that should be in the extended window\n * (includes prediction based on navigation direction)\n *\n * @returns Array of slide indices in the extended window\n */\n public getExtendedWindowIndices(): number[] {\n const indices = this.getWindowIndices();\n\n // Add extra slides in the direction of navigation\n if (this.lastDirection !== 0) {\n const extraIndex = this.lastDirection > 0\n ? this.activeIndex + this.windowSize + 1\n : this.activeIndex - this.windowSize - 1;\n\n if (extraIndex >= 0 && extraIndex < this.totalSlides) {\n indices.push(extraIndex);\n }\n }\n\n return indices;\n }\n\n /**\n * Update the active slide index and recalculate the window\n *\n * @param newIndex - New active slide index\n * @returns Object containing arrays of indices that entered and left the window\n */\n public updateActiveIndex(newIndex: number): {\n entered: number[],\n left: number[]\n } {\n if (newIndex < 0 || newIndex >= this.totalSlides) {\n this.log(`Invalid index: ${newIndex}`, 'error');\n return { entered: [], left: [] };\n }\n\n // Calculate direction of navigation\n this.lastDirection = newIndex > this.activeIndex ? 1 : -1;\n\n const oldWindowIndices = this.getWindowIndices();\n const oldActiveIndex = this.activeIndex;\n\n // Update active index\n this.activeIndex = newIndex;\n\n // Update active slide info\n if (this.slides[newIndex]) {\n this.slides[newIndex].state = SlideState.ACTIVE;\n this.slides[newIndex].lastActiveTime = Date.now();\n }\n\n // Update previous active slide\n if (this.slides[oldActiveIndex] && oldActiveIndex !== newIndex) {\n if (this.slides[oldActiveIndex].state === SlideState.ACTIVE) {\n this.slides[oldActiveIndex].state = SlideState.LOADED;\n }\n }\n\n // Get new window indices\n const newWindowIndices = this.getWindowIndices();\n\n // Calculate which indices entered and left the window\n const entered = newWindowIndices.filter(index => !oldWindowIndices.includes(index));\n const left = oldWindowIndices.filter(index => !newWindowIndices.includes(index));\n\n // Update inWindow flag for all slides\n this.slides.forEach(slide => {\n slide.inWindow = this.isInWindow(slide.index, this.activeIndex);\n });\n\n this.log(`Updated active index to ${newIndex}, direction: ${this.lastDirection}`);\n this.log(`Window changed: +[${entered.join(', ')}] -[${left.join(', ')}]`);\n\n return { entered, left };\n }\n\n /**\n * Register a sprite for a slide\n *\n * @param index - Slide index\n * @param sprite - Sprite instance\n * @param state - Current state of the slide\n */\n public registerSlide(index: number, sprite: EnhancedSprite, state: SlideState = SlideState.LOADED): void {\n if (index < 0 || index >= this.totalSlides) {\n this.log(`Invalid index for registerSlide: ${index}`, 'error');\n return;\n }\n\n this.slides[index] = {\n ...this.slides[index],\n sprite,\n state: index === this.activeIndex ? SlideState.ACTIVE : state,\n inWindow: this.isInWindow(index, this.activeIndex)\n };\n\n this.log(`Registered slide ${index} with state ${state}`);\n }\n\n /**\n * Update the state of a slide\n *\n * @param index - Slide index\n * @param state - New state\n */\n public updateSlideState(index: number, state: SlideState): void {\n if (index < 0 || index >= this.totalSlides) {\n this.log(`Invalid index for updateSlideState: ${index}`, 'error');\n return;\n }\n\n this.slides[index].state = state;\n this.log(`Updated slide ${index} state to ${state}`);\n }\n\n /**\n * Get information about a slide\n *\n * @param index - Slide index\n * @returns Slide information or null if index is invalid\n */\n public getSlideInfo(index: number): SlideInfo | null {\n if (index < 0 || index >= this.totalSlides) {\n this.log(`Invalid index for getSlideInfo: ${index}`, 'error');\n return null;\n }\n\n return this.slides[index];\n }\n\n /**\n * Get the current active index\n *\n * @returns Active slide index\n */\n public getActiveIndex(): number {\n return this.activeIndex;\n }\n\n /**\n * Get all slide information\n *\n * @returns Array of slide information\n */\n public getAllSlides(): SlideInfo[] {\n return [...this.slides];\n }\n\n /**\n * Get slides that need to be initialized (converted from UNINITIALIZED to at least PLACEHOLDER)\n *\n * @returns Array of slide indices that need initialization\n */\n public getSlidesToInitialize(): number[] {\n const windowIndices = this.getExtendedWindowIndices();\n\n return windowIndices.filter(index =>\n this.slides[index].state === SlideState.UNINITIALIZED\n );\n }\n\n /**\n * Get slides that need to be fully loaded (converted from PLACEHOLDER to LOADED)\n *\n * @returns Array of slide indices that need to be fully loaded\n */\n public getSlidesToLoad(): number[] {\n const windowIndices = this.getWindowIndices();\n\n return windowIndices.filter(index =>\n this.slides[index].state === SlideState.PLACEHOLDER\n );\n }\n\n /**\n * Get slides that can be unloaded (converted from LOADED to PLACEHOLDER)\n *\n * @returns Array of slide indices that can be unloaded\n */\n public getSlidesToUnload(): number[] {\n return this.slides\n .filter(slide =>\n !slide.inWindow &&\n (slide.state === SlideState.LOADED || slide.state === SlideState.ACTIVE)\n )\n .map(slide => slide.index);\n }\n\n /**\n * Set the window size\n *\n * @param size - New window size\n */\n public setWindowSize(size: number): void {\n if (size < 1) {\n this.log(`Invalid window size: ${size}, must be at least 1`, 'error');\n return;\n }\n\n this.windowSize = size;\n\n // Recalculate which slides are in the window\n this.slides.forEach(slide => {\n slide.inWindow = this.isInWindow(slide.index, this.activeIndex);\n });\n\n this.log(`Window size updated to ±${size}`);\n }\n\n /**\n * Get the current window size\n *\n * @returns Current window size\n */\n public getWindowSize(): number {\n return this.windowSize;\n }\n\n /**\n * Get the last navigation direction\n *\n * @returns Last direction (-1 for prev, 1 for next, 0 for initial)\n */\n public getLastDirection(): number {\n return this.lastDirection;\n }\n\n /**\n * Alias for updateActiveIndex to maintain naming consistency\n *\n * @param newIndex - New current slide index\n * @returns Object containing arrays of indices that entered and left the window\n */\n public updateCurrentIndex(newIndex: number): {\n entered: number[],\n left: number[]\n } {\n return this.updateActiveIndex(newIndex);\n }\n}"],"names":[],"mappings":"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"}