UNPKG

resig.js

Version:

Universal reactive signal library with complete platform features: signals, animations, CRDTs, scheduling, DOM integration. Works identically across React, SolidJS, Svelte, Vue, and Qwik.

288 lines 22.8 kB
"use strict"; /** * Animation Scheduler Integration * Connects animation system with the existing scheduler for optimal frame management */ Object.defineProperty(exports, "__esModule", { value: true }); exports.profileAnimations = exports.debugAnimations = exports.getAnimationStats = exports.scheduledTimeline = exports.animate = exports.scheduledAnimation = exports.getGlobalAnimationManager = void 0; const signal_1 = require("../core/signal"); const scheduler_1 = require("../scheduler"); const core_1 = require("./core"); const composer_1 = require("./composer"); // Global animation manager instance let globalAnimationManager = null; const getGlobalAnimationManager = () => { if (!globalAnimationManager) { globalAnimationManager = createAnimationManager(); } return globalAnimationManager; }; exports.getGlobalAnimationManager = getGlobalAnimationManager; // Create animation manager that integrates with scheduler const createAnimationManager = () => { const activeAnimations = (0, signal_1.signal)(new Set()); const frameRate = (0, signal_1.signal)(60); // let lastFrameTime = 0; let frameCount = 0; let fpsUpdateTime = 0; const animations = new Map(); const animationTasks = new Map(); // animationId -> taskId let isRunning = false; let masterTaskId = null; const updateFrameRate = (currentTime) => { frameCount++; if (currentTime - fpsUpdateTime >= 1000) { const fps = frameCount / ((currentTime - fpsUpdateTime) / 1000); frameRate._set(Math.round(fps)); frameCount = 0; fpsUpdateTime = currentTime; } }; const animationLoop = () => { const currentTime = performance.now(); updateFrameRate(currentTime); // Update all active animations const activeIds = new Set(); for (const [id, anim] of Array.from(animations.entries())) { if (!anim.isComplete.value()) { activeIds.add(id); // The animation's internal update loop will handle the actual updates // We just need to track which animations are still active } else { // Animation completed, remove it animations.delete(id); const taskId = animationTasks.get(id); if (taskId) { (0, scheduler_1.cancel)(taskId); animationTasks.delete(id); } } } activeAnimations._set(activeIds); // Continue the loop if there are active animations if (activeIds.size > 0) { return Promise.resolve(); // Continue the scheduled task } else { // No more animations, stop the master loop isRunning = false; masterTaskId = null; return Promise.resolve(); // Stop the scheduled task } }; const startMasterLoop = () => { if (!isRunning && animations.size > 0) { isRunning = true; fpsUpdateTime = performance.now(); frameCount = 0; masterTaskId = (0, scheduler_1.schedule)({ priority: scheduler_1.Priority.HIGH, repeat: true, execute: animationLoop, }); } }; const stopMasterLoop = () => { if (isRunning && masterTaskId) { (0, scheduler_1.cancel)(masterTaskId); isRunning = false; masterTaskId = null; } }; const instance = { activeAnimations, frameRate, register: (animation) => { animations.set(animation.id, animation); // Start the master loop if not already running startMasterLoop(); // Set up cleanup when animation completes animation.onComplete(() => { animations.delete(animation.id); const taskId = animationTasks.get(animation.id); if (taskId) { (0, scheduler_1.cancel)(taskId); animationTasks.delete(animation.id); } // Update active animations const current = activeAnimations.value(); const updated = new Set(current); updated.delete(animation.id); activeAnimations._set(updated); // Stop master loop if no more animations if (updated.size === 0) { stopMasterLoop(); } }); return animation.id; }, unregister: (animationId) => { const animation = animations.get(animationId); if (animation) { animation.stop(); animations.delete(animationId); const taskId = animationTasks.get(animationId); if (taskId) { (0, scheduler_1.cancel)(taskId); animationTasks.delete(animationId); } // Update active animations const current = activeAnimations.value(); const updated = new Set(current); updated.delete(animationId); activeAnimations._set(updated); return true; } return false; }, pause: () => { for (const animation of Array.from(animations.values())) { animation.pause(); } stopMasterLoop(); }, resume: () => { for (const animation of Array.from(animations.values())) { animation.resume(); } startMasterLoop(); }, clear: () => { for (const animation of Array.from(animations.values())) { animation.stop(); } for (const taskId of Array.from(animationTasks.values())) { (0, scheduler_1.cancel)(taskId); } animations.clear(); animationTasks.clear(); activeAnimations._set(new Set()); stopMasterLoop(); }, }; return instance; }; // Create a scheduled animation that integrates with the animation manager const scheduledAnimation = (from, to, duration, interpolator, easing) => { const baseAnimation = (0, core_1.animation)(from, to, duration, interpolator, easing); const isScheduledSignal = (0, signal_1.signal)(false); let taskId = null; const instance = { ...baseAnimation, taskId, isScheduled: isScheduledSignal, start: () => { // Register with animation manager const manager = (0, exports.getGlobalAnimationManager)(); manager.register(baseAnimation); isScheduledSignal._set(true); // Start the base animation baseAnimation.start(); }, stop: () => { // Unregister from animation manager const manager = (0, exports.getGlobalAnimationManager)(); manager.unregister(baseAnimation.id); isScheduledSignal._set(false); // Stop the base animation baseAnimation.stop(); }, pause: () => { baseAnimation.pause(); }, resume: () => { baseAnimation.resume(); }, }; return instance; }; exports.scheduledAnimation = scheduledAnimation; // Utility function to create animations that automatically integrate with scheduler const animate = (from, to, duration, interpolator, easing) => { return (0, exports.scheduledAnimation)(from, to, duration, interpolator, easing); }; exports.animate = animate; // Timeline that integrates with scheduler const scheduledTimeline = () => { const baseTimeline = (0, composer_1.timeline)(); let isRegistered = false; const register = () => { if (!isRegistered) { const manager = (0, exports.getGlobalAnimationManager)(); // Register a dummy animation to keep the manager active const dummyAnim = (0, core_1.animation)(0, 1, baseTimeline.duration, (_f, _t, p) => p); manager.register(dummyAnim); isRegistered = true; } }; const unregister = () => { if (isRegistered) { // Timeline cleanup is handled by the base timeline isRegistered = false; } }; return { ...baseTimeline, register, unregister, start: () => { register(); baseTimeline.start(); }, stop: () => { unregister(); baseTimeline.stop(); }, }; }; exports.scheduledTimeline = scheduledTimeline; // Performance monitoring utilities const getAnimationStats = () => { const manager = (0, exports.getGlobalAnimationManager)(); return { activeCount: manager.activeAnimations.value().size, frameRate: manager.frameRate.value(), scheduler: (0, scheduler_1.getGlobalScheduler)().state.value(), }; }; exports.getAnimationStats = getAnimationStats; // Debug utilities const debugAnimations = () => { const manager = (0, exports.getGlobalAnimationManager)(); const stats = (0, exports.getAnimationStats)(); console.group('Animation Debug Info'); console.log('Active Animations:', stats.activeCount); console.log('Frame Rate:', stats.frameRate, 'fps'); console.log('Scheduler State:', stats.scheduler); console.log('Active Animation IDs:', Array.from(manager.activeAnimations.value())); console.groupEnd(); }; exports.debugAnimations = debugAnimations; // Animation performance profiler const profileAnimations = (duration = 5000) => { const manager = (0, exports.getGlobalAnimationManager)(); const startTime = performance.now(); const samples = []; const sampleInterval = setInterval(() => { const currentTime = performance.now(); samples.push({ time: currentTime - startTime, count: manager.activeAnimations.value().size, fps: manager.frameRate.value(), }); }, 100); setTimeout(() => { clearInterval(sampleInterval); console.group('Animation Performance Profile'); console.table(samples); const avgFps = samples.reduce((sum, s) => sum + s.fps, 0) / samples.length; const maxAnimations = Math.max(...samples.map((s) => s.count)); console.log('Average FPS:', avgFps.toFixed(2)); console.log('Max Concurrent Animations:', maxAnimations); console.groupEnd(); }, duration); return () => clearInterval(sampleInterval); }; exports.profileAnimations = profileAnimations; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZWR1bGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FuaW1hdGlvbi9zY2hlZHVsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7R0FHRzs7O0FBRUgsMkNBQWdEO0FBQ2hELDRDQUtzQjtBQUN0QixpQ0FLZ0I7QUFDaEIseUNBQXNDO0FBb0J0QyxvQ0FBb0M7QUFDcEMsSUFBSSxzQkFBc0IsR0FBNEIsSUFBSSxDQUFDO0FBRXBELE1BQU0seUJBQXlCLEdBQUcsR0FBcUIsRUFBRTtJQUM5RCxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUM1QixzQkFBc0IsR0FBRyxzQkFBc0IsRUFBRSxDQUFDO0lBQ3BELENBQUM7SUFDRCxPQUFPLHNCQUFzQixDQUFDO0FBQ2hDLENBQUMsQ0FBQztBQUxXLFFBQUEseUJBQXlCLDZCQUtwQztBQUVGLDBEQUEwRDtBQUMxRCxNQUFNLHNCQUFzQixHQUFHLEdBQXFCLEVBQUU7SUFDcEQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFBLGVBQU0sRUFBQyxJQUFJLEdBQUcsRUFBVSxDQUFDLENBQUM7SUFDbkQsTUFBTSxTQUFTLEdBQUcsSUFBQSxlQUFNLEVBQUMsRUFBRSxDQUFDLENBQUM7SUFFN0IseUJBQXlCO0lBQ3pCLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztJQUNuQixJQUFJLGFBQWEsR0FBRyxDQUFDLENBQUM7SUFFdEIsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLEVBQTBCLENBQUM7SUFDckQsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUMsQ0FBQyx3QkFBd0I7SUFFMUUsSUFBSSxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ3RCLElBQUksWUFBWSxHQUFrQixJQUFJLENBQUM7SUFFdkMsTUFBTSxlQUFlLEdBQUcsQ0FBQyxXQUFtQixFQUFFLEVBQUU7UUFDOUMsVUFBVSxFQUFFLENBQUM7UUFFYixJQUFJLFdBQVcsR0FBRyxhQUFhLElBQUks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