How to apply gradient fill to an object in matter.js
Asked Answered
L

1

1

How do i gradient fill a body created in matter.js?

I have tried this but it won't work:

Bodies.rectangle(400, 520, 800, 120, { render: { fillStyle: 'linear-gradient(50%, red, blue)' } );
Longwinded answered 29/6, 2021 at 8:26 Comment(3)
Use your own renderer such as plain DOM, canvas or p5.js, then you can do whatever you want. MJS' builtin renderer is just for proofs of concept -- MJS' primary role is a headless physics engine, not a full-featured rendering suite. See Using Matter.js to render to the DOM or React and simply apply your desired CSS to the DOM elements.Unfortunate
Thanks for the directions, but i'd need a little more specific piece of code to understand how to use it with plain js (so i would'nt need React) and create my own rendererLongwinded
No React necessary. Use the top code block in the link (plain JS) but change the CSS background property on one or both of the elements to linear-gradient(45deg, blue, red); -- that's it.Unfortunate
U
1

MJS is a physics engine, not a rendering library. The built-in renderer is there for prototyping purposes only. As indicated in the comments, your use case sounds complex enough that you've outgrown the built-in renderer. I'd suggest refactoring to use canvas, the DOM or any other rendering library that suits your fancy.

If you want to use the DOM, take this answer and simply change background: #666; to background: linear-gradient(45deg, blue, red);.

If you want to use HTML5 canvas, here's an example:

const renderVertices = body => {
  ctx.beginPath();
  body.vertices.forEach(({x, y}) => ctx.lineTo(x, y));
  ctx.closePath();
  ctx.fill();
  ctx.stroke();
};

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const gradient = ctx.createLinearGradient(
  0, 0, canvas.width, canvas.height
);
gradient.addColorStop(0, "red");
gradient.addColorStop(1, "blue");
ctx.fillStyle = gradient;
ctx.lineWidth = 2;

const engine = Matter.Engine.create();  
const box = Matter.Bodies.rectangle(150, 0, 40, 40);
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, ground, mouseConstraint]
);

(function rerender() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  renderVertices(box);
  renderVertices(ground);
  Matter.Engine.update(engine);
  requestAnimationFrame(rerender);
})();
body {
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.20.0/matter.min.js"></script>
<canvas width="700" height="400"></canvas>

Once you're comfortable with a headless setup, adapting to another rendering library is straightforward.

Unfortunate answered 25/12, 2022 at 0:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.