【问题标题】:How can I create an svg body out of svg parts with matter.js?如何使用 matter.js 从 svg 部分创建 svg 主体?
【发布时间】:2023-02-06 07:12:42
【问题描述】:

我的 html 中有两个 svg,想将它们分组,所以最后我有一个包含 2 个 svg 部分的 Body。 我怎样才能做到这一点?

工作笔:https://codepen.io/m42444/pen/eYVEbOq

目前我正在自己渲染这两个 svg,就像下面的代码一样:

const vertexSets = [],

$("#svgOne")
  .find("path")
  .each(function (i, path) {
    var svgOne = Bodies.fromVertices(
      percentX(80),
      percentY(30),
      Matter.Vertices.scale(
        Svg.pathToVertices(path, 10),
        window.innerWidth / 2000,
        window.innerWidth / 2000,
      ),
      {
        render: {
          fillStyle: #F9420B,
          strokeStyle: #F9420B,
          lineWidth: 1,
        },
      },
      true,
    );

    vertexSets.push(svgOne);
  });

$("#svgTwo")
  .find("path")
  .each(function (i, path) {
    var svgTwo = Bodies.fromVertices(
      percentX(80),
      percentY(30),
      Matter.Vertices.scale(
        Svg.pathToVertices(path, 10),
        window.innerWidth / 2000,
        window.innerWidth / 2000,
      ),
      {
        render: {
          fillStyle: #F9420B,
          strokeStyle: #F9420B,
          lineWidth: 1,
        },
      },
      true,
    );

    vertexSets.push(svgTwo);
  });

World.add(engine.world, vertexSets);
<svg id="svgOne" style="position:absolute; width: 0; height: 0" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" xml:space="preserve">
        <g>
          <path class="e" d="M93.87,11.03S-16.33,82.23,2.07,171.13s105.8,179.6,174.3,238c68.5,58.4,109.1,86.2,125.2,179.6s7.3,128.4,53.8,100.2,56.9,2.4,74.5-29.7c17.5-32.2-64.7-117.3-78.4-164.2-13.7-46.8,12-169.1-18.3-328.1C302.87,8.03,164.07-19.67,93.87,11.03Z"/>                  
        </g>
      </svg>


      <svg id="svgTwo" style="position:absolute; width: 0; height: 0" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" xml:space="preserve">
        <g> 
          <path d="M116.37,127.73c9.7-4,18.8-7.8,29.1-12.1-2.9-7.1-5.6-14-8.7-20.8-1.4-3.1-2.2-5.6,1.9-6.9,3.2-1,6.6-3.4,8.8,1.9,7.5,18.5,15.3,37,22.8,55.5,2.1,5.1-2.8,11.6-8.3,11.2-1.3-.1-3.1-2-3.7-3.4-2.5-6.2-4.7-12.5-7.1-18.7-.9-2.5-2-4.9-3.2-7.8-9.3,3.8-18.2,7.6-28.2,11.7,3.1,7.4,6.1,15,9.4,22.6,2.5,5.7-1.1,11.2-7.5,10.7-1.3-.1-3-2-3.6-3.4-7.8-18.6-15.4-37.4-23.2-56-1.5-3.7-1.4-6.5,2.7-8.1,3.9-1.6,7.1-1.7,9.2,2.9,2.9,6.8,6.2,13.5,9.6,20.7Z"/>
        </g> 
      </svg>

【问题讨论】:

  • 请在您的代码中添加更多详细信息。由于您的 sn-p 根本不起作用,因此不清楚什么已经在起作用。您可以通过“添加外部库”按钮在 sn-p 工具中添加 cdn 托管脚本 url (matter.js)。
  • 谢谢@herrstrietzel,刚刚在帖子中添加了一个可用的代码笔。 :)
  • 对不起,唠叨,但你的代码笔不工作。它还需要一个pathSeg polyfill。你可以 fork this pen。目前尚不清楚您要实现的目标。也许您想要的输出的屏幕截图/模型可能会有所帮助。
  • 感谢@herrstrietzel 让我知道!你的笔工作了,现在我想要实现的只是一个带有“H”-svg 的 svg(红色的)。所以最后我得到了一根上面有字母 H 的红色鸡棒。再往上,上面应该有“鸡”字样。
  • 嘿@herrstrietzel,你有时间调查这个问题吗? :) 提前致谢!

标签: javascript html svg matter.js


【解决方案1】:

你的意思是这样的吗?(就像下面的代码一样)

svg 图像看起来不像在网页上那样,但我认为这与 Matter.Svg.pathToVertices 函数有关,因为 documentation 指出:“...请注意,此功能不保证支持复杂路径(例如有孔的路径)。...”

基于提供的 CodePen 精简了演示代码:

let Engine = Matter.Engine,
    Render = Matter.Render,
    Body = Matter.Body,
    Bodies = Matter.Bodies,
    Composite = Matter.Composite,
    Svg = Matter.Svg,
    Vertices = Matter.Vertices,
    Runner = Matter.Runner;

