UNPKG

move.gl

Version:

Motion and Animation Library for Stylescape.

193 lines (177 loc) 6.02 kB
// ============================================================================ // move.gl | Screensaver // ============================================================================ // Copyright 2025 Scape Agency BV // Licensed under MIT License // ============================================================================ /** * Screensaver Configuration Options */ export interface ScreensaverOptions { /** Inactivity timeout in milliseconds */ timeout: number; /** URL for the video to play */ videoUrl?: string; /** URL for the audio to play */ audioUrl?: string; /** ID of the screensaver container element */ containerId?: string; /** ID of the video element */ videoId?: string; /** ID of the audio element */ audioId?: string; } /** * Screensaver Class * * Handles the activation and deactivation of a screensaver based on * user inactivity. Provides methods to start and stop the screensaver, * manage media sources, and handle user interactions. * * @example * ```typescript * const screensaver = new Screensaver({ * timeout: 300000, // 5 minutes * videoUrl: 'path/to/video.mp4', * audioUrl: 'path/to/audio.mp3' * }); * screensaver.setVolume(0.5); * ``` */ export class Screensaver { private timeoutId: number | undefined; private readonly timeout: number; private screensaverElement: HTMLElement | null = null; private videoElement: HTMLVideoElement | null = null; private audioElement: HTMLAudioElement | null = null; private isActive: boolean = false; private readonly options: ScreensaverOptions; /** * Creates a new Screensaver instance. * @param options - Configuration options for the screensaver. */ constructor(options: ScreensaverOptions) { this.options = { containerId: 'screensaver', videoId: 'screensaverVideo', audioId: 'screensaverAudio', ...options }; this.timeout = options.timeout; this.initializeElements(); if (options.videoUrl && options.audioUrl) { this.loadMedia(options.videoUrl, options.audioUrl); } this.setupEventListeners(); this.startScreensaverTimeout(); } /** * Initializes HTML elements from the DOM. */ private initializeElements(): void { this.screensaverElement = document.getElementById(this.options.containerId!); this.videoElement = document.getElementById(this.options.videoId!) as HTMLVideoElement | null; this.audioElement = document.getElementById(this.options.audioId!) as HTMLAudioElement | null; } /** * Loads media sources into the video and audio elements. * @param videoUrl - The source URL of the video. * @param audioUrl - The source URL of the audio. */ private loadMedia(videoUrl: string, audioUrl: string): void { if (this.videoElement) { this.videoElement.src = videoUrl; } if (this.audioElement) { this.audioElement.src = audioUrl; } } /** * @notice Sets up event listeners for user interaction to prevent * screensaver activation. * @dev Listens for 'mousemove', 'keydown', and 'touchstart' events * to reset the screensaver timer. */ private setupEventListeners() { ['mousemove', 'keydown', 'touchstart'].forEach(event => { document.addEventListener(event, this.resetScreensaver); }); } /** * @notice Starts or restarts the screensaver timeout. * @dev Resets any existing timeout and sets a new timeout to activate * the screensaver. */ private startScreensaverTimeout() { this.stopScreensaver(); // Stop existing screensaver if active this.timeoutId = window.setTimeout( () => this.activateScreensaver(), this.timeout ); } /** * @notice Resets the screensaver timer and stops the screensaver if * active. * @dev Called upon user interactions detected by event listeners. */ private resetScreensaver = () => { if (this.isActive) { this.stopScreensaver(); } this.startScreensaverTimeout(); }; /** * Activates the screensaver, displaying elements and playing media. */ private activateScreensaver = (): void => { if (this.screensaverElement) { this.screensaverElement.style.display = 'block'; } this.videoElement?.play(); this.audioElement?.play(); this.isActive = true; }; /** * Stops the screensaver and hides its elements. */ public stopScreensaver(): void { if (this.screensaverElement) { this.screensaverElement.style.display = 'none'; } this.videoElement?.pause(); this.audioElement?.pause(); this.isActive = false; if (this.timeoutId !== undefined) { clearTimeout(this.timeoutId); this.timeoutId = undefined; } } /** * Sets the volume for both video and audio elements. * @param volume - A number between 0.0 and 1.0 indicating the volume level. */ public setVolume(volume: number): void { const clampedVolume = Math.max(0, Math.min(1, volume)); if (this.videoElement) { this.videoElement.volume = clampedVolume; } if (this.audioElement) { this.audioElement.volume = clampedVolume; } } /** * Returns whether the screensaver is currently active. */ public getIsActive(): boolean { return this.isActive; } /** * Cleans up event listeners and stops the screensaver. */ public destroy(): void { this.stopScreensaver(); ['mousemove', 'keydown', 'touchstart'].forEach(event => { document.removeEventListener(event, this.resetScreensaver); }); } } export default Screensaver;