I'm new to Matter JS, so please bear with me. I have the following code I put together from demos and other sources to suit my needs:
function biscuits(width, height, items, gutter) {
const {
Engine,
Render,
Runner,
Composites,
MouseConstraint,
Mouse,
World,
Bodies,
} = Matter
const engine = Engine.create()
const world = engine.world
const render = Render.create({
element: document.getElementById('canvas'),
engine,
options: {
width,
height,
showAngleIndicator: true,
},
})
Render.run(render)
const runner = Runner.create()
Runner.run(runner, engine)
const columns = media({ bp: 'xs' }) ? 3 : 1
const stack = Composites.stack(
getRandom(gutter, gutter * 2),
gutter,
columns,
items.length,
0,
0,
(x, y, a, b, c, i) => {
const item = items[i]
if (!item) {
return null
}
const {
width: itemWidth,
height: itemHeight,
} = item.getBoundingClientRect()
const radiusAmount = media({ bp: 'sm' }) ? 100 : 70
const radius = item.classList.contains('is-biscuit-4')
? radiusAmount
: 0
const shape = item.classList.contains('is-biscuit-2')
? Bodies.circle(x, y, itemWidth / 2)
: Bodies.rectangle(x, y, itemWidth, itemHeight, {
chamfer: { radius },
})
return shape
}
)
World.add(world, stack)
function positionDomElements() {
Engine.update(engine, 20)
stack.bodies.forEach((block, index) => {
const item = items[index]
const xTrans = block.position.x - item.offsetWidth / 2 - gutter / 2
const yTrans = block.position.y - item.offsetHeight / 2 - gutter / 2
item.style.transform = `translate3d(${xTrans}px, ${yTrans}px, 0) rotate(${block.angle}rad)`
})
window.requestAnimationFrame(positionDomElements)
}
positionDomElements()
World.add(world, [
Bodies.rectangle(width / 2, 0, width, gutter, { isStatic: true }),
Bodies.rectangle(width / 2, height, width, gutter, { isStatic: true }),
Bodies.rectangle(width, height / 2, gutter, height, { isStatic: true }),
Bodies.rectangle(0, height / 2, gutter, height, { isStatic: true }),
])
const mouse = Mouse.create(render.canvas)
const mouseConstraint = MouseConstraint.create(engine, {
mouse,
constraint: {
stiffness: 0.2,
render: {
visible: false,
},
},
})
World.add(world, mouseConstraint)
render.mouse = mouse
Render.lookAt(render, {
min: { x: 0, y: 0 },
max: { x: width, y: height },
})
}
I have a HTML list of links that mimics the movements of the items in Matter JS (the positionDomElements function). I'm doing this for SEO purposes and also to make the navigation accessible and clickable.
However, because my canvas sits on top of my HTML (with opacity zero) I need to be able to make the items clickable as well as draggable, so that I can perform some other actions, like navigating to the links (and other events).
I'm not sure how to do this. I've searched around but I'm not having any luck.
Is it possible to have each item draggable (as it already is) AND perform a click event of some kind?
Any help or steer in the right direction would be greatly appreciated.
Matter.Mouse.setOffset
. – BookmarkrequestAnimationFrame
, but I ultimately draw on my own canvas instead of positioning HTML elements. If I have a better idea of what you're going for here I can provide an example that uses a composite stack and an HTML list. – Bookmark