From 102ab47430a104a680d4cf9ea21408118b0d51d8 Mon Sep 17 00:00:00 2001 From: MelekTaus Date: Mon, 21 Sep 2026 06:51:36 +0200 Subject: [PATCH] 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 --- Architecture.md | 5 +++-- Development.md | 2 +- Keyboard.md | 2 +- Vector-Art.md | 39 ++++++++++++++++++++++++++++++--------- 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/Architecture.md b/Architecture.md index 2cc92dc..08a44ee 100644 --- a/Architecture.md +++ b/Architecture.md @@ -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 diff --git a/Development.md b/Development.md index ae2224e..774b45e 100644 --- a/Development.md +++ b/Development.md @@ -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 # 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 diff --git a/Keyboard.md b/Keyboard.md index 48c4757..a2092b4 100644 --- a/Keyboard.md +++ b/Keyboard.md @@ -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)). diff --git a/Vector-Art.md b/Vector-Art.md index 8047265..6d6ef65 100644 --- a/Vector-Art.md +++ b/Vector-Art.md @@ -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.