Move door animations into viewer system

This commit is contained in:
sudhir
2026-05-07 10:11:25 +05:30
parent 0de07d6130
commit cef3f24dad
8 changed files with 181 additions and 109 deletions
+8
View File
@@ -137,6 +137,13 @@ type GuideEvents = {
'guide:deleted': { guideId: GuideNode['id'] }
}
type DoorAnimationEvents = {
'door:animation-completed': {
doorId: DoorNode['id']
field: 'operationState' | 'swingAngle'
}
}
type PresetEvents = {
'preset:generate-thumbnail': { presetId: string; nodeId: string }
'preset:thumbnail-updated': { presetId: string; thumbnailUrl: string }
@@ -178,6 +185,7 @@ type EditorEvents = GridEvents &
CameraControlEvents &
ToolEvents &
GuideEvents &
DoorAnimationEvents &
PresetEvents &
ThumbnailEvents &
SnapshotEvents &
+1
View File
@@ -68,6 +68,7 @@ export {
} from './store/history-control'
export {
type ControlValue,
type DoorAnimationState,
type DoorInteractiveState,
type ItemInteractiveState,
useInteractive,
@@ -17,9 +17,19 @@ export type DoorInteractiveState = {
swingAngle?: number
}
export type DoorAnimationState = {
field: keyof DoorInteractiveState
from: number
to: number
startedAt: number | null
durationMs: number
persist: boolean
}
type InteractiveStore = {
items: Record<AnyNodeId, ItemInteractiveState>
doors: Record<AnyNodeId, DoorInteractiveState>
doorAnimations: Record<AnyNodeId, DoorAnimationState>
/** Initialize a node's interactive state from its asset definition (idempotent) */
initItem: (itemId: AnyNodeId, interactive: Interactive) => void
@@ -35,6 +45,12 @@ type InteractiveStore = {
/** Clear transient door open state */
removeDoorOpenState: (doorId: AnyNodeId) => void
/** Queue a door animation for the viewer frame loop */
startDoorAnimation: (doorId: AnyNodeId, value: DoorAnimationState) => void
/** Cancel a queued door animation */
cancelDoorAnimation: (doorId: AnyNodeId) => void
}
const defaultControlValue = (interactive: Interactive, index: number): ControlValue => {
@@ -53,6 +69,7 @@ const defaultControlValue = (interactive: Interactive, index: number): ControlVa
export const useInteractive = create<InteractiveStore>((set, get) => ({
items: {},
doors: {},
doorAnimations: {},
initItem: (itemId, interactive) => {
const { controls } = interactive
@@ -106,4 +123,20 @@ export const useInteractive = create<InteractiveStore>((set, get) => ({
return { doors: rest }
})
},
startDoorAnimation: (doorId, value) => {
set((state) => ({
doorAnimations: {
...state.doorAnimations,
[doorId]: value,
},
}))
},
cancelDoorAnimation: (doorId) => {
set((state) => {
const { [doorId]: _, ...rest } = state.doorAnimations
return { doorAnimations: rest }
})
},
}))