import { Spring } from 'svelte/motion'; export interface PerspectiveConfig { /** * How many px to move back per level */ depthStep?: number; /** * Scale reduction per level */ scaleStep?: number; /** * Blur amount per level */ blurStep?: number; /** * Opacity reduction per level */ opacityStep?: number; /** * Parallax intensity per level */ parallaxIntensity?: number; /** * Horizontal offset for each plan (x-axis positioning) * Positive = right, Negative = left */ horizontalOffset?: number; /** * Layout mode: 'center' (default) or 'split' for Swiss-style side-by-side */ layoutMode?: 'center' | 'split'; } /** * Manages perspective state with a simple boolean flag. * * Drastically simplified from the complex camera/index system. * Just manages whether content is in "back" or "front" state. * * @example * ```typescript * const perspective = createPerspectiveManager({ * depthStep: 100, * scaleStep: 0.5, * blurStep: 4, * }); * * // Toggle back/front * perspective.toggle(); * * // Check state * const isBack = perspective.isBack; // reactive boolean * ``` */ export class PerspectiveManager { /** * Spring for smooth back/front transitions */ spring = new Spring(0, { stiffness: 0.2, damping: 0.8, }); /** * Reactive boolean: true when in back position (blurred, scaled down) */ isBack = $derived(this.spring.current > 0.5); /** * Reactive boolean: true when in front position (fully visible, interactive) */ isFront = $derived(this.spring.current < 0.5); /** * Configuration values for style computation */ private config: Required; constructor(config: PerspectiveConfig = {}) { this.config = { depthStep: config.depthStep ?? 100, scaleStep: config.scaleStep ?? 0.5, blurStep: config.blurStep ?? 4, opacityStep: config.opacityStep ?? 0.5, parallaxIntensity: config.parallaxIntensity ?? 0, horizontalOffset: config.horizontalOffset ?? 0, layoutMode: config.layoutMode ?? 'center', }; } /** * Toggle between front (0) and back (1) positions. * Smooth spring animation handles the transition. */ toggle = () => { const target = this.spring.current < 0.5 ? 1 : 0; this.spring.target = target; }; /** * Force to back position */ setBack = () => { this.spring.target = 1; }; /** * Force to front position */ setFront = () => { this.spring.target = 0; }; /** * Get configuration for style computation * @internal */ getConfig = () => this.config; } /** * Factory function to create a PerspectiveManager instance. * * @param config - Configuration options * @returns Configured PerspectiveManager instance */ export function createPerspectiveManager(config: PerspectiveConfig = {}) { return new PerspectiveManager(config); }