Point handles for routes and outlines; Area corners; bus goes round right
Deploy web Studio / deploy (push) Successful in 1m4s

Studio: one selected object with pts (a route, an outlined area) shows a
handle on each point and a + in the middle of each side: drag a point to
move it, drag a + to add one there, double-click a point to remove it
(open routes keep 2, outlines 3). Points snap to the grid and onto wall,
fence and road ends, at any angle; one undo step each. Handles keep their
screen size (new viewer callback onView on every redraw) and follow
re-renders and selection. The viewer captures the pointer, so a double-
click targets the drawing: the last point pressed is remembered instead.

Prefab meta `outline`: the prefab draws pts as its outline. Area has it:
Edit corners turns its rectangle into four points, Rectangle again
removes them.

Routes: where a path doubles back, the lane offset puts a point on each
side, so it rounds into a U-turn instead of a diagonal across the lanes.
The streets demo bus now runs east, three quarters round the roundabout
(clockwise, left-hand traffic), down south street, turns and comes back
by the short way, instead of going round the wrong way on its way out.

Tests: Rust 81 (a doubling-back route: each mover once, no sort cycles),
Studio 134 (corners, move, add, remove, undo), web 100.
This commit is contained in:
grabowski committed 2026-10-25 18:46:47 +07:00
1 parent 540b37020c
commit c8becc2e59
12 files changed
+189 -11

No files matched your search

+6
View File
@@ -185,6 +185,12 @@ body.st-listdrag, body.st-listdrag * { cursor: grabbing !important; }
/* long object lists: rows out of sight are not laid out or painted */
#objects li { content-visibility: auto; contain-intrinsic-size: auto 28px; }
/* point handles of the selected route or outline: points (drag, double-click removes), a + per side (drag adds) */
.iso-svg .st-hline { fill: none; stroke: var(--iso-accent); stroke-width: 1.5; stroke-dasharray: 4 3; vector-effect: non-scaling-stroke; pointer-events: none; }
.iso-svg .st-hpt { fill: #fff; stroke: var(--iso-accent); stroke-width: 2; vector-effect: non-scaling-stroke; cursor: grab; }
.iso-svg .st-hpt:hover, .iso-svg .st-hpt.st-on { fill: var(--iso-accent); }
.iso-svg .st-hmid { fill: var(--iso-accent); fill-opacity: .45; stroke: #fff; stroke-width: 1; vector-effect: non-scaling-stroke; cursor: copy; }
.iso-svg .st-hmid:hover { fill-opacity: 1; }
/* previews while placing: footprints, wall planes, where a window lands */
.iso-svg .st-ghosts { pointer-events: none; }
.iso-svg .st-ghost { fill: color-mix(in srgb, var(--iso-accent) 16%, transparent); stroke: var(--iso-accent); stroke-width: 1.5; stroke-dasharray: 5 3; vector-effect: non-scaling-stroke; stroke-linejoin: round; }