base(target="_blank")
img(src="https://images.unsplash.com/photo-1540202404-b2979d19ed37?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=700&q=60", data-url="https://unsplash.com/photos/wXt0DiISf38")
img(src="https://images.unsplash.com/photo-1510636767771-f2ef61f98721?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60", data-url="https://unsplash.com/photos/LsIXVKThAG0")
img(src='https://images.unsplash.com/photo-1513039464749-94912b3841ce?ixlib=rb-1.2.1&auto=format&fit=crop&w=700&q=60', data-url="https://unsplash.com/photos/u5K46PukKAo")
img(src="https://images.unsplash.com/photo-1488953994029-e6a7ba3348f7?ixlib=rb-1.2.1&auto=format&fit=crop&w=700&q=60", data-url="https://unsplash.com/photos/dwKd_Epw2GE")
img(src="https://images.unsplash.com/photo-1437622368342-7a3d73a34c8f?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60", data-url="https://unsplash.com/photos/L-2p8fapOA8")

a#elbga(href="https://images.unsplash.com/photo-1437622368342-7a3d73a34c8f?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60") https://unsplash.com/photos/L-2p8fapOA8
View Compiled
img {
  width:200px;
  height:auto;
  display:block;
  background:black;
  position:absolute; top:50%; left:40%; z-index:1;
  transform:translate(-50%,-50%);
  user-select:none;
  cursor:move;
  border:5px solid white;
  box-shadow:0 0 2px 1px rgba(0,0,0,0.2);
}

canvas {
  position:absolute; top:0;  left:0;
  display:none;
  z-index:-1;
}

body {
  min-height:100vh;
  overflow:hidden;
}

.drag {
  box-shadow:0 0 0 2px rgba(0,0,0,1);
}

#elbga {
  position:absolute; top:50%; left:50%;
  transform:translate(-50%,-50%);
  z-index:0;
  color:black;
  filter:opacity(0.2);
  text-shadow:0 0 2px black;
  font:1em/1 monospace;
}
const {
  Engine,
  Render,
  World,
  Bodies,
  Body,
  Mouse,
  MouseConstraint,
  Events,
  Vector
} = Matter;

const FRICTIONAIR = 0.3;
const dragging = {
  body:null,
  TORQUE_SCALE:0.0008
};
const engine = Engine.create();
const render = Render.create({
  element:document.body,
  engine
});



//
// setup world;
// bird view, no gravity
//
engine.world.gravity.y = 0.0;



//
// process dom elements
// 0. random rotation for elm
// 1. create matter body for each elm, add to bodyMap
// 2. listen elm events
//
const elms = document.querySelectorAll("img");
const bodyMap = new WeakMap();

for (const elm of elms) {
  
  const {width, left, top, height} = elm.getBoundingClientRect();
  const cx = left + width * 0.5;
  const cy = top + height * 0.5;
  const body = Bodies.rectangle(cx, cy, width, height);
  body.frictionAir = FRICTIONAIR;
  body.collisionFilter.group = -1; // same -ve means never collide 
  
  const angle = Math.random() * Math.PI/4 - Math.PI/8;
  elm.style.transformOrigin = `50% 50%`;
  Matter.Body.rotate(body, angle, Vector.create(cx, cy));

  World.add(engine.world, [body]);
  bodyMap.set(elm, body);
  elm.ondragstart = () => false;
  elm.onmousedown = e => {
    for (const elm of elms)
      elm.classList.toggle("drag", elm == e.target);
  };
  elm.onmouseover = e => {
    elbga.href = 
      elbga.textContent = e.target.dataset.url;
  }
}



//
// sync dom elm with engine body
//
Matter.Events.on(engine, "tick", e => {
  for (const elm of elms) {
    const body = bodyMap.get(elm);
    // check oob here ...
    elm.style.top = `${body.position.y}px`;
    elm.style.left = `${body.position.x}px`;
    elm.style.transform = `translate(-50%, -50%)rotate(${body.angle}rad)`;
  }
});

//
// Run engine, render(for debug)
//
Engine.run(engine);
Render.run(render);



//
// setup mouseconstraint
//
const mouse = Mouse.create(document.body);
const mouseconstraint = MouseConstraint.create(engine,{
  mouse
});

Events.on(mouseconstraint, "startdrag", e => {
  dragging.body = e.body;
});

Events.on(mouseconstraint, "enddrag", e => {
  dragging.body = null;
});

Events.on(mouseconstraint, "mousemove", e => {
  if (dragging.body) {
    Matter.Body.applyForce(
      dragging.body,
      e.mouse.mousedownPosition,
      Vector.mult(dragging.body.velocity, dragging.TORQUE_SCALE * dragging.body.mass)
    );
  }
})
World.add(engine.world, [mouseconstraint]);


External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.12.0/matter.min.js