Matter.js Text inside a rectangle
Asked Answered
B

2

2

i have some rectangles created with Matter.js, like this: Bodies.rectangle (getRandomInt (200,400), 50,140,50, {restitution: 0.7, timeScale: 0.5}) But now I need is to add a text inside that rectangle. How could I do that? The documentation is not clear for this type of actions

Backchat answered 1/7, 2020 at 16:37 Comment(0)
G
7

One of the most common question categories in Matter.js is "how do I do X (with the built-in renderer)?"

I suspect most of these questions come from a fundamental misunderstanding about the purpose of the built-in renderer. Matter.js is foremost a physics engine, not a rendering library. The built-in renderer is only there for prototyping purposes: simple use cases to show wireframes, basic colors or sprites.

The docs are quite explicit:

There is an included debug renderer called Matter.Render. This module is an optional canvas based renderer for visualising instances of Matter.Engine. It is mostly intended for development and debugging purposes, but may also be suitable starting point for simple games.

For just about any rendering need beyond development and debugging, the library expects you to use your own rendering solution that fits your needs.

In this case, text is something that isn't available in the renderer, according to this comment from the creator of MJS in issue #321: Is there anyway to render text in Matter.js?:

Not with the built in debug renderer, if you need to do anything fancy I'd suggest creating your own, see Rendering. A place to start is to copy the code of Matter.Render.

So let's go ahead and use our own renderer instead of trying to push the built-in renderer to do things it wasn't designed for.

The DOM is perfect for text, so that'd be my first suggestion, building on Using Matter.js to render to the DOM or React.

const engine = Matter.Engine.create();
const box = {
  w: 140,
  h: 80,
  body: Matter.Bodies.rectangle(150, 0, 140, 80),
  elem: document.querySelector("#box"),
  render() {
    const {x, y} = this.body.position;
    this.elem.style.top = `${y - this.h / 2}px`;
    this.elem.style.left = `${x - this.w / 2}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, [box.body, ground, mouseConstraint]
);
(function rerender() {
  box.render();
  Matter.Engine.update(engine);
  requestAnimationFrame(rerender);
})();
@import url(https://fonts.bunny.net/css?family=amatic-sc:700);

#box {
  position: absolute;
  background: #111;
  color: #eee;
  height: 80px;
  width: 140px;
  cursor: move;
  user-select: none;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Amatic SC";
  text-shadow: 2px 2px 3px #38e;
}

#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.20.0/matter.min.js"></script>
<div id="box">
  <h1>hello world</h1>
</div>
<div id="ground"></div>

Hopefully this example is enough to show that you can render pretty much anything with the DOM and plug into MJS, from <video> elements to images to <canvas>es, <iframes> to SVGs.

Gunpaper answered 3/7, 2022 at 18:55 Comment(0)
K
-4

Try the following example:

reactionText = Bodies.rectangle(400, 305, 20, 20, {
  isStatic: true,
  render: {
    fillStyle: "transparent",
    strokeStyle: "transparent",
    text: {
      content: "FN",
      color: "black",
      size: 15
    }
  }
})
Kimberli answered 21/4, 2021 at 13:43 Comment(3)
While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value.Hankins
okay I will do it the next time thanks for your adviceKimberli
You can edit the post and improve this one. Also, this doesn't appear to work, so if you could provide a minimal, runnable, complete example showing your approach without room for ambiguity, that'd be great. Thanks.Gunpaper

© 2022 - 2024 — McMap. All rights reserved.