SVG Canvas — vector drawing that emits SVG

Showcase of Engine.createSVGCanvas — same API surface as the raster CanvasHandle (fill / pen / drawPath / linearGradient / radialGradient / drawText) but the output is a real SVG document rather than rasterised pixels. Demonstrates radial gradients, layered glow rings, accent dots, and SVG-native text in two fonts.

SVG canvas (rasterised)
SVG canvas (rasterised) — SVG Canvas — vector drawing that emits SVG
JavaScript
// Vector-native drawing via Engine.createSVGCanvas — same API as
// createCanvas() but emits an SVG document instead of rasterizing.
// demo_svg_canvas.js
//!NOIMAGE
//!OUTPUT: OUTPUT
//!PARAM: WIDTH:integer=600,min=200,max=1600
//!PARAM: HEIGHT:integer=400,min=200,max=1200
//!PARAM: TITLE:string=mlc OpticScript

// ── 1. Build an SVG canvas ────────────────────────────────────────────────
const svg = Engine.createSVGCanvas(WIDTH, HEIGHT);

// Background — radial gradient via canvas API. Same call shape as
// CanvasHandle, but the gradient ends up as a <radialGradient> in <defs>.
svg.radialGradient(
  px(WIDTH / 2, HEIGHT / 2),
  Math.max(WIDTH, HEIGHT) * 0.7,
  ["#1a1a2e", "#16213e"],
  [0, 1],
);
svg.drawPath(Engine.createPath().rect(0, 0, WIDTH, HEIGHT));

// Glow ring stack — circles with decreasing alpha + linear gradient stroke.
const cx = WIDTH / 2, cy = HEIGHT / 2;
for (let i = 0; i < 5; i++) {
  const r = 60 + i * 30;
  svg.pen([0.91, 0.27, 0.38, 0.6 - i * 0.1], 2);
  svg.drawPath(Engine.createPath().circle(cx, cy, r), true);
}

// Filled centre — radial highlight via gradient.
svg.radialGradient(
  px(cx, cy),
  60,
  ["#e94560", "#e9456000"],   // hex8 with trailing alpha
  [0, 1],
);
svg.drawPath(Engine.createPath().circle(cx, cy, 60));

// Three accent dots on the right, using save/restore + translate.
svg.save();
svg.translate(WIDTH - 80, cy);
svg.fill("#0f3460");
for (let i = -1; i <= 1; i++) {
  svg.drawPath(Engine.createPath().circle(0, i * 20, 6));
}
svg.restore();

// Title text — SVG <text> with embedded font hint.
svg.drawText(TITLE, cx, cy + 100, {
  font: "Inter",
  size: 28,
  color: "#ffffff",
  anchor: "middle",
});
svg.drawText("vector → svg", cx, cy + 130, {
  font: "JetBrains Mono",
  size: 14,
  color: "#94a3b8",
  anchor: "middle",
});

// ── 2. Serialise + rasterise so the playground can preview the result ────
const svgMarkup = svg.toString();
const img = Engine.loadSVG(svgMarkup, 2.0);   // 2× for crisp preview
Engine.saveImage(img, "OUTPUT");

`SVG canvas → ${svgMarkup.length} chars, rasterised to ${img.width}×${img.height}`;

// © 2026 Michael Lechner · mlc OpticScript · https://mlcgo.eu · Elastic License 2.0