Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
984 views
in Technique[技术] by (71.8m points)

javascript - How to use an SVG image in Matter.js?

What I'm trying to do: Use a Font Awesome SVG - sleigh - in matter.js.

I've tried this:

Matter.Bodies.fromVertices(500, 50 , Matter.Svg.pathToVertices("sleigh.svg"))

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M612.7 350.7l-9.3-7.4c-6.9-5.5-17-4.4-22.5 2.5l-10 12.5c-5.5 6.9-4.4 17 2.5 22.5l9.3 7.4c5.9 4.7 9.2 11.7 9.2 19.2 0 13.6-11 24.6-24.6 24.6H48c-8.8 0-16 7.2-16 16v16c0 8.8 7.2 16 16 16h516c39 0 73.7-29.3 75.9-68.3 1.4-23.8-8.7-46.3-27.2-61zM32 224c0 59.6 40.9 109.2 96 123.5V400h64v-48h192v48h64v-48c53 0 96-43 96-96v-96c17.7 0 32-14.3 32-32s-14.3-32-32-32h-96v64c0 35.3-28.7 64-64 64h-20.7c-65.8 0-125.9-37.2-155.3-96-29.4-58.8-89.6-96-155.3-96H32C14.3 32 0 46.3 0 64s14.3 32 32 32v128z"/></svg>

But got:

matter.js:4624 matter-js: Svg.pathToVertices: SVGPathSeg not defined, a polyfill is required.

matter.js:7554 Uncaught TypeError: Cannot read property 'numberOfItems' of undefined

What am I doing wrong?

(P. S: I'm pretty new to matter.js, so sorry if this is a silly question…)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Getting this working can be a bit of a fuss because, as the docs point out, there are a couple of external scripts necessary to polyfill SVGPathSeg and to decompose a 2D polygon into convex pieces. Version frustrations ensue.

The versions that worked for me after referencing the official example and this outdated Codepen example are shown below in the snippet.

Worth noting, the Matter.Bodies.fromVertices docs state: "if the vertices are concave, they will be decomposed if poly-decomp.js is available. Note that this process is not guaranteed to support complex sets of vertices (e.g. those with holes may fail)" which probably accounts for the extra line you see in the rendered body.

Furthermore, MJS' built-in renderer is mainly for prototyping purposes, so the fact that there's an extra line on the body likely won't matter if you're animating the original SVG element on the page. You may also try the premium font-awesome filled sleighs, but I don't have access to them.

const engine = Matter.Engine.create();
const render = Matter.Render.create({
  element: document.body,
  engine: engine
});
const bodies = [
  Matter.Bodies.rectangle(400, 210, 810, 60, {isStatic: true}),
  ...[...document.querySelectorAll("svg > path")].map(path => {
    const body = Matter.Bodies.fromVertices(
      100, 80, Matter.Svg.pathToVertices(path), {}, true
    );
    Matter.Body.scale(body, 0.2, 0.2);
    return body;
  })
];
Matter.World.add(engine.world, bodies);
Matter.Runner.run(engine);
Matter.Render.run(render);
svg {display: none;}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/pathseg.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/decomp.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.17.1/matter.js"></script>
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="sleigh" class="svg-inline--fa fa-sleigh fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="currentColor" d="M612.7 350.7l-9.3-7.4c-6.9-5.5-17-4.4-22.5 2.5l-10 12.5c-5.5 6.9-4.4 17 2.5 22.5l9.3 7.4c5.9 4.7 9.2 11.7 9.2 19.2 0 13.6-11 24.6-24.6 24.6H48c-8.8 0-16 7.2-16 16v16c0 8.8 7.2 16 16 16h516c39 0 73.7-29.3 75.9-68.3 1.4-23.8-8.7-46.3-27.2-61zM32 224c0 59.6 40.9 109.2 96 123.5V400h64v-48h192v48h64v-48c53 0 96-43 96-96v-96c17.7 0 32-14.3 32-32s-14.3-32-32-32h-96v64c0 35.3-28.7 64-64 64h-20.7c-65.8 0-125.9-37.2-155.3-96-29.4-58.8-89.6-96-155.3-96H32C14.3 32 0 46.3 0 64s14.3 32 32 32v128z"></path></svg>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...