Files
ComfyUI_frontend/src/extensions/core/load3d/load3dRenderLoop.ts
Terry Jia b0fa179b87 refactor: extract Load3d render loop to load3dRenderLoop (#11623)
## Summary

Pull the `requestAnimationFrame` loop and its activity-gated tick body
out of `Load3d` into a small `startRenderLoop({ tick, isActive })`
helper. Pure mechanical refactor — no behavior change. First of four
small PRs splitting up the
https://github.com/Comfy-Org/ComfyUI_frontend/pull/11495.

## Changes

- **What**: New `load3dRenderLoop.ts` exports `startRenderLoop` (returns
a `{ stop }` handle). `Load3d.startAnimation()` now constructs a loop
through it; `Load3d.remove()` calls `stop()` instead of
`cancelAnimationFrame`. Field `animationFrameId: number | null` becomes
`renderLoop: RenderLoopHandle | null`.

## Review Focus

- The tick body inside `startAnimation()` is byte-identical to the
previous inline body — only the rAF scheduling has moved.
- `isActive()` is now invoked through a `() => this.isActive()` closure
instead of a direct call inside the inline `animate` function, so the
activity check still fires once per frame and reads the same fields.
- The new helper has 4 unit tests covering: ticks while active, skip
while inactive, stop halts ticks, stop is idempotent.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11623-refactor-extract-Load3d-render-loop-to-load3dRenderLoop-34d6d73d3650815c9c4ec7713e912e37)
by [Unito](https://www.unito.io)
2026-04-25 20:03:01 -04:00

33 lines
516 B
TypeScript

type RenderLoopOptions = {
tick: () => void
isActive: () => boolean
}
export type RenderLoopHandle = {
stop: () => void
}
export function startRenderLoop({
tick,
isActive
}: RenderLoopOptions): RenderLoopHandle {
let frameId: number | null = null
const loop = () => {
frameId = requestAnimationFrame(loop)
if (!isActive()) return
tick()
}
loop()
return {
stop() {
if (frameId !== null) {
cancelAnimationFrame(frameId)
frameId = null
}
}
}
}