/** * AnimationPlayer.jsx * Per-model animation controls with working play/pause/loop/speed/switch. * Connects to ModelManager's mixer via the store. */ import { useState } from 'react' import useStore from '../store/useStore' const COLORS = ['#4f8eff','#ef4444','#22c55e','#f59e0b','#8b5cf6','#f97316'] function AnimBlock({ model, colorIdx }) { const { setModelActiveAnimation, setModelAnimSpeed, setModelAnimPlaying } = useStore.getState() const c = COLORS[colorIdx % COLORS.length] const playing = model.animationPlaying const switchTo = (name) => { setModelActiveAnimation(model.id, name) setModelAnimPlaying(model.id, true) } const togglePlay = () => { setModelAnimPlaying(model.id, !playing) } if (!model.animations.length) return null return (
{/* Header */}
{model.name} {model.animations.length} clip{model.animations.length>1?'s':''}
{/* Now playing indicator */} {model.activeAnimation && (
{model.activeAnimation} {playing ? 'PLAYING' : 'PAUSED'}
)} {/* Clip list */}
{model.animations.map(anim => { const isActive = model.activeAnimation === anim return ( ) })}
{/* Controls row */}
{/* Play/Pause */} {/* Stop */} {/* Speed slider */}
SPD setModelAnimSpeed(model.id, +e.target.value)} style={{ flex:1 }} /> {model.animationSpeed.toFixed(1)}×
) } export default function AnimationPlayer() { const models = useStore(s => s.models) const animated = models.filter(m => (m.animations?.length??0)>0) if (!animated.length) { return (
🎞
No animations detected
Load a GLB with built-in animation clips.
Try: Fox, Robot, Soldier, Flamingo
) } return (
{animated.length} animated model{animated.length>1?'s':''}
{animated.map(m => ( ))}
) }