let vertexSets = [],
    firstColor = '#F9420B',
    secondColor = '#009245';

let engine = Engine.create();

let render = Render.create({
    element: document.body,
    engine: engine,
    options: {
        wireframes: false,
        showInternalEdges: false,
        width: 400,
        height: 200,
        background: "#fff"
    }
});

let svgPath = document.querySelector('#svgOne path');
let svgVertices = Bodies.fromVertices(200, 75, Vertices.scale(Svg.pathToVertices(svgPath), .2, .2), {
    render: {
        strokeStyle: firstColor,
        lineWidth: 1
    }
}, true);
    
vertexSets.push(svgVertices);

svgPath = document.querySelector('#svgTwo path'); 

svgVertices = Bodies.fromVertices(240, 50, Vertices.scale(Svg.pathToVertices(svgPath,200),1, 1),{
    render: {
        strokeStyle: secondColor,
        lineWidth: 1
    }
}, true);

vertexSets.push(svgVertices);

let body = Composite.create({});
let constraint1 = Matter.Constraint.create({
        pointA: { x: 0, y: -45 },
        bodyA: vertexSets[0],
        bodyB: vertexSets[1],
        pointB: { x: 24, y: 26 }, 
        stiffness:.1,
        render:{strokeStyle: '#ff0000'},
       length:10
    });
    
let constraint2 = Matter.Constraint.create({
        pointA: { x: -45, y: -40 },
        bodyA: vertexSets[0],
        bodyB: vertexSets[1],
        pointB: { x: -11, y: 30}, 
        stiffness:.1,
        render:{strokeStyle: '#0000ff'},
       length:10
    })
    
Composite.add(body, [...vertexSets, constraint1, constraint2] );

Composite.add(engine.world, [
    body,
    Bodies.rectangle(0, 200, 1200, 50.5, { isStatic: true })
]);

Runner.run(engine);
Render.run(render);
<script src="//cdn.jsdelivr.net/npm/matter-js@0.18.0/build/matter.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/poly-decomp@0.3.0/build/decomp.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/pathseg@1.2.1/pathseg.min.js"></script>
  <body>
    <div class="container"> 
      <svg id="svgOne" style="position:absolute; width: 0; height: 0" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" xml:space="preserve">
        <g><path class="e" d="M93.87,11.03S-16.33,82.23,2.07,171.13s105.8,179.6,174.3,238c68.5,58.4,109.1,86.2,125.2,179.6s7.3,128.4,53.8,100.2,56.9,2.4,74.5-29.7c17.5-32.2-64.7-117.3-78.4-164.2-13.7-46.8,12-169.1-18.3-328.1C302.87,8.03,164.07-19.67,93.87,11.03Z"/></g></svg>
      <svg id="svgTwo" style="position:absolute;display:none" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" xml:space="preserve">
   <g><path d="M116.37,127.73c9.7-4,18.8-7.8,29.1-12.1-2.9-7.1-5.6-14-8.7-20.8-1.4-3.1-2.2-5.6,1.9-6.9,3.2-1,6.6-3.4,8.8,1.9,7.5,18.5,15.3,37,22.8,55.5,2.1,5.1-2.8,11.6-8.3,11.2-1.3-.1-3.1-2-3.7-3.4-2.5-6.2-4.7-12.5-7.1-18.7-.9-2.5-2-4.9-3.2-7.8-9.3,3.8-18.2,7.6-28.2,11.7,3.1,7.4,6.1,15,9.4,22.6,2.5,5.7-1.1,11.2-7.5,10.7-1.3-.1-3-2-3.6-3.4-7.8-18.6-15.4-37.4-23.2-56-1.5-3.7-1.4-6.5,2.7-8.1,3.9-1.6,7.1-1.7,9.2,2.9,2.9,6.8,6.2,13.5,9.6,20.7Z"/></g></svg>
    </div>
</body>

【讨论】:

  • 谢谢@winner_joiner!总体上看起来不错,但现在 svg 格式不正确。创建化合物时,我遇到了完全相同的问题。您是否有其他想法如何避免这种情况?或者它是否在您这边正确显示?
  • @m4424 你可以使用Matter.Constraint来连接身体,但它有点笨拙。我用一个例子更新了答案,它是如何完成的。
  • 谢谢@winner_joiner,但是“h”应该就在大 svg 上..
  • @m4424为此你只需要将两个Contrstrains的属性改为pointA即可。我不是 100% 确定它应该是什么样子,但我更新了代码,以匹配第一个版本。
  • @m4424 好的,我明白了,但是两个身体不能真正重叠。如果你只是想要。要添加文本,请查看问题+答案stackoverflow.com/questions/26043360/…brm.io/matter-js/docs/classes/Body.html#property_render.sprite 以添加纹理。
猜你喜欢
  • 2016-09-16
  • 2018-03-12
  • 1970-01-01
  • 2020-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多