// matter.js cdn: https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.20.0/matter.min.js
const { Engine, Render, Body, Bodies, Composite } = Matter;
/// matterjs engine and runner
const engine = Engine.create();
// svg variables
const viewportWidth = 400;
const viewportHeight = 400;
const w = 400;
const h = 400;
// svg namespace just in case we're creating some graphics
const namespace = "http://www.w3.org/2000/svg";
// particle vars
let particleGraphic, particleBody;
const particleRadius = 10;
// holder variable
const particleHolder = document.querySelector("#particleHolder");
let floor;
const wallThickness = 100;
// ui
const replayButton = document.querySelector("#replayButton");
function initSVG() {
const svg = document.querySelector("svg");
svg.setAttribute("width", `${viewportWidth}`);
svg.setAttribute("height", `${viewportHeight}`);
svg.setAttribute("viewBox", `0 0 ${w} ${h}`);
const bg = document.querySelector("#bg");
bg.setAttribute("width", `${viewportWidth}`);
bg.setAttribute("height", `${viewportHeight}`);
bg.setAttribute("fill", "#eaeaea");
}
function initRenderer() {
// create renderer
const rendererHolder = document.querySelector("#rendererHolder");
const render = Render.create({
element: rendererHolder,
engine: engine,
options: {
width: w,
height: h,
showAngleIndicator: true
}
});
Render.run(render);
}
function initParticleGraphic() {
particleGraphic = document.createElementNS(namespace, "circle");
particleGraphic.setAttribute("cx", "0");
particleGraphic.setAttribute("cy", "0");
particleGraphic.setAttribute("r", particleRadius);
particleGraphic.setAttribute("fill", "black");
particleHolder.appendChild(particleGraphic);
}
function initParticleBody() {
particleBody = Bodies.circle(0, 0, particleRadius, {
id: `particleBody`,
friction: 0,
restitution: 0.99
});
Body.setPosition(particleBody, { x: w/2, y: particleRadius });
}
function initFloor() {
floor = Bodies.rectangle(w/2, h + wallThickness/2, w, wallThickness, {
isStatic: true,
id: "floor"
});
}
function makeWorld() {
Composite.add(engine.world, [particleBody, floor]);
}
function initUI() {
replayButton.addEventListener("click", () => {
const xpos = particleRadius + Math.random()*(w-2*particleRadius);
const ypos = -particleRadius;
Body.setPosition(particleBody, { x: xpos, y: ypos });
Body.setSpeed(particleBody, 0);
});
}
function update() {
// look at the particleBody position and update graphic position accordingly.
Engine.update(engine);
const pos = particleBody.position;
particleGraphic.setAttribute("cx", pos.x);
particleGraphic.setAttribute("cy", pos.y);
window.requestAnimationFrame(update);
}
initSVG();
initRenderer();
initParticleGraphic();
initParticleBody();
initFloor();
makeWorld();
initUI();
update();