import { AnimatedEntity, AnimationData, getAnimatedPropertiesByAnimatedEntity, } from "primitives/AnimatedEntities"; import { AnimatedProperty } from "primitives/AnimatedProperty"; import { AnimatedVec2, ValueType } from "primitives/Values"; import { FC, memo, useCallback, useMemo, useState } from "react"; import { z } from "zod"; import { AnimatedNumberKeyframeIndicator, AnimatedVec2KeyframeIndicator, AnimatedVec3KeyframeIndicator, } from "../KeyframeIndicator"; import { ToggleGroup, ToggleGroupItem } from "components/ToggleGroup"; import { produce } from "immer"; import set from "lodash.set"; import { useEntitiesStore } from "stores/entities.store"; import { AnimatedValue } from "primitives/Values"; import { motion } from "framer-motion"; import { ease } from "@unom/style"; import { TrackDisplayType } from "../Track"; import TrackPropertyGraph from "./TrackPropertyGraph"; import { LineChart } from "lucide-react"; type DisplayState = { type: z.input; selectedAnimatedProperties: Array; }; const TrackAnimatedPropertyKeyframes: FC<{ animatedProperty: z.input; animationData: z.input; onUpdate: (animatedProperty: z.input) => void; selectedDimension?: "x" | "y" | "z"; }> = ({ animatedProperty, animationData, selectedDimension, onUpdate }) => { const handleUpdate = useCallback( (animatedValue: z.input) => { onUpdate({ ...animatedProperty, animatedValue }); }, [onUpdate, animatedProperty] ); switch (animatedProperty.animatedValue.type) { case "Number": return ( ); case "Vec2": return ( ); case "Vec3": return ( ); default: return null; } }; const TrackAnimatedProperty: FC<{ animatedProperty: z.input; animationData: z.input; displayState: DisplayState; index: number; onDisplayStateUpdate: (s: DisplayState) => void; onUpdate: (e: z.input) => void; }> = ({ animatedProperty, animationData, onUpdate, displayState, index, onDisplayStateUpdate, }) => { const [selectedDimension, setSelectedDimension] = useState<"x" | "y" | "z">(); return (

{animatedProperty.label}

selectedDimension === "x" ? setSelectedDimension(undefined) : setSelectedDimension("x") } selected={selectedDimension === "x"} > X selectedDimension === "y" ? setSelectedDimension(undefined) : setSelectedDimension("y") } selected={selectedDimension === "y"} > Y {animatedProperty.animatedValue.type === ValueType.Enum.Vec3 && ( selectedDimension === "z" ? setSelectedDimension(undefined) : setSelectedDimension("z") } selected={selectedDimension === "z"} > Z )} { if (displayState.selectedAnimatedProperties.includes(index)) { onDisplayStateUpdate({ ...displayState, selectedAnimatedProperties: displayState.selectedAnimatedProperties.filter( (index) => index !== index ), }); } else { onDisplayStateUpdate({ ...displayState, selectedAnimatedProperties: [ ...displayState.selectedAnimatedProperties, index, ], }); } }} >
); }; const TrackPropertiesEditor: FC<{ entity: z.input; }> = ({ entity }) => { const animatedProperties = useMemo( () => getAnimatedPropertiesByAnimatedEntity(entity), [entity] ); const handleUpdate = useCallback( (animatedProperty: z.input) => { const entitiesStore = useEntitiesStore.getState(); const nextValue = produce(entity, (draft) => { const animatedValue = animatedProperty.animatedValue; set(draft, animatedProperty.propertyPath, animatedValue); }); const parsedEntity = AnimatedEntity.parse(nextValue); entitiesStore.updateEntityById(parsedEntity.id, parsedEntity); }, [entity] ); const [displayState, setDisplayState] = useState({ type: TrackDisplayType.Enum.Default, selectedAnimatedProperties: [], }); return ( {animatedProperties.map((animatedProperty, index) => ( ))} {displayState.selectedAnimatedProperties.length > 0 && ( animatedProperties[index] )} /> )} ); }; export default memo(TrackPropertiesEditor);