jonobr1 / two.js

A renderer agnostic two-dimensional drawing api for the web.
https://two.js.org
MIT License
8.3k stars 455 forks source link

[Question] SVG String to `two.interpret` argument #664

Closed dan-fritchman closed 2 years ago

dan-fritchman commented 2 years ago

Great project, thanks much for your work on it.
And extra thanks for the support I've seen you provide on other issues and forums.

My question:
I have a string with SVG content.
What would I need to do with it, to make a valid argument to two.interpret?

https://codepen.io/dan-fritchman/pen/RwMzbgL

import Two from 'https://cdn.skypack.dev/two.js@latest';

var two = new Two({
  type: Two.Types.svg,
  fullscreen: true,
  autostart: true
}).appendTo(document.body);

const someSvgString = `
<svg>
  <g>
    <path d="M 0 0 L 0 8 L 10 8 L 10 24 L 0 24 L 0 32 " />
  </g>
</svg>`;

// Something needs to come between this `someSvgString` 
// and the argument to `two.interpret()`; 
// I'm not clear on just what.
const twoSvgGroup = two.interpret(someSvgString);
twoSvgGroup.visible = true;
twoSvgGroup.translation.set(two.width/2, two.height/2);
twoSvgGroup.center();
twoSvgGroup.stroke = 'black';

two.update();

In the CodePen that produces nothing; in my larger application it generates:

index.js:420 Uncaught TypeError: Cannot read properties of undefined (reading 'toLowerCase')
    at _Two.interpret (two.module.js?fc08:10165:1)
    at eval (renderer.js?5bd3:48:1)
    at ./src/renderer.js (index.js:300:1)
    at __webpack_require__ (index.js:417:33)
    at index.js:1484:37
    at index.js:1486:12

That CodePen, and my application's usage, both started from the "Interpret SVGs" example:
https://codepen.io/jonobr1/pen/KKvYXzp

Which stores the content in HTML, and loads it via document.querySelectorAll.

Thanks again!

jonobr1 commented 2 years ago

Glad you're enjoying the library! Unfortunately, until this issue is resolved, there's not a super elegant way. Though as a workaround for the moment, you can use the two.load method which will stuff your SVG String into an offscreen div. Use it like so:

const group = two.load(svgString);
// It doesn't automatically add your group to the scene, so don't forget to do that!
two.add(group);
dan-fritchman commented 2 years ago

Outstanding, thanks very much!