Document the four vector point types (#195)

Vector Art explains straight, corner, smooth and symmetric points,
the Point menu in the tab header and the pen that pulls out both
handles. Keyboard keeps Alt-click as the straight/symmetric toggle.
Architecture names the mode rules in polygonEdit, Development the
check sum.

Tests: check sum 1195 is computed (1188 + 7), CI measures it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
adminandClaude Opus 5 committed 2026-09-21 06:51:36 +02:00
1 parent 64305861e0
commit 102ab47430
4 files changed
+35 -13

No files matched your search

+3 -2
@@ -126,7 +126,8 @@ src/editor/ App → Editor (layout + ticker), PlaySession (the run),
polygonEdit (points of an outline: what is under the pointer, whether a point is inside,
put / move / take away — scene view and Texture tab; and the same for a ring of a vector art
shape, where a point may carry Bezier handles: `ringGripAt`, splitting a curved segment
without changing the curve, making a corner round, #129),
without changing the curve, the four point types and how a dragged handle moves the other,
#129, #195),
fileImport (drop/paste) → assetImport (one upload pipeline, an ImportKind per sort) ← textureImport / fontImport / soundImport,
FilePicker (the shared "+ → Texture / Font / Sound" dialog; ImagePicker/FontPicker/SoundPicker only describe their row),
framing (fit/marquee/snap maths), FormDialog (the small modal forms: label column, Cancel + confirm, one open at a time; `dialogButtons` is the closing row every dialog shares, the pickers' included), AssetTabEditor (the shared shell of the asset tabs), TabHeader (the bar across the top of a tab — asset tabs, Plugins tab, NodeBoard; drawn by `drawHeaderBar` like the toolbar and the breadcrumb),
@@ -163,7 +164,7 @@ src/editor/graph/ GraphEditor (header, breadcrumb), GraphCanvas, graphView
src/editor/container/ ContainerEditor (header), ContainerCanvas (a SceneViewport on a template)
src/editor/texture/ TextureEditor (header), TextureCanvas (picture + frames), SliceDialog (a FormDialog), sheetView (the grid maths),
ImagePicker + imageGrid (the "+ → Texture" dialog), checker (the transparency board)
src/editor/vectorart/ VectorArtEditor (header: the two tools and the magnet), VectorArtCanvas (the drawing
src/editor/vectorart/ VectorArtEditor (header: the two tools, the picked point's type and the magnet), VectorArtCanvas (the drawing
painted from core/model/vectorPath onto its own Graphics, with points and handles over it;
the pen puts points down, the arrow drags points, handles and whole shapes, #129),
ShapeList (the shapes as rows with a preview each, in the inspector; a row may be dragged to
+1 -1
@@ -13,7 +13,7 @@ npm run check # typecheck + lint + format:check + tests, the gate CI runs
npm run build # writes dist/ and regenerates index.html
./build.sh # the same under `set -o pipefail`, for callers that pipe the output
php tools/make-user.php <name> <password> # an account; every tool signs in (see Accounts)
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1188 editor checks, screenshots in /tmp/gm-e2e-*.png
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1195 editor checks, screenshots in /tmp/gm-e2e-*.png
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step
./e2e.sh start [GM_STEPS] # the same run detached, see below
./e2e.sh status # live progress, or the last run's result
+1 -1
@@ -14,4 +14,4 @@ and every tab), the value itself is kept at that precision — fields that are i
milliseconds, the index and count ports of list and text nodes) set `NumberField`'s
`decimals: 0` and round to whole numbers · viewport: wheel zooms,
middle-drag or `Shift`+drag pans, drag on empty space rubber-bands, `Ctrl`/`Shift`-click toggles an
object in the selection (hierarchy rows too) · tilemap panel: holding `Alt` switches to Pick – a click takes that cell's tile from the active layer – and releasing it brings back the tool before ([Tilemaps](Tilemaps)) · Vector art tab: `Alt`-click a point to make it round and square again, double-click takes it away, `Esc` ends the line the Pen is drawing, `Delete` removes the selected shape ([Vector art](Vector-Art)).
object in the selection (hierarchy rows too) · tilemap panel: holding `Alt` switches to Pick – a click takes that cell's tile from the active layer – and releasing it brings back the tool before ([Tilemaps](Tilemaps)) · Vector art tab: `Alt`-click a point to make it symmetric and straight again, double-click takes it away, `Esc` ends the line the Pen is drawing, `Delete` removes the selected shape ([Vector art](Vector-Art)).
+30 -9
@@ -37,20 +37,28 @@ A second ring **inside** another cuts a **hole** into it, which is how a ring-sh
letter-like form is made. Holes work by containment: a ring inside a ring is a hole, a ring beside
it is a second area of the same shape.
A point is a **corner** or **round**. A round point carries two handles, `in` and `out`, and the
segment between two points is a curve as soon as one of its two ends has a handle — so a corner may
stand right beside a curved side. The two handles are kept apart, not mirrored: pulling one does not
swing the other, which is what lets a curve break at a point.
A point may carry two handles, `in` and `out`, and the segment between two points is a curve as soon
as one of its two ends has a handle — so a sharp point may stand right beside a curved side. What a
point is decides what dragging one of its handles does to the other:
| Type | Handles | Dragging one handle |
|---|---|---|
| **Straight** | none | — both sides of the point are straight |
| **Corner** | free | leaves the other where it is, so the curve breaks at the point |
| **Smooth** | in line | turns the other to the opposite side and keeps its length |
| **Symmetric** | in line, same length | mirrors the other exactly |
The type only steers the next drag; it changes nothing that is drawn.
## The tab
The toolbar holds **Select**, **Pen**, the magnet and **Fit**; the view pans and zooms like the
Texture tab, and the checkerboard behind the canvas is what is transparent.
The toolbar holds **Select**, **Pen**, **Point**, the magnet and **Fit**; the view pans and zooms
like the Texture tab, and the checkerboard behind the canvas is what is transparent.
**Pen** draws a new shape:
- A click puts a point down; **dragging** while putting it down pulls the two handles out, so a
curve is drawn in one gesture.
- A click puts a straight point down; **dragging** while putting it down pulls both handles out,
mirrored, so a curve is drawn in one gesture and the point is symmetric.
- A click on the **first point** closes the ring and ends the shape.
- **Esc** ends the line where it is, leaving an open ring.
@@ -60,9 +68,22 @@ Texture tab, and the checkerboard behind the canvas is what is transparent.
- A click **on a segment** puts a new point there. On a curved segment the curve is *split*, not
cut: both halves together draw exactly what was drawn before.
- A **double click** on a point takes it away.
- **Alt** on a point makes it round, and a round one square again.
- **Alt** on a straight point makes it symmetric, and a point with handles straight again.
- **Delete** removes the selected shape.
The point pressed last — or put down last with the Pen — is **picked** and drawn filled. The
**Point** menu in the toolbar shows its type and turns it into another one, as one undo step:
- **Straight** takes both handles away.
- A straight point that becomes **Corner**, **Smooth** or **Symmetric** first grows handles along
the line between its two neighbours, a third of the way to each.
- **Smooth** and **Symmetric** line the handles up on the direction between them, so the curve keeps
its general course; Smooth keeps each length, Symmetric gives both their mean.
- **Corner** leaves the handles where they are and sets them free.
A point put on a curved segment is smooth, since the split leaves its handles in line; a symmetric
point at either end of that segment becomes smooth, because the split shortens one of its handles.
The **magnet** snaps to 8 units while it is lit; it is off by default. It is the same switch the
graph tabs carry. **Fit** brings the whole canvas back
into view.