<script src="matter.min.js"></script>
cfg.fw = cfg.fh = Math.sqrt(Math.pow(Math.min(cfg.w, cfg.h) / 2, 2) * 2) * 0.9;
var engine = Matter.Engine.create(document.body, {
engine.metrics.extended = true;
Matter.World.add(engine.world, Matter.MouseConstraint.create(engine));
Matter.Bodies.rectangle(cfg.w / 2, (cfg.h - cfg.fw) / 2 + cfg.frameSize / 2, cfg.fw - cfg.frameSize * 2, cfg.frameSize, {
render: {lineWidth: 1e-6, fillStyle: '#f42'},
Matter.Bodies.rectangle(cfg.w / 2, (cfg.h - cfg.fw) / 2 + cfg.fh - cfg.frameSize / 2, cfg.fw - cfg.frameSize * 2, cfg.frameSize, {
render: {lineWidth: 1e-6, fillStyle: '#f42'},
Matter.Bodies.rectangle((cfg.w - cfg.fw) / 2 + cfg.frameSize / 2, cfg.h / 2, cfg.frameSize, cfg.fw, {
render: {lineWidth: 1e-6, fillStyle: '#f42'},
Matter.Bodies.rectangle((cfg.w - cfg.fw) / 2 + cfg.fw - cfg.frameSize / 2, cfg.h / 2, cfg.frameSize, cfg.fw, {
render: {lineWidth: 1e-6, fillStyle: '#f42'},
var frame = Matter.Body.create({
for (var x = 0; x < cfg.grid; x++) {
for (var y = 0; y < cfg.grid; y++) {
var px = (cfg.fw / (cfg.grid)) * (0.5 + x - cfg.grid / 2);
var py = (cfg.fw / (cfg.grid)) * (0.5 + y - cfg.grid / 2);
var o = Matter.Bodies.circle(px + cfg.w / 2, py + cfg.h / 2, cfg.frameSize / 2, {
render: {lineWidth: 1e-6, fillStyle: '#f42'}
var frameConstraint = Matter.Constraint.create({
pointB: {x: cfg.w / 2, y: cfg.h / 2},
Matter.World.add(engine.world, [frame, frameConstraint]);
var ball = Matter.Bodies.circle(cfg.w / 2, cfg.h / 2, cfg.frameSize * 1.25, {
Matter.World.add(engine.world, ball);
Matter.Events.on(engine, 'collisionStart', function (event) {
for (var i = 0; i < pairs.length; i++) {
pair.bodyA.render.fillStyle = '#000';
pair.bodyA.render.strokeStyle = '#000';
var ind = parts.indexOf(pair.bodyA);
if (parts.length === 4) {
var runner = Matter.Engine.run(engine);
setInterval(function () {
frame.angle += -0.05 * (Math.random() - 0.5);