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...