🚀 Auto-deploy: melhoria no snap e medição AR em 24/05/2026 16:22:27

This commit is contained in:
2026-05-24 16:22:27 +00:00
parent febb533f5e
commit 00a8cee511
+28 -16
View File
@@ -384,16 +384,28 @@ function useLabelDistanceFactor(position: [number, number, number]): number {
const dist = camera.position.distanceTo(v); const dist = camera.position.distanceTo(v);
const perspCam = camera as THREE.PerspectiveCamera; const perspCam = camera as THREE.PerspectiveCamera;
const fov = (perspCam.fov ?? 50) * (Math.PI / 180); const fov = (perspCam.fov ?? 50) * (Math.PI / 180);
const worldPerPixel = (2 * dist * Math.tan(fov / 2)) / size.height; const height = size.height || 1;
const worldPerPixel = (2 * dist * Math.tan(fov / 2)) / height;
// distanceFactor scales the html so it stays ~140 px tall at this distance // distanceFactor scales the html so it stays ~140 px tall at this distance
ref.current = Math.max(0.05, worldPerPixel * 140); ref.current = isNaN(worldPerPixel) || !isFinite(worldPerPixel) ? 1.5 : Math.max(0.05, worldPerPixel * 140);
}); });
return ref.current; return ref.current;
} }
function MeasurementLabel({ position, text, variant, fixed = false }: { position: [number, number, number]; text: string; variant: 'success' | 'primary' | 'accent'; fixed?: boolean }) { function DynamicLabel({ position, text, borderClass, textClass }: { position: [number, number, number]; text: string; borderClass: string; textClass: string }) {
const dfDynamic = useLabelDistanceFactor(position); const dfDynamic = useLabelDistanceFactor(position);
const df = fixed ? dfDynamic : 1.5; return (
<Html position={position} center distanceFactor={dfDynamic} zIndexRange={[100, 0]} style={{ pointerEvents: 'none' }}>
<div className={`rounded bg-card/95 border ${borderClass} px-2 py-0.5 shadow-lg backdrop-blur-sm`}>
<span className={`font-mono text-[11px] font-bold ${textClass} whitespace-nowrap`}>
{text}
</span>
</div>
</Html>
);
}
function MeasurementLabel({ position, text, variant, fixed = false }: { position: [number, number, number]; text: string; variant: 'success' | 'primary' | 'accent'; fixed?: boolean }) {
const borderClass = variant === 'success' const borderClass = variant === 'success'
? 'border-success/60' ? 'border-success/60'
: variant === 'accent' : variant === 'accent'
@@ -404,8 +416,11 @@ function MeasurementLabel({ position, text, variant, fixed = false }: { position
: variant === 'accent' : variant === 'accent'
? 'text-amber-400' ? 'text-amber-400'
: 'text-primary'; : 'text-primary';
return (
<Html position={position} center distanceFactor={df} zIndexRange={[100, 0]} style={{ pointerEvents: 'none' }}> return fixed ? (
<DynamicLabel position={position} text={text} borderClass={borderClass} textClass={textClass} />
) : (
<Html position={position} center distanceFactor={1.5} zIndexRange={[100, 0]} style={{ pointerEvents: 'none' }}>
<div className={`rounded bg-card/95 border ${borderClass} px-2 py-0.5 shadow-lg backdrop-blur-sm`}> <div className={`rounded bg-card/95 border ${borderClass} px-2 py-0.5 shadow-lg backdrop-blur-sm`}>
<span className={`font-mono text-[11px] font-bold ${textClass} whitespace-nowrap`}> <span className={`font-mono text-[11px] font-bold ${textClass} whitespace-nowrap`}>
{text} {text}
@@ -473,15 +488,12 @@ function ModelMeasurements({ modelId }: { modelId: string }) {
/** Renders snap indicator, hover tooltip, pending point and any *legacy* /** Renders snap indicator, hover tooltip, pending point and any *legacy*
* world-frame measurements that aren't attached to a specific model. */ * world-frame measurements that aren't attached to a specific model. */
function HoverLabelOverlay({ hoverInfo }: { hoverInfo: HoverInfo | null }) { function HoverLabelOverlay({ hoverInfo }: { hoverInfo: HoverInfo }) {
const visible = !!hoverInfo; const position = hoverInfo.position;
const position = hoverInfo?.position ?? [0, 0, 0]; const text = hoverInfo.type === 'hole'
const text = hoverInfo
? hoverInfo.type === 'hole'
? `Ø ${hoverInfo.value.toFixed(1)}` ? `Ø ${hoverInfo.value.toFixed(1)}`
: `${hoverInfo.value.toFixed(1)} mm` : `${hoverInfo.value.toFixed(1)} mm`;
: ''; const variant = hoverInfo.type === 'hole' ? 'accent' : 'primary';
const variant = hoverInfo?.type === 'hole' ? 'accent' : 'primary';
const dfDynamic = useLabelDistanceFactor(position); const dfDynamic = useLabelDistanceFactor(position);
@@ -500,8 +512,6 @@ function HoverLabelOverlay({ hoverInfo }: { hoverInfo: HoverInfo | null }) {
zIndexRange={[100, 0]} zIndexRange={[100, 0]}
style={{ style={{
pointerEvents: 'none', pointerEvents: 'none',
display: visible ? 'block' : 'none',
opacity: visible ? 1 : 0,
}} }}
> >
<div className={`rounded bg-card/95 border ${borderClass} px-2 py-0.5 shadow-lg backdrop-blur-sm`}> <div className={`rounded bg-card/95 border ${borderClass} px-2 py-0.5 shadow-lg backdrop-blur-sm`}>
@@ -530,7 +540,9 @@ function MeasurementOverlay() {
)} )}
{/* Hover auto-detect tooltip (works both inside and outside measure mode) */} {/* Hover auto-detect tooltip (works both inside and outside measure mode) */}
{hoverInfo && (
<HoverLabelOverlay hoverInfo={hoverInfo} /> <HoverLabelOverlay hoverInfo={hoverInfo} />
)}
{/* Pending first point (always in world coords) */} {/* Pending first point (always in world coords) */}
{measurePoints.length === 1 && ( {measurePoints.length === 1 && (