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:
co-authored by
Claude Fable 5
parent
f6a58489b8
commit
51fddc2d9c
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) =>
|
||||
|
||||
Reference in New Issue
Block a user