Text centered at x = (w2 + w) / 2 — the middle of the wide right
portion of the trapezoid where there's the most space.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Place text centered at the wide bottom edge where there's always
enough room. No font shrinking — the wide end has plenty of space.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Center text at 75% of trapezoid height where the shape is widest,
using the actual width at that height for proper fit.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Center text at vertical midpoint, shifted right toward the wider end
where there's more horizontal space. Uses 55% of the mid-height width
as center position and 85% as available width.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move text to 65% from top (wider end) so it fits without shrinking
- Fix effective angle for mirrored symbols: use (360-rot) to determine
if flip is needed, preventing incorrect upside-down detection
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Position text at 40% from top (toward narrow end) and constrain width
to the narrower edge so text never overflows the trapezoid shape.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mirrored symbols need text counter-mirrored (scale -1,1) to prevent
backwards text. Restored mirror fix that was incorrectly removed.
Applied to both canvas renderer and SVG export.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Labels now follow the mirrored shape naturally — text mirrors
along with the conveyor/shape as the user expects.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Canvas renderer:
- Straight/spur: flip text 180 when rotation is 91-269 deg
- Mirror: counter-scale text so it doesn't read backwards
- Curved: compute world angle (sym rotation + tangent), flip if upside-down
SVG export:
- Curved text now includes rotation transform along the arc tangent
- Straight text includes rotation correction for readability
- All text stays grouped with its shape for proper transform inheritance
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Wrap each conveyance shape + its label text in a <g> element so
rotation/mirror transforms apply to both shape and text together
- Change stroke-width from 0.5 to 1 on all conveyance and PE shapes
(both canvas renderer and SVG export)
- Text is now inside the group, inheriting the transform — no more
floating unrotated labels
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Curved: position text at arc band midpoint, rotated along the curve
- Spur: center text in the trapezoid shape, not the bounding box
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Parse labels like UL17_22_VFD into stacked text: "UL" / "17-22".
Bold black Arial, targets 14px but auto-scales down to fit with
consistent padding. Strips _VFD suffix, splits prefix from numbers.
If full text doesn't fit, strips the letter prefix.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix shift-drag: require 8px movement before locking axis, use strict
greater-than to avoid horizontal bias at small deltas
- Add PE shape-following outline for selection/hover/collision highlights
- Add PE shape-aware hit-testing (arrow + beam + receiver zones with margin)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SVG-based rendering caused non-uniform stroke scaling when symbols were
stretched. Now conveyor, chute, tipper are drawn as canvas rects, and
extendo is drawn as a canvas path with fixed left bracket proportions.
All use consistent 0.5px stroke regardless of size.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Change all conveyance SVGs from black fill to white fill with black stroke
- Update programmatic rendering (curves, induction, spur) to white fill
- Replace PE 3-slice rendering with programmatic canvas paths for
consistent stroke width at any size
- Reduce PE default size from 56x20 to 30x14 to fit around conveyor devices
- Update SVG export to match new white fills
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Right box stroke now uses EPC_CONFIG.lineWidth (1.5) instead of 0.3
- Right box positioned at -rb.w (backward) matching canvas renderer
- End box rotated 90° (perpendicular to line) in canvas, export, and hit-testing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Increase EPC line width from 0.4 to 1.5 for visibility
- Increase right box stroke from 0.3 to 1.0 to match left icon stroke
- Fix right box to extend behind last waypoint (like left icon), not forward
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Collision detection now mirrors spur trapezoid and induction arrow
vertices when the symbol is mirrored, matching the visual appearance.
Previously the collision polygon stayed unmirrored causing false
positives/misaligned collision zones.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Blue dashed rectangle drawn while dragging
- Selects all visible symbols whose bounding box intersects the marquee
- Respects hidden symbols and hidden groups
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Right-click context menu: "Hide" option to hide individual symbols
- "Show All Hidden" appears in context menu when anything is hidden
- Top visibility bar with toggle chips for each device group
- Hidden symbols are excluded from rendering, hit testing, and SVG export
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add search filter to Devices tab in right dock
- Add IDs tab: flat list of unassigned device IDs, drag onto placed symbol to assign label
- Highlight drop target symbol with cyan glow during label drag
- Add labelDropTarget state and dropTarget theme entry
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Split collision.ts (707→549): extract distance.ts (pure math) and grid-snap.ts
- Fix curved conveyor/chute outline to match SVG viewBox geometry
- Draw curves programmatically with fixed 30px band width (no SVG stretching)
- Single resize handle for curves (was 2)
- Add .gitattributes for consistent line endings
- Make Vec2 type module-private
- Add mirror transform support in renderer
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>