如何在matter.js中将图像裁剪成圆形

4

当一个球落下时,我希望能够在里面放置图像,但是使用fillStyle渲染无法实现,只能填充颜色,使用sprite可以实现,但它们不适合圆圈,除非图像是圆形的,如何用javascript和matter.js使图像变成圆形?

代码:

return Matter.Bodies.circle(280, 40, 11, {
    restitution: 0.5,
    render: {
        // fillStyle: '#F00',
        // strokeStyle: 'black',
        // lineWidth: 3,
        sprite: {
            texture: img,
            xScale: 0.3,
            yScale: 0.3,  
        }
    }
    
});

img 从抖音获取的是方形图片,我不知道如何将其变为圆形。

2个回答

1

我不100%确定这是否是最好的方法(在你特定的用例中),但你可以:

  • create a helper canvas Element:
    <canvas id='helper-canvas'></canvas> or let canvas = document.createElement('canvas');

  • set the width/height of the canvas (width = desired texture width)

    ...
    canvas.width='100';
    canvas.height='100';
    ...
    
  • draw the image onto a canvas element(using the context).

    ...
    ctx.drawImage(img, 0, 0); // "img" is a HtmlImageElement
    ...
    
  • set composite-mode and draw a circle that should have the desired size

    ...
    ctx.globalCompositeOperation='destination-in';
    ctx.beginPath();
    ctx.arc(img.width/2,img.width/2,img.width/2,0,Math.PI*2);
    ctx.closePath();
    ctx.fill();
    ...
    
  • generate the url of the new "create image"

    ...
    let imgUrl = img.toDataURL('image/png'); 
    ...
    

不仅要创建“matter-body”,还要使用该图像:

Matter.Bodies.circle(280, 40, 11, {
    restitution: 0.5,
    render: {
        sprite: {
            texture: imgUrl,
            xScale: 0.3,
            yScale: 0.3,  
        }
    }      
});

1
你可能正在将内置渲染器用于超出其简单使用情况(调试、原型制作)的范围。考虑在MJS中使用自定义渲染器,以更好地适应典型游戏或动画的渲染复杂性。
你可以使用类似于Matter.js Text inside a rectangle中描述的技术,使用HTML和CSS创建圆形。

document.querySelector("img")
  .addEventListener("load", () => {
  const engine = Matter.Engine.create();
  const circle = {
    body: Matter.Bodies.circle(150, 0, 50),
    elem: document.querySelector("#circle"),
    render() {
      const {x, y} = this.body.position;
      this.elem.style.top = `${y - 50}px`;
      this.elem.style.left = `${x - 50}px`;
      this.elem.style.transform = `rotate(${this.body.angle}rad)`;
    },
  };
  const ground = Matter.Bodies.rectangle(
    200, 200, 400, 120, {isStatic: true}
  );
  const mouseConstraint = Matter.MouseConstraint.create(
    engine, {element: document.body}
  );
  Matter.Composite.add(
    engine.world, [circle.body, ground, mouseConstraint]
  );
  (function rerender() {
    circle.render();
    Matter.Engine.update(engine);
    requestAnimationFrame(rerender);
  })();
});
#circle {
  position: absolute;
  background: #111;
  height: 100px;
  width: 100px;
  top: -100px;
  left: -100px;
  cursor: move;
  border-radius: 50%;
}
#circle img {
  border-radius: 50%;
}

#ground {
  position: absolute;
  background: #666;
  top: 140px;
  height: 120px;
  width: 400px;
}

html, body {
  position: relative;
  height: 100%;
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js"></script>
<div id="circle">
  <img
    draggable="false"
    src="https://4.bp.blogspot.com/-DmPeZ5KQhnM/TvDXvxxb_WI/AAAAAAAAAKI/aRDOjVpBtfM/s1600/poptarticon.gif"
  >
</div>
<div id="ground"></div>

你可以使用 CSS 的 background 属性来替代这里的 <img>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接