JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://rawgit.com/ReddogStone/behavior.js/master/behavior.js"></script>
<body>
<canvas id="screen" width="600" height="400"></canvas>
</body>
JavaScript
'use strict';
function getMousePos(canvas, event) {
let rect = canvas.getBoundingClientRect();
return { x: event.clientX - rect.left, y: event.clientY - rect.top };
}
function renderFrame(context, rects) {
rects.forEach(function(rect) {
context.fillStyle = rect.color;
context.fillRect(rect.x, rect.y, rect.sx, rect.sy);
});
}
function waitForGrab(rect) {
return Behavior.run(function*() {
while (true) {
let event = yield Behavior.type('mousedown');
let pos = event.pos;
let dx = pos.x - rect.x;
let dy = pos.y - rect.y;
if ((dx >= 0) && (dy >= 0) && (dx <= rect.sx) && (dy <= rect.sy)) {
return { x: dx, y: dy };
}
}
});
}
function grabOne(rects) {
return Behavior.first(rects.map(rect => Behavior.run(function*() {
let offset = yield waitForGrab(rect);
return {
offset: offset,
rect: rect
}
})));
}
function putOnTop(rect, rects) {
rects.push(rects.splice(rects.indexOf(rect), 1)[0]);
}
function moveDragged(rect, grabOffset, newPos) {
rect.x = newPos.x - grabOffset.x;
rect.y = newPos.y - grabOffset.y;
}
let canvas = document.getElementById('screen');
let context = canvas.getContext('2d');
let rects = [
{ x: 50, y: 100, sx: 100, sy: 50, color: 'red' },
{ x: 500, y: 100, sx: 100, sy: 50, color: 'blue' }
];
var behavior = Behavior.run(function*() {
while (true) {
let grab = yield grabOne(rects);
putOnTop(grab.rect, rects);
yield Behavior.first(
Behavior.type('mouseup'),
Behavior.repeat(() => Behavior.run(function*() {
let event = yield Behavior.type('mousemove');
moveDragged(grab.rect, grab.offset, event.pos);
}))
);
}
});
function handleMouseEvent(event) {
let pos = getMousePos(canvas, event);
behavior({ type: event.type, pos: pos });
}
canvas.addEventListener('mousedown', handleMouseEvent, true);
canvas.addEventListener('mousemove', handleMouseEvent, true);
document.addEventListener('mouseup',...