canvas

loader / svg

What this shows

Parse SVG files into ShapeGeometry fills and stroke meshes over a grid, with toggles for strokes, fills and wireframes.

Side by side with the three.js r186 original: webgl_loader_svg.html

Differences from three.js

  • The default file is Joins and caps instead of Tiger, and the Tiger, emoji, blueprint, Defs, Defs2, Defs3, Defs4 and Defs5 files are left out: tiger.svg is the Ghostscript tiger (AGPL-3.0), emoji.svg is a Noto Emoji glyph, blueprint.svg is a third-party Illustrator file with no stated license, and tests/testDefs/* are CC-BY-SA 2.5.
  • EASEL's SVGLoader has no createFillMaterial, createStrokeMaterial or pointsToStroke, so the port builds BasicMaterials from each path's style (fill defaults to black, stroke width to 1) and draws each stroke segment as a plain quad, without line joins, caps or miter limits.
  • EASEL's SVGLoader ignores <style> sheets, CSS classes, <use>/<defs> references, gradients and non-px units, so Style CSS inside defs, Multiple CSS classes, Styles in svg tag and Units draw with default black fills, and gradient fills fall back to a flat color.
  • EASEL's SVG path parser reads the implicit line-to pairs after an absolute M command as relative from the second pair on, so paths written as M x,y x,y x,y (the Joins and caps shapes, among others) draw distorted.
  • EASEL's SVG path parser rejects arc commands whose flags are packed against the next number (for example A4.679 4.679 0 0012.711.092), so Test 9 shows only the grid.
  • SVG opacity is rounded to EASEL's 9 discrete opacity levels, and draw order follows material.layer because EASEL has no per-mesh renderOrder.
EASEL (Canvas2D)
This example needs a canvas-capable browser.

Loading scene…

three.js r186 (WebGL)
This example needs a canvas-capable browser.

Loading scene…

Loading scene…

Key API excerpt

import * as EASEL from "@xsyetopz/easel";


const data = new EASEL.SVGLoader().parse(svgText);

for (const path of data.paths) {
  const material = new EASEL.BasicMaterial({
    color: path.color,
    side: EASEL.Side.Double,
    depthWrite: false,
  });

  for (const shape of path.toShapes()) {
    group.add(new EASEL.Mesh(new EASEL.ShapeGeometry(shape), material));
  }
}

renderer.prepare(scene, camera);
renderer.render(scene, camera);