Polish editor interaction behavior

This commit is contained in:
Aymeric Rabot
2026-06-10 11:28:12 -04:00
parent bdfee058bd
commit 3a1ba56246
7 changed files with 142 additions and 75 deletions
+29 -1
View File
@@ -40,6 +40,7 @@ import {
} from 'lucide-react'
import Image from 'next/image'
import { type ReactNode, useCallback } from 'react'
import { flushSync } from 'react-dom'
import { cn } from '@/lib/utils'
import { Tooltip, TooltipContent, TooltipTrigger } from './toolbar-tooltip'
@@ -49,6 +50,24 @@ const TOOLBAR_CONTAINER =
const TOOLBAR_BTN =
'flex w-8 items-center justify-center text-muted-foreground/80 transition-colors hover:bg-white/8 hover:text-foreground/90'
function requestWalkthroughPointerLock() {
const canvas = document.querySelector<HTMLCanvasElement>('[data-pascal-viewer-3d] canvas')
if (!canvas) return
if (!canvas.hasAttribute('tabindex')) {
canvas.tabIndex = -1
}
canvas.focus({ preventScroll: true })
if (document.pointerLockElement === canvas) return
try {
canvas.requestPointerLock?.()
} catch {
return
}
}
function ToolbarTooltip({ children, label }: { children: ReactNode; label: string }) {
return (
<Tooltip>
@@ -441,6 +460,15 @@ function DisplayMenu() {
function WalkthroughButton() {
const isFirstPersonMode = useEditor((state) => state.isFirstPersonMode)
const setFirstPersonMode = useEditor((state) => state.setFirstPersonMode)
const handleClick = useCallback(() => {
if (isFirstPersonMode) {
setFirstPersonMode(false)
return
}
flushSync(() => setFirstPersonMode(true))
requestWalkthroughPointerLock()
}, [isFirstPersonMode, setFirstPersonMode])
return (
<ToolbarTooltip label="Walkthrough">
@@ -449,7 +477,7 @@ function WalkthroughButton() {
TOOLBAR_BTN,
isFirstPersonMode && 'bg-emerald-500/15 text-emerald-400 hover:bg-emerald-500/20',
)}
onClick={() => setFirstPersonMode(!isFirstPersonMode)}
onClick={handleClick}
type="button"
>
<Footprints className="h-4 w-4" />