fix: capture-mode polish for studio & presets + pausable render loop (#469)

* fix(editor): keep snapshot pitch out of preset thumbnail capture

The capture overlay's snapshot hint and 'Take snapshot' shutter label
rendered in every capture variant, clashing with the save-as-preset
flow's own 'Frame your item — click Capture' banner. Gate them on the
existing isPreset discriminator and label the shutter 'Capture' there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(viewer): renderPaused flag suspends the frame loop

Hosts that fully cover the canvas (e.g. the studio gallery overlay) can
set renderPaused to stop FrameLimiter's RAF loop — a heavy animated
scene otherwise keeps starving the GPU behind the overlay and makes it
stutter.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(editor): drop the crop/format HUD in preset capture

The pills crowded the save-as-preset banner and repeat what the fixed
square frame already shows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(editor): no contextual shortcut hints in the studio workspace

Holding Shift surfaced select-mode/snapping hints over the studio
compose panel and gallery, where there is no scene selection or tool to
act on.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Wassim SAMAD
2026-07-07 17:10:53 -04:00
committed by GitHub
co-authored by Claude Fable 5
parent f6a58489b8
commit 51fddc2d9c
4 changed files with 27 additions and 6 deletions
@@ -1,5 +1,6 @@
import { useThree } from '@react-three/fiber'
import { useLayoutEffect } from 'react'
import useViewer from '../../store/use-viewer'
type FrameLimiterProps = {
fps?: number
@@ -8,8 +9,11 @@ type FrameLimiterProps = {
const FrameLimiter: React.FC<FrameLimiterProps> = ({ fps = 50 }) => {
const { advance, set, frameloop: initFrameloop, scene, clock } = useThree()
const renderer = useThree((state) => state.gl)
// Fully covered canvas (e.g. studio gallery) → stop advancing frames
const renderPaused = useViewer((s) => s.renderPaused)
useLayoutEffect(() => {
if (renderPaused) return
let elapsed = 0
let then = 0
let i = 0
@@ -35,7 +39,7 @@ const FrameLimiter: React.FC<FrameLimiterProps> = ({ fps = 50 }) => {
}
set({ frameloop: initFrameloop })
}
}, [fps, advance, set, initFrameloop])
}, [fps, advance, set, initFrameloop, renderPaused])
return null
}
+7
View File
@@ -49,6 +49,10 @@ type ViewerState = {
isExporting: boolean
setExporting: (value: boolean) => void
/** Suspend the render loop while the canvas is fully covered (e.g. studio gallery). */
renderPaused: boolean
setRenderPaused: (value: boolean) => void
shading: RenderShading
shadingByContext: Partial<Record<RenderContext, RenderShading>>
setShading: (shading: RenderShading) => void
@@ -233,6 +237,9 @@ const useViewer = create<ViewerState>()(
isExporting: false,
setExporting: (value) => set({ isExporting: value }),
renderPaused: false,
setRenderPaused: (value) => set({ renderPaused: value }),
shading: 'rendered',
shadingByContext: {},
setShading: (shading) =>