JSFiddle - React, Tailwind, and code Playground
by brigand
HTML
<main>
<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloribus aspernatur reprehenderit illo, ducimus, quae expedita quas adipisci, laboriosam culpa quos reiciendis similique minima quia tempora corrupti in esse repudiandae cum.</div>
<div>Maxime laboriosam facere rerum eaque, eos debitis eveniet saepe commodi atque explicabo tempora ad voluptate nisi, soluta deleniti modi neque delectus, sunt vel cupiditate. Optio voluptas autem deleniti sed quasi.</div>
<div>Nostrum eum consequuntur sint accusamus alias, quibusdam deleniti, dicta unde et eligendi officiis minus fugiat, commodi maiores, iure iste quo? Sequi, aspernatur, vitae illo qui nesciunt id explicabo voluptatum. Commodi!</div>
<div>Nostrum assumenda voluptas vero mollitia. Iure deleniti distinctio nesciunt cum expedita harum est molestias commodi, repudiandae aspernatur ut incidunt ipsum voluptatibus, maiores eaque nihil deserunt totam esse quam sed facere!</div>
<div>Fugit vel quo impedit iusto sint quisquam esse eum excepturi tempore provident maxime accusantium maiores consequatur accusamus, praesentium. Sapiente, aspernatur amet voluptatum officia reiciendis optio quibusdam accusantium facere ad reprehenderit!</div>
<div>Molestias laudantium labore ipsum dolorem aperiam vitae rerum? Quas enim aliquam quaerat ad corporis ducimus deserunt id expedita, neque dicta itaque distinctio ex, labore! Esse architecto ipsum error vel magni?</div>
<div>Suscipit sapiente explicabo impedit molestias, aut, voluptate dolorem, sequi quos provident minus nemo soluta quae cumque maxime! Reiciendis cumque accusamus quos praesentium quisquam, doloremque, blanditiis libero omnis. Sed, blanditiis, unde.</div>
<div>Recusandae nisi repellendus obcaecati eaque architecto velit officiis deserunt ea vitae. Inventore reprehenderit magni mollitia corporis, blanditiis nostrum sunt, officia, doloribus ratione fugit iste doloremque odio fuga saepe consectetur repellendus!</div>
<div>Quisquam deserunt...
CSS
html,
body {
margin: 0;
padding: 0;
}
#overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: none;
}
.drag::after {
content: '';
display: block;
position: absolute;
top: -100em;
right: -100em;
bottom: -100em;
left: -100em;
}
JavaScript
const canvas = document.querySelector('#overlay');
canvas.width = Math.round(window.innerWidth * window.devicePixelRatio * 2);
canvas.height = Math.round(window.innerHeight * window.devicePixelRatio * 2);
const ctx = canvas.getContext('2d');
class HitTarget {
constructor(opts, drawImpl) {
this.drawImpl = drawImpl;
this.x = 0;
this.y = 0;
this.width = 100;
this.height = 100;
this.events = {};
this.canvas = canvas;
this.ctx = ctx;
Object.assign(this, opts);
if (!this.el) {
this.el = document.createElement('div');
this.el.style.position = 'absolute';
}
}
draw() {
this.el.style.top = `${this.y}px`
this.el.style.left = `${this.x}px`
this.el.style.width = `${this.width}px`
this.el.style.height = `${this.height}px`
this.drawImpl(this);
}
init() {
document.body.appendChild(this.el);
for (const event of Object.keys(this.events)) {
this.el.addEventListener(event, (ev) => {
this.events[event](ev, this);
})
}
}
update() {
}
}
const targets = [];
targets.push(new HitTarget({
x: 10,
y: 10,
width: 200,
height: 50,
events: {
mousedown: (ev, ht) => {
ht.el.classList.toggle('drag', true)
ht.drag = {
x: ht.x,
y: ht.y,
startX: ev.pageX,
startY: ev.pageY,
}
},
mouseup: (ev, ht) => {
ht.el.classList.toggle('drag', false)
ht.drag = null
},
mousemove: (ev, ht) => {
if (ht.drag) {
ht.x = ht.drag.x + ev.pageX - ht.drag.startX
ht.y = ht.drag.y + ev.pageY - ht.drag.startY
}
},
}
}, (ht) => {
ht.ctx.fillStyle = 'red';
ht.ctx.fillRect(ht.x, ht.y , ht.width, ht.height)
}))
targets.forEach(target => target.init())
function run() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
targets.forEach(target => target.draw())
requestAnimationFrame(run)
}
run();