feat(editor): wall room/single + fence continuous/single chain toggles
Replace the legacy held-Alt mechanism on wall and fence drafting with a mode toggle, mirroring the snapping-mode chip: - Wall: `wallChainMode` room (auto-close on loop) / single. Room mode finishes automatically when the new endpoint lands within the join-snap radius of the chain's first vertex; single commits one wall per click. - Fence: `fenceChainMode` continuous (chain until double-click/Esc) / single. Fences are linear barriers, so continuous has no auto-close. - Both: Alt-tap cycles the active drafting tool's chain mode (clean-tap, scoped to wall/fence drafting); a clickable HUD chip shows the mode. Persisted + migrated in `useEditor`. Migrate wall and fence off held-Alt-bypass-alignment to the unified convention: alignment now follows the magnetic snap mode, which frees Alt for the toggle. 2D floorplan parity kept in sync with the 3D tools. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
6d02ad424e
commit
2666b07479
@@ -467,8 +467,7 @@ export const FenceTool: React.FC = () => {
|
||||
}
|
||||
|
||||
// Align the drafted point onto another object's nearest real anchor and
|
||||
// publish the guide. Alt bypasses alignment. Returns the possibly snapped
|
||||
// point.
|
||||
// publish the guide. Returns the possibly snapped point.
|
||||
const alignPoint = (point: FencePlanPoint, bypass: boolean): FencePlanPoint => {
|
||||
// Figma alignment pulls the endpoint onto existing corners / edges, so it
|
||||
// is a line snap — suppress it whenever magnetic snap is off (`'off'` /
|
||||
@@ -500,8 +499,9 @@ export const FenceTool: React.FC = () => {
|
||||
const localPoint: FencePlanPoint = [event.localPosition[0], event.localPosition[2]]
|
||||
// While drafting, the segment locks to 15° rays from its start.
|
||||
// Snapping is governed by the snapping mode (`'off'` is the bypass);
|
||||
// there is no Shift hold-to-bypass. Alt still bypasses alignment guides.
|
||||
const bypassAlign = event.nativeEvent?.altKey === true
|
||||
// there is no Shift hold-to-bypass. Alignment follows the magnetic snap
|
||||
// mode, not Alt (Alt-tap toggles continuous/single chaining).
|
||||
const bypassAlign = !isMagneticSnapActive()
|
||||
|
||||
if (buildingState.current === 1) {
|
||||
const angleLocked = isAngleSnapActive()
|
||||
@@ -567,7 +567,7 @@ export const FenceTool: React.FC = () => {
|
||||
|
||||
const { walls, fences } = getCurrentLevelElements()
|
||||
const localClick: FencePlanPoint = [event.localPosition[0], event.localPosition[2]]
|
||||
const bypassAlign = event.nativeEvent?.altKey === true
|
||||
const bypassAlign = !isMagneticSnapActive()
|
||||
|
||||
if (buildingState.current === 0) {
|
||||
const snappedStart = alignPoint(
|
||||
@@ -612,6 +612,13 @@ export const FenceTool: React.FC = () => {
|
||||
refreshAlignmentCandidates()
|
||||
useAlignmentGuides.getState().clear()
|
||||
|
||||
// Single mode commits one segment per click: stop drafting so the next
|
||||
// click starts a fresh segment instead of chaining off this endpoint.
|
||||
if (useEditor.getState().fenceChainMode === 'single') {
|
||||
stopDrafting()
|
||||
return
|
||||
}
|
||||
|
||||
const nextStart = createdFence.end
|
||||
// Publish the resolved chain start so the 2D floor-plan draft
|
||||
// chains its next segment from the same point (its own snap
|
||||
|
||||
Reference in New Issue
Block a user