Vector Paths
Draw and edit fully-editable Bézier paths — the same foundation Illustrator-class vector work is built on. Create paths with the Pen tool, reshape them node-by-node, convert any shape into a path, combine paths with boolean (Pathfinder) operations, and derive new paths with Outline Stroke and Offset Path. Every path renders in both the Sketch and Architectural drawing styles.
The Pen Tool
Pick the Pen / Vector Path tool (the pen-nib icon) from the toolbar, then build a path point by point. Click to drop corner points; click-and-drag to drop a smooth point with curve handles that follow your drag.
| Gesture | Result |
|---|---|
| Click | Add a corner anchor (straight segment) |
| Click + drag | Add a smooth anchor; the drag sets the Bézier handles (curved segment) |
| Click the first anchor | Close the path into a shape filled with your current fill colour. The Pen stays selected for the next shape (unless Settings → Input → Keep tool active is off) and the shape you closed is selected |
| Alt + click the anchor you just placed | Retract its outgoing handle only, so the next segment leaves straight while the curve you drew into it keeps its shape. Keep holding and drag to pull a new outgoing handle on its own |
| Alt + click an earlier anchor | Convert it corner ↔ smooth without leaving the Pen |
| Shift + click (between points) | Constrain the segment to 45° increments: perfectly horizontal, vertical or diagonal lines |
| Shift + drag (while curving) | Clock Method — constrain the Bézier handles to 90°/45° for clean, easily-edited curves |
| Enter / Esc / double-click | Finish the path open (not closed) — you can pick it up again later |
| Space (while dragging out an anchor) | Move the anchor you are placing; its handles come with it. Let go of Space to go back to shaping the curve |
| Ctrl/⌘ + drag an anchor or handle of the path | Fix an earlier point or handle without ending the path (Illustrator's temporary Direct Selection) |
| Ctrl/⌘ + click empty canvas | Finish the path open and stay on the Pen, ready for the next curve |
| Backspace or Ctrl/⌘ + Z | Step back one anchor while still drawing |
| Click an end anchor of an open path | Continue that path from where you stopped |
| Click a segment of the selected path (Pen idle) | Add an anchor there. The cursor shows + |
| Click an anchor of the selected path (Pen idle) | Delete it. The cursor shows − (a path keeps at least two anchors) |
You always see what you are drawing. While a path is under construction the Pen draws a thin blue guide through the anchors, with a square on each one and a rubber-band segment running to the cursor. That guide is independent of the shape's own paint, which matters when you are building a filled shape with no stroke: set the stroke to None, and the object itself is invisible until it closes — the blue guide is what you draw against in the meantime. The guide is construction chrome only; it disappears the moment the path is finished and it never appears in an export.
Leaving a path open is a first-class result, not a fallback. An open path is a stroke — a curve with no fill — and Yappy has four ways to end one: Enter, Esc, a double-click, or Ctrl/⌘ + click anywhere on the canvas. The last one is the one to reach for with a stylus in your hand, and it is the only one that keeps the Pen selected, so drawing a run of separate open curves is one continuous gesture instead of re-picking the tool between each. A single-anchor path is discarded rather than left as a stub.
Undo steps back one point while you are drawing. Ctrl/⌘ + Z mid-path removes the most recent anchor — the same as Backspace — rather than discarding the whole path. (The path is one undo entry until you finish it, so the document undo would have taken all of it at once.) Undo the very first anchor and the path is dropped and the Pen is free. Once the path is finished, Ctrl/⌘ + Z is the ordinary document undo again. The same rule applies to the Polyline tool.
Pause a path and come back to it. You do not have to finish a path in one sitting. Press Esc or Enter (or just switch tools) and the path stays on the canvas, open, as an ordinary object — style it, move it, save the drawing, close the app. To carry on, pick the Pen again and hover over either end of the path: a blue ring appears on the anchor the next click will continue from. Click it and you are back in drawing mode, rubber-band and all, with that anchor as the live end. Clicking the other end then closes the shape.
Either end works. Click the start anchor and the path is continued backwards — Yappy reverses the point order behind the scenes (handles and all, so the curve does not change) so that new points still extend the end you clicked. Rotated paths and compound paths (ones with holes) are not resumable this way; edit those with the Node tool (N) instead.
Shift does two jobs, and which one you get depends on whether you are dragging. Between clicks it aims the next segment: the point snaps to the nearest 45° from the previous anchor, as in Illustrator, so horizontals, verticals and diagonals come out exact (it overrides Snap to Grid for that click). The Line and Arrow tools keep their finer 15° steps. Mid-drag it shapes the handles instead — see the Clock Method below. Clicking the first anchor still closes the path with Shift held.
The Clock Method (90°/45°). Holding Shift while you drag a handle snaps it straight to 12/3/6/9 o'clock (or the diagonals) — the trick pro illustrators use to keep curves smooth and predictable. No keyboard? Switch on the 90°/45° button in the floating Pen options bar, or rest a second finger on the canvas while dragging with the stylus (the same Procreate-style constrain modifier used for proportional resize). The 90°/45° toggle and the second finger constrain segments too, so tablet users get the straight-line behaviour without a keyboard.
The cursor tells you what a click will do. Next to the Pen's crosshair: + adds an anchor to the selected path, − deletes the anchor under it, ○ closes the path you are drawing, and / continues an open path from its end. With no badge, a click starts or extends a path as usual. Add and delete work on the selected path only, so the Pen can still start a new path over any other shape. Picking the Pen with a single path selected keeps it selected, and starting a new path deselects it. Rotated paths are left to the Node tool (N).
A path carries the usual stroke (color / width / style), fill (solid or gradient), and text properties — set them in the property panel like any other shape.
Editing Nodes
Nodes belong to the Node tool, not the Select tool — the same split every other vector editor makes (Illustrator V vs A, Inkscape S vs N). Press N, or simply double-click the path, to reveal its anchors (squares) and Bézier handles (circles). Drag to reshape; use the modifiers below to restructure.
Why the Select tool shows no anchors. It used to. On a four-point curve that was handy; on an outlined word or an imported icon it buried the artwork under hundreds of squares you had no intention of touching — and the anchors sitting on the bounding box quietly stole the corner-resize drag. Select is now purely a move / resize / rotate tool. You can still right-click (or long-press) a path without leaving it to reach Make Smooth / Corner, Delete Anchor and Insert Point Here — those appear at the top of the usual right-click menu, so Group / Ungroup, Pathfinder and the rest are still right there underneath.
| Gesture | Result |
|---|---|
| Drag an anchor | Move the point (its handles travel with it) |
| Drag a handle | Reshape the curve (smooth = mirrored, corner = independent) |
| Shift + drag a handle | Constrain the handle to 90°/45° (Clock Method) |
| Alt + click an anchor | Convert corner ↔ smooth |
| Alt + click a segment | Insert a new anchor on the segment |
| Ctrl/⌘ + click an anchor | Delete that anchor |
On a tablet (no keyboard)
Every node-editing action above has a touch equivalent, so you never need a modifier key on an iPad or touch device:
| Touch gesture | Result | Desktop equivalent |
|---|---|---|
| Tap an anchor | Toggle smooth ↔ corner | Alt-click |
| Long-press an anchor | Menu: Make Smooth/Corner, Delete Anchor | Alt / Ctrl-click |
| Long-press the outline | Menu: Insert Point Here | Alt-click a segment |
| 90°/45° toggle or second finger | Constrain handles (Clock Method) | Hold Shift |
Tapping an anchor toggles its type; dragging it moves it — a small movement threshold keeps the two apart, so a deliberate drag never accidentally flips the point.
The Node tool (Illustrator's “Direct Selection”)
Everything above edits one anchor at a time. Press N — double-click a path, or Command Palette (Ctrl+K) → Node Tool / Direct Selection, or the Vector Tools palette → Nodes — to switch into the dedicated Node tool, which edits many anchors at once. It's the same thing Illustrator calls Direct Selection (the white arrow) and Inkscape calls the Node tool; Yappy uses Inkscape's N because A is already the Arrow tool.
Select a path first — the tool draws anchors for the selected path, so with nothing selected there's nothing to edit. You don't have to leave the tool to move on: click another shape and it becomes the one you're editing, Shift-click to edit several paths at once, and with nothing selected a drag picks shapes rather than anchors. Clicking empty space lets go in two stages — the first click drops the selected anchors, a second drops the path — so missing an anchor by a few pixels doesn't cost you your place.
| Gesture | Result |
|---|---|
| Click another shape | Switch to editing that path — no need to leave the tool |
| Shift + click a shape | Add it, so several paths edit at once |
| Drag on empty space | Marquee-select every anchor inside the box (or shapes, if no path is loaded) |
| Click empty space | Drop the selected anchors; click again to drop the path |
| Shift + marquee | Add those anchors to the selection |
| Drag a selected anchor | Move all selected anchors together |
| Drag a handle | Reshape that one anchor's curvature |
| Ctrl/⌘+A | Select every node of the selected path (as in Inkscape) |
| Del / Backspace | Delete the selected nodes (not the whole shape) |
| Esc | Clear the node selection; press again to leave the tool |
Pressing N again leaves the tool, as does the ✕ in the tool-options bar. Scripted: Yappy.toggleNodeTool(true) / Yappy.toggleNodeTool(false).
Move, resize, rotate, align, snapping, and undo/redo all work on paths exactly as they do for other shapes.
Convert to Path
Turn any shape into an editable vector path in place — same position, z-order, style, and connections. Select one or more shapes, right-click, and choose Path → Convert to Path.
- Rectangles → 4 corner anchors (rounded corners keep their arcs)
- Circles / ellipses → 4 smooth Bézier anchors
- Polygons & stars → exact corner anchors
- Curved shapes (database, cloud, capsule, lightbulb, …) → the outline is converted command by command, so arcs come through as real Bézier curves rather than being sampled into a polygon. A database becomes six anchors — two straight sides and two arcs — not thirty flat chords.
- Shapes whose outline has more than one contour stay compound (their subpaths are kept).
- 3D solids (isometric cube, solid block, perspective block, open box, cylinder) convert to their silhouette — the union of their faces. The interior edges that make them read as 3D are shading, not outline, so they do not survive; you get one editable outline of the whole solid. This also means the Node tool, Warp, Turntable, the Knife and the Pathfinder now work on 3D blocks, which previously refused them outright.
Once converted, every node is editable with the gestures above.
Decoration comes with it. Some shapes are drawn with lines that are not part of their fill outline — a database's cap ellipse, the bars of a predefined process, the rules of an internal storage. Convert to Path now hands those back as their own stroke-only paths alongside the body, selected together with it, instead of dropping them. That is what makes a converted database a usable starting point for a hand-built cylinder: you get the barrel and the rim, both node-editable. (They are separate objects rather than extra subpaths on the body because subpaths fill even-odd — a cap folded into the body ring would punch a hole in the lid.)
If all you want is a tube that is narrower at one end, try the Cylinder shape's Taper slider first — it stays live and editable, where a converted path does not.
Pathfinder (Boolean Operations)
Combine two or more overlapping shapes into a new path. Select the shapes, right-click, and open the Pathfinder submenu. Order matters for Subtract — the back-most (lowest) shape is the base that the others are removed from.
| Operation | Result |
|---|---|
| Unite | Merge all shapes into one outline |
| Subtract | Remove the front shapes from the back-most shape |
| Intersect | Keep only the overlapping region |
| Exclude | Keep everything except the overlap |
Outline Stroke & Offset Path
Both live in the right-click Path submenu.
Outline Stroke
Converts a stroked line or path into a filled shape of the stroke itself (thickness = the current stroke width). The original element is replaced; the new path is filled with the old stroke color. Great for giving a brush-like outline real, editable geometry you can then recolor or combine.
Offset Path
Creates a parallel copy of the path, expanded or contracted by a fixed distance, while keeping the original. Offset Path (+10) grows the outline outward by 10px; Offset Path (−10) shrinks it inward. Handy for concentric outlines, padding, and inset/outset effects.
Stroke Alignment, Corners & End Caps
Three controls in the Properties panel decide how a stroke is actually painted around its outline. They apply to shapes and Pen tool paths, in both the sketch and architectural draw styles.
Stroke Align — Center / Inside / Outside
By default a stroke straddles the outline: half its width falls inside the shape, half outside. That's Center. Switch to:
- Inside — the whole stroke sits within the outline, so the shape never grows past the box you drew. A border stops eating into the space around it.
- Outside — the whole stroke sits outside the outline, so a thick border never covers the artwork or fill it frames.
This is what you want when a region has to line up exactly with a grid or a neighbouring shape — a 12px map border on Center silently overhangs its region by 6px.
Closed outlines only. Inside/Outside need an interior to be meaningful, so the control is offered for closed shapes and closed Pen paths. Open paths, lines, arrows and freehand strokes stay centred.
Corner Style — Sharp / Round / Bevel
How the stroke turns a corner. Miter (Sharp) extends both edges to a crisp point; Round arcs them; Bevel (Flat) cuts the corner off square. Sharp suits technical and architectural work, Round softens icons and routes, Bevel keeps very thick strokes from growing long spikes at tight angles.
End Cap — Butt / Round / Square
How an open path ends — Pen paths, lines and freehand strokes. Butt (Flat) stops the line dead at its last point; Round finishes with a half-circle; Square with a flat extension. Round and Square both push the line past its final point by half the stroke width, so Butt is the one to use when a route must terminate exactly on a coordinate.
const Y = window.Yappy;
// A region whose 12px border stays entirely inside its bounds
Y.createRectangle(100, 100, 200, 140, {
strokeColor: '#1d4ed8', strokeWidth: 12,
backgroundColor: '#bfdbfe', fillStyle: 'solid',
strokeAlign: 'inside', // 'center' (default) | 'inside' | 'outside'
strokeLineJoin: 'miter', // 'round' (default) | 'miter' | 'bevel'
});
// A map route that terminates exactly on its end points
Y.createPath([{ x: 100, y: 300 }, { x: 260, y: 340 }, { x: 400, y: 300 }], {
strokeColor: '#0f766e', strokeWidth: 14,
strokeLineCap: 'butt', // 'round' (default) | 'butt' | 'square'
strokeLineJoin: 'bevel',
});All three survive SVG export: corners and caps map straight onto stroke-linejoin / stroke-linecap, and alignment is reproduced with a clipPath (SVG has no stroke-alignment attribute of its own).
Sketch style is approximate. In the hand-drawn style rough.js paints its own wobbly multi-pass strokes, so alignment is honoured to within the sketchiness rather than to the pixel. Use the architectural style when the edge has to be exact.
Simplify & Compound Paths
In the right-click Path submenu:
| Op | What it does |
|---|---|
| Simplify Ctrl+L | Reduces a path's anchor count while preserving its shape (great after Pathfinder/Outline produce dense corners) |
| Smooth | Rounds off janky corners without dropping anchors — the counterpart to Simplify |
| Join Paths | Connects 2+ open paths into one by chaining nearest endpoints; auto-closes if the free ends meet |
| Make Compound Path | Combines 2+ selected shapes into one path; overlapping areas become holes (even-odd) — the way a donut or the letter “O” is built |
| Release Compound Path | Splits a compound path back into separate, individually editable paths |
Simplify and Smooth work straight off a freehand stroke. If what you selected isn’t a path yet — a pencil/fineliner stroke, a star, a cloud — it is converted to an editable path first, as part of the same action. That means one Ctrl+ Z undoes the whole thing, not just half of it. So the natural loop is: scribble a hill with the freehand tool, press Ctrl+L, and you get a clean, node-editable curve that keeps the hand-drawn wobble.
const Y = window.Yappy;
Y.simplifyPath(); // selection; auto-converts non-paths first
Y.smoothPath(); // same, but rounds corners instead of dropping anchorsExporting as Vector
Export to SVG (Export dialog → SVG) writes every shape and path as a real, scalable <path> — including compound holes (even-odd), rotation, and flips. Sketch-style shapes export as vector rough strokes; architectural shapes export as clean paths. The result opens losslessly in Illustrator, Inkscape, or any browser, with no pixelation.
Holes & Compound Paths
A single path can hold multiple subpaths — letting it have holes (a donut, the counter of an “O”) or several disjoint islands. Holes are produced automatically:
- Subtract a shape from the middle of another → the result keeps the hole.
- Outline Stroke on a closed loop → keeps the inner edge as a hole.
Compound paths fill with the even-odd rule, so overlapping closed subpaths punch holes. Clicking inside a hole clicks through it (it selects whatever is behind, not the path) — matching what you see. Resize, rotate, and both drawing styles work on compound paths just like simple ones.
Compound paths are fully node-editable — select one and every subpath's anchors (including the hole's) can be dragged, converted (Alt-click), deleted (Ctrl/⌘-click), and have new anchors inserted (Alt-click a segment), just like a simple path.
Scripting (API)
Everything the Pen tool and the right-click Path menu do is also available programmatically. The global entry point is window.Yappy (usable as Yappy in the console or a script block). Anchors use the PathAnchor shape { x, y, kind?: 'corner' | 'smooth', inX?, inY?, outX?, outY? }, where the handle offsets are relative to the anchor.
Porting Canvas 2D or Cairo code? Yappy.draw(ctx => { ctx.moveTo(…); ctx.arc(…); ctx.fill(); }) builds these same path elements from pen calls. See the Canvas-style Drawing doc.
Create & read paths
// A closed triangle from three corner anchors
const tri = Yappy.createPath([
{ x: 100, y: 100, kind: 'corner' },
{ x: 260, y: 140, kind: 'corner' },
{ x: 140, y: 260, kind: 'corner' },
], { closed: true, strokeColor: '#1e1e1e', strokeWidth: 2 });
// A smooth curve (Bezier handles via out/in offsets)
Yappy.createPath([
{ x: 100, y: 300, kind: 'smooth', outX: 60, outY: -60 },
{ x: 300, y: 300, kind: 'smooth', inX: -60, inY: -60 },
], { closed: false });
// Read an editable path back
const data = Yappy.getPath(tri); // { anchors, closed } or { subpaths }Holes & compound paths
// A donut: outer ring + inner hole (even-odd fill)
Yappy.createMultiPath([
{ closed: true, anchors: [
{ x: 0, y: 0 }, { x: 200, y: 0 }, { x: 200, y: 200 }, { x: 0, y: 200 },
] },
{ closed: true, anchors: [
{ x: 60, y: 60 }, { x: 140, y: 60 }, { x: 140, y: 140 }, { x: 60, y: 140 },
] },
], { backgroundColor: '#4dabf7' });
// Or build/release a compound from existing selected shapes
Yappy.makeCompoundPath([idA, idB]);
Yappy.releaseCompoundPath([compoundId]);Convert, combine & derive
// Any shape -> editable path (in place)
Yappy.convertToPath([shapeId]);
// Boolean (Pathfinder) ops on 2+ ids
Yappy.pathfinder([a, b], 'union'); // 'union' | 'subtract' | 'intersect' | 'exclude'
Yappy.pathfinderRegion([a, b], 'divide'); // 'divide' | 'trim' | 'merge' | 'crop' | 'outline'
// Stroke -> filled outline shape
Yappy.outlineStroke([lineId]);
// Parallel copy, +grows / -shrinks
Yappy.offsetPath([pathId], 10);
// Chain open paths into one (auto-closes if ends meet)
Yappy.joinPaths([p1, p2]);Tidy up
// Reduce anchor count while keeping the shape
Yappy.simplifyPath([pathId]);
// Smooth anchors (strength 0..1, iterations). No ids -> current selection.
Yappy.smoothPath([pathId], 0.5, 2);Node editing
The Node tool is scriptable as well as clickable. An anchor is addressed by a NodeRef — { id, sub, i }: the element id, which subpath (0 for a simple path), and the anchor's index within it. Operations act on the current anchor selection, which is separate from the element selection.
const Y = window.Yappy;
Y.select(pathId);
Y.toggleNodeTool(true); // show the anchors
// Take every anchor of the selected path(s), then round them all off.
Y.setNodeSelection(Y.allNodesOfSelection());
Y.setSelectedNodesKind('smooth');
// Nudge just the anchors you pick (element-origin units).
Y.setNodeSelection([{ id: pathId, sub: 0, i: 2 }]);
Y.moveSelectedNodes(0, -20);
// Read positions in WORLD space, e.g. to drive your own layout.
Y.getPathNodes(); // [{ ref, x, y, kind }, ...]
Y.getNodeHandles(); // [{ h, x, y, ax, ay }, ...] for the selected anchors
Y.deleteSelectedNodes(); // a subpath is never taken below 2 anchors
Y.toggleNodeTool(false);| Method | Purpose |
|---|---|
toggleNodeTool(active?) | Show/hide the anchors of the selected path(s) |
setNodeSelection(refs) | Replace the anchor selection; refs are { id, sub, i } |
allNodesOfSelection() | Every anchor of every path in the element selection |
getPathNodes() | Selected paths' anchors in world space — { ref, x, y, kind } |
getNodeHandles() | Bézier handles of the selected anchors — { h, x, y, ax, ay } |
moveSelectedNodes(dx, dy) | Move every selected anchor by the same delta |
setSelectedNodesKind(kind) | 'corner' or 'smooth' for the selection |
deleteSelectedNodes() | Delete the selected anchors |
createPath(anchors, opts?) | New single-subpath path; opts.closed fills it |
createMultiPath(subpaths, opts?) | Multi-subpath path (holes / islands, even-odd) |
getPath(id) | Read anchors + closed, or subpaths |
convertToPath(ids) | Turn shapes into editable paths in place |
pathfinder(ids, op) | Boolean: union / subtract / intersect / exclude |
pathfinderRegion(ids, op) | Region: divide / trim / merge / crop / outline |
outlineStroke(ids) | Convert a stroke into a filled outline path |
offsetPath(ids, distance) | Parallel copy (+out / −in) |
simplifyPath(ids) | Reduce anchor count, keep shape |
smoothPath(ids?, strength?, iterations?) | Smooth anchors (defaults 0.5, 2) |
makeCompoundPath(ids) | Combine shapes into one compound path |
releaseCompoundPath(ids) | Split a compound back into separate paths |
joinPaths(ids) | Chain open paths by nearest endpoints |
Need a shape with no dedicated helper? The generics Yappy.createElement('path', x, y, w, h, opts) and Yappy.updateElement(id, { ... }) always work.