JSFiddle - React, Tailwind, and code Playground
by João Vitor Scheuermann
HTML
<canvas id="canvas"></canvas>
CSS
* {
margin: 0;
padding: 0;
}
document, body {
width: 100%;
height: 100%;
}
canvas {
/* background: red; */
}
JavaScript
const canvas = document.querySelector('#canvas')
const context = canvas.getContext('2d')
const createEventRepresentation = (type, data) => { return {type, data} }
class Vector {
constructor (x, y) {
this.x = x
this.y = y
}
}
const events = []
canvas.addEventListener('mousemove', ({ x, y }) => events.push(createEventRepresentation('mousemove', { position: new Vector(x, y) })))
canvas.addEventListener('mousedown', ({ x, y, button }) => events.push(createEventRepresentation('mousedown', { position: new Vector(x, y), button })))
canvas.addEventListener('mouseup', ({ x, y, button }) => events.push(createEventRepresentation('mouseup', { position: new Vector(x, y), button })))
function drawPoint (x, y, radius, color) {
context.save()
context.beginPath()
context.arc(x, y, radius, 0, 2 * Math.PI)
context.fillStyle = color
context.fill()
context.restore()
}
function drawPoints (points = [], radius = 1, color="#000000") {
for (let {x, y} of points) drawPoint(x, y, radius, color)
}
function drawPath (points = []) {
let firstPoint = points.shift()
if (firstPoint) {
context.beginPath()
context.moveTo(firstPoint.x, firstPoint.y)
for (let {x, y} of points) context.lineTo(x, y)
context.strokeStyle = '#ff0000'
context.stroke()
}
}
function render () {
let renderEvents = events.slice(-100)
let mousemove = renderEvents.filter(event => event.type === 'mousemove')
let mousedown = renderEvents.filter(event => event.type === 'mousedown')
let mouseup = renderEvents.filter(event => event.type === 'mouseup')
drawPath(mousemove.map(event => event.data.position))
drawPoints(mousedown.map(event => event.data.position), 2, '#00ff00')
drawPoints(mouseup.map(event => event.data.position), 2, '#0000ff')
}
// UPDATE LOOP
let last = 0
function update (ts = 0) {
// UPDATE THE CANVAS SIZE
canvas.width = window.innerWidth
canvas.height = window.innerHeight
// CLEAR THE CANVAS FOR THE NEXT...