No description
  • TypeScript 86.3%
  • CSS 13.4%
  • HTML 0.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-23 18:12:01 +07:00
src Add reparenting link feature to hand and halo 2026-09-23 18:12:01 +07:00
.gitignore Initial commit 2026-09-23 17:14:06 +07:00
index.html Initial commit 2026-09-23 17:14:06 +07:00
package-lock.json Initial commit 2026-09-23 17:14:06 +07:00
package.json Initial commit 2026-09-23 17:14:06 +07:00
README.md Initial commit 2026-09-23 17:14:06 +07:00
tsconfig.json Initial commit 2026-09-23 17:14:06 +07:00

Halo — a vector editor built around the Morphic halo

A TypeScript prototype of the Morphic halo (Self → Squeak/Smalltalk) applied to a vector drawing editor. Every shape is a morph; morphs contain other morphs; clicking one surrounds it with a halo of coloured handles, each a direct-manipulation verb.

npm install
npm run dev        # http://localhost:5173
npm run build      # typecheck + production bundle

The halo

Selecting an object surrounds it with a halo of handles; each handle performs one operation when pressed or dragged.

Handle Does
Delete delete the object and its children
Object menu arrange, flip, parent / unparent, group, clip, convert to path, stroke, export; the menu can be pinned as a tear-off
Reparent drag onto another object to nest it there (Alt-drop → root)
Move · hold G move within the current parent (Shift constrains)
Duplicate drag out a copy
Collapse collapse to a label
Edit points edit path points (paths only)
Rotate · hold R rotate about centre (Shift: 15°)
Fill / stroke colour picker; the handle shows the current fill and stroke
Scale · hold S uniform scale, including stroke and children
Resize · hold Alt+S resize geometry; children keep position (Shift constrains)

Hold-key modes: while G / R / S / Alt+S is held, simply moving the mouse moves / rotates / scales / resizes the selection (with nothing selected, the object under the pointer) — no click needed. Releasing the key applies it as one undo step; Esc or right-click cancels and restores. Pressing another mode key mid-hold applies the current change and switches mode — except S ⇄ Alt+S: tapping Alt while S is held swaps between proportional scale and free resize, re-applied from where the operation began. The matching halo button lights up and a mode badge shows in the viewport.

Selection follows the Morphic halo model: the first click selects the top-level object under the cursor, clicking again steps into the child under the cursor, Shift-click selects the parent. Alt+↑/↓ and Tab walk the hierarchy; the status bar shows the path as breadcrumbs.

Workspace: medium-grey DCC-style layout with a menu bar (File / Edit / Object / View), a tool strip (select, pen, polygon, plus draggable create tools), a docked Properties panel (drag a numeric label to scrub its value: Shift ×10, Alt ×0.1) and a Layers outliner. Also: right-click menus, scroll-wheel zoom and middle-drag pan (Space+drag also pans), undo/redo, autosave to localStorage, SVG export.

Layout

  • src/morphs.ts — the morph model: transform, submorphs, SVG sync, clipping, collapse, serialization
  • src/world.ts — scene root, pan/zoom view, per-frame render loop, hit testing, snapshot undo
  • src/halo.ts — handle definitions and the halo overlay (plus vertex editing)
  • src/hand.ts — carrying and dropping morphs (reparenting while preserving world transform)
  • src/ops.ts — the operations behind handles and menus
  • src/editor.ts — tools, input handling, chrome (menu bar, tool strip, status, reference)
  • src/outliner.ts — Layers panel
  • src/inspector.ts — Properties panel; src/colorPicker.ts, src/menu.ts — pop-ups