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.
@KennethCooney Do you fix this problem?
If you're just looking for a way to render a simple UI or instructions you could also just layer another canvas element on top of the canvas the Matter.Render is using and draw text on that. I'm using typescript and wasn't really keen on the idea making my own render class. I get it's somewhat of a hacky work around but this was a simple enough solution and accomplished what I need.
I stumbled upon this question/answer multiple times while searching google for an easy solution. Maybe this will help someone else in the same situation...
If you're wondering how to implement this, here's a quick example to get you off the ground. Make your own custom copy of MatterRenderer (as liabru stated). Then in the render.bodies function there is a loop that is responsible for rendering each individual body (should be around line 616) include the following at the end immediately after c.globalAlpha = 1; (around line 706)
c.globalAlpha=1;
//Here's the custom part
if(part.render.text)
{
//30px is default font size
var fontsize = 30;
//arial is default font family
var fontfamily = part.render.text.family || "Arial";
//white text color by default
var color = part.render.text.color || "#FFFFFF";
if(part.render.text.size)
fontsize = part.render.text.size;
else if(part.circleRadius)
fontsize = part.circleRadius/2;
var content = "";
if(typeof part.render.text == "string")
content = part.render.text;
else if(part.render.text.content)
content = part.render.text.content;
c.textBaseline="middle";
c.textAlign="center";
c.fillStyle=color;
c.font = fontsize+'px '+fontfamily;
c.fillText(content,part.position.x,part.position.y);
}
Then in your code instead of importing Matter.Renderer import your custom renderer, and use as follows :
//an example using a circle
Bodies.circle(x,y,circleSize,{
restitution:0.95,
friction:0.05,
density:0.0005,
render:{
fillStyle:"#C44D58",
text:{
content:"Test",
color:"blue",
size:16,
family:"Papyrus",
},
},
});
Or you can just set render.text to a string and the rest will be set to the defaults we defined in the custom renderer.
This is an overly simplified solution and the following issues still exist
@antontsvil Thanks for your idea, it works for me. But I wonder if matter.js should provide a Render Middleware Mechanism(like middleware in koa or redux), which programer can acquire ctx and perform their own render logic.
@lcx-seima you can use the beforeRender and afterRender events on the renderer, you can get the context at any time from render.canvas or just use render.context. You could also extend the renderer using your own plugin. Generally though the built in renderer is only intended for debugging so it is advised to write your own renderer for anything more complex.
I want to create an animation of word tiles that behave like solid bodies. So move around bouncing off each other. But I need to be able to easily populate the tiles with different strings. Would like to use matter.js to manage the movement. Is this possible?
You could just set each letter as a texture (pngs), and use transparent rectangles as "hit boxes" around each letter. seems overkill to expect this library to have a body.text engine, when fonts can be so weird and unpredictable.
I might be late to the party, but if your project is using P5.js, this is an easy solution to render text while using Matter.js.
Based on P5-matter of @shiffman AKA CodingTrain I made a quick demo.
馃拵 Tip: The text is rendered in a same-sized invisible rectangle, this rectangle is recreated at
Bodies.rectangle(x, y, 90, 60, params);So if you change the text, the width ofBodies.rectangleneeds to be updated too. I can imagine if you have multiple strings of text from an array, this being a dynamic value calculated on the width of the text being passed inmakeCircle(). This way you can have multiple words floating around without overlap.
Most helpful comment
If you're wondering how to implement this, here's a quick example to get you off the ground. Make your own custom copy of MatterRenderer (as liabru stated). Then in the render.bodies function there is a loop that is responsible for rendering each individual body (should be around line 616) include the following at the end immediately after
c.globalAlpha = 1;(around line 706)Then in your code instead of importing
Matter.Rendererimport your custom renderer, and use as follows :Or you can just set render.text to a string and the rest will be set to the defaults we defined in the custom renderer.
This is an overly simplified solution and the following issues still exist