mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-03 12:10:11 +00:00
feat: add animation progress bar for 3D nodes and viewer (#7839)
## Summary - Add draggable progress bar to AnimationControls component - Display current time / total duration - Allow seeking through animations when paused or playing - Add animation controls to 3D Viewer fix https://github.com/Comfy-Org/ComfyUI_frontend/issues/7830 and https://github.com/Comfy-Org/ComfyUI_frontend/issues/7831 ## Screenshots (if applicable) https://github.com/user-attachments/assets/f6d0668c-c7a4-497e-8345-9ef6e47a41c6 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7839-feat-add-animation-progress-bar-for-3D-nodes-and-viewer-2de6d73d36508101ac98f673206b30d9) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -125,6 +125,13 @@ export class AnimationManager implements AnimationManagerInterface {
|
||||
}
|
||||
|
||||
this.animationActions = [action]
|
||||
|
||||
// Emit initial progress to set duration
|
||||
this.eventManager.emitEvent('animationProgressChange', {
|
||||
progress: 0,
|
||||
currentTime: 0,
|
||||
duration: clip.duration
|
||||
})
|
||||
}
|
||||
|
||||
toggleAnimation(play?: boolean): void {
|
||||
@@ -150,8 +157,58 @@ export class AnimationManager implements AnimationManagerInterface {
|
||||
update(delta: number): void {
|
||||
if (this.currentAnimation && this.isAnimationPlaying) {
|
||||
this.currentAnimation.update(delta)
|
||||
|
||||
if (this.animationActions.length > 0) {
|
||||
const action = this.animationActions[0]
|
||||
const clip = action.getClip()
|
||||
const progress = (action.time / clip.duration) * 100
|
||||
this.eventManager.emitEvent('animationProgressChange', {
|
||||
progress,
|
||||
currentTime: action.time,
|
||||
duration: clip.duration
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getAnimationTime(): number {
|
||||
if (this.animationActions.length === 0) return 0
|
||||
return this.animationActions[0].time
|
||||
}
|
||||
|
||||
getAnimationDuration(): number {
|
||||
if (this.animationActions.length === 0) return 0
|
||||
return this.animationActions[0].getClip().duration
|
||||
}
|
||||
|
||||
setAnimationTime(time: number): void {
|
||||
if (this.animationActions.length === 0) return
|
||||
const duration = this.getAnimationDuration()
|
||||
const clampedTime = Math.max(0, Math.min(time, duration))
|
||||
|
||||
// Temporarily unpause to allow time update, then restore
|
||||
const wasPaused = this.animationActions.map((action) => action.paused)
|
||||
this.animationActions.forEach((action) => {
|
||||
action.paused = false
|
||||
action.time = clampedTime
|
||||
})
|
||||
|
||||
if (this.currentAnimation) {
|
||||
this.currentAnimation.setTime(clampedTime)
|
||||
this.currentAnimation.update(0)
|
||||
}
|
||||
|
||||
// Restore paused state
|
||||
this.animationActions.forEach((action, i) => {
|
||||
action.paused = wasPaused[i]
|
||||
})
|
||||
|
||||
this.eventManager.emitEvent('animationProgressChange', {
|
||||
progress: (clampedTime / duration) * 100,
|
||||
currentTime: clampedTime,
|
||||
duration
|
||||
})
|
||||
}
|
||||
|
||||
reset(): void {}
|
||||
}
|
||||
|
||||
@@ -726,6 +726,19 @@ class Load3d {
|
||||
return this.animationManager.animationClips.length > 0
|
||||
}
|
||||
|
||||
public getAnimationTime(): number {
|
||||
return this.animationManager.getAnimationTime()
|
||||
}
|
||||
|
||||
public getAnimationDuration(): number {
|
||||
return this.animationManager.getAnimationDuration()
|
||||
}
|
||||
|
||||
public setAnimationTime(time: number): void {
|
||||
this.animationManager.setAnimationTime(time)
|
||||
this.forceRender()
|
||||
}
|
||||
|
||||
public remove(): void {
|
||||
if (this.contextMenuAbortController) {
|
||||
this.contextMenuAbortController.abort()
|
||||
|
||||
@@ -146,6 +146,9 @@ export interface AnimationManagerInterface extends BaseManager {
|
||||
updateSelectedAnimation(index: number): void
|
||||
toggleAnimation(play?: boolean): void
|
||||
update(delta: number): void
|
||||
getAnimationTime(): number
|
||||
getAnimationDuration(): number
|
||||
setAnimationTime(time: number): void
|
||||
}
|
||||
|
||||
export interface ModelManagerInterface {
|
||||
|
||||
Reference in New Issue
Block a user