Respect unit preference in alignment guides

This commit is contained in:
Aymeric Rabot
2026-06-07 00:27:08 -04:00
parent f84910848b
commit 2b3d3d06b5
2 changed files with 9 additions and 19 deletions
@@ -1,7 +1,9 @@
'use client'
import { useAlignmentGuides } from '@pascal-app/core'
import { useViewer } from '@pascal-app/viewer'
import { memo } from 'react'
import { formatMeasurement } from '../editor/measurement-pill'
import { useFloorplanRender } from './floorplan-render-context'
/**
@@ -23,6 +25,7 @@ import { useFloorplanRender } from './floorplan-render-context'
*/
export const FloorplanAlignmentGuideLayer = memo(function FloorplanAlignmentGuideLayer() {
const guides = useAlignmentGuides((s) => s.guides)
const unit = useViewer((s) => s.unit)
const ctx = useFloorplanRender()
if (guides.length === 0) return null
@@ -56,7 +59,7 @@ export const FloorplanAlignmentGuideLayer = memo(function FloorplanAlignmentGuid
// offset along X.
const pillX = axis === 'x' ? midX + pillOffset : midX
const pillZ = axis === 'z' ? midZ + pillOffset : midZ
const distLabel = formatMeters(distMeters)
const distLabel = formatMeasurement(distMeters, unit)
const charWidth = pillFontSize * 0.55
const pillWidth = distLabel.length * charWidth + pillPadX * 2
const pillHeight = pillFontSize + pillPadY * 2
@@ -135,10 +138,3 @@ function XCap({
</g>
)
}
function formatMeters(meters: number): string {
// Sub-centimetre = "0". Otherwise show with up to 2 decimals, trimmed.
if (meters < 0.005) return '0'
const fixed = meters.toFixed(2)
return `${fixed.replace(/\.?0+$/, '')}m`
}
@@ -8,6 +8,7 @@ import { memo, useMemo, useRef } from 'react'
import { BoxGeometry, CircleGeometry, type Group } from 'three'
import { MeshBasicNodeMaterial } from 'three/webgpu'
import { EDITOR_LAYER } from '../../lib/constants'
import { formatMeasurement } from './measurement-pill'
/**
* Figma-style alignment guides for the 3D editor — the spatial twin of
@@ -53,6 +54,7 @@ type Vec3 = [number, number, number]
export const Alignment3DGuideLayer = memo(function Alignment3DGuideLayer() {
const guides = useAlignmentGuides((s) => s.guides)
const levelId = useViewer((s) => s.selection.levelId)
const unit = useViewer((s) => s.unit)
const groupRef = useRef<Group>(null)
// Guides carry only XZ (building-local plan coords); their Y has to track
@@ -71,16 +73,16 @@ export const Alignment3DGuideLayer = memo(function Alignment3DGuideLayer() {
return (
<group ref={groupRef}>
{guides.map((guide, i) => (
<GuideLine guide={guide} key={i} />
<GuideLine guide={guide} key={i} unit={unit} />
))}
</group>
)
})
function GuideLine({ guide }: { guide: AlignmentGuide }) {
function GuideLine({ guide, unit }: { guide: AlignmentGuide; unit: 'metric' | 'imperial' }) {
const { x: fx, z: fz } = guide.from
const { x: tx, z: tz } = guide.to
const distLabel = formatMeters(guide.distance)
const distLabel = formatMeasurement(guide.distance, unit)
// Lay out the dash centres along the from→to direction. The ribbon
// stretches the dash period up if the line is long enough to exceed the
@@ -152,11 +154,3 @@ function Dot({ position }: { position: Vec3 }) {
/>
)
}
function formatMeters(meters: number): string {
// Sub-centimetre = "0"; otherwise up to 2 decimals, trimmed. Matches the
// 2D floor-plan guide layer's pill formatting.
if (meters < 0.005) return '0'
const fixed = meters.toFixed(2)
return `${fixed.replace(/\.?0+$/, '')}m`
}