UNPKG

@thi.ng/hiccup-canvas

Version:

Hiccup shape tree renderer for vanilla Canvas 2D contexts

124 lines (123 loc) 2.94 kB
import { fromEndPoints } from "@thi.ng/geom-arc/from-endpoints"; import { __endShape } from "./internal/end-shape.js"; const path = (ctx, attribs, segments) => { ctx.beginPath(); let a = [0, 0]; for (let i = 0, n = segments.length; i < n; i++) { const s = segments[i]; let b = s[1], c, d; switch (s[0]) { // move to case "m": b = [a[0] + b[0], a[1] + b[1]]; case "M": ctx.moveTo(b[0], b[1]); a = b; break; // line to case "l": b = [a[0] + b[0], a[1] + b[1]]; case "L": ctx.lineTo(b[0], b[1]); a = b; break; // horizontal line rel case "h": b = [a[0] + b, a[1]]; ctx.lineTo(b[0], b[1]); a = b; break; // horizontal line abs case "H": b = [b, a[1]]; ctx.lineTo(b[0], b[1]); a = b; break; // vertical line rel case "v": b = [a[0], a[1] + b]; ctx.lineTo(b[0], b[1]); a = b; break; // vertical line abs case "V": b = [a[0], b]; ctx.lineTo(b[0], b[1]); a = b; break; // cubic curve rel case "c": c = s[2]; d = s[3]; d = [a[0] + d[0], a[1] + d[1]]; ctx.bezierCurveTo( a[0] + b[0], a[1] + b[1], a[0] + c[0], a[1] + c[1], d[0], d[1] ); a = d; break; // cubic curve abs case "C": c = s[2]; d = s[3]; ctx.bezierCurveTo(b[0], b[1], c[0], c[1], d[0], d[1]); a = d; break; // quadratic curve rel case "q": c = s[2]; c = [a[0] + c[0], a[1] + c[1]]; ctx.quadraticCurveTo(a[0] + b[0], a[1] + b[1], c[0], c[1]); a = c; break; // quadratic curve abs case "Q": c = s[2]; ctx.quadraticCurveTo(b[0], b[1], c[0], c[1]); a = c; break; // elliptic arc (SVG compatible) case "A": case "a": { c = s[2]; d = s[6]; s[0] === "a" && (d = [a[0] + d[0], a[1] + d[1]]); const { center: [x, y], start, end } = fromEndPoints(a, d, [b, c], s[3], s[4], s[5]); ctx.ellipse(x, y, b, c, s[3], start, end, !s[5]); a = d; break; } // circular arc rel // Note: NOT compatible w/ SVG arc segments case "r": c = s[2]; c = [a[0] + c[0], a[1] + c[1]]; ctx.arcTo(a[0] + b[0], a[1] + b[1], c[0], c[1], s[3]); a = c; break; // circular arc abs // Note: NOT compatible w/ SVG arc segments case "R": c = s[2]; ctx.arcTo(b[0], b[1], c[0], c[1], s[3]); a = c; break; // close path case "z": case "Z": ctx.closePath(); } } __endShape(ctx, attribs); }; export { path };