JSFiddle - React, Tailwind, and code Playground
by Yaroslav Samardak
HTML
<canvas id="canvas">
CSS
body {
padding: 0;
margin: 0;
overflow: hidden;
}
canvas {
width: 100dvw;
height: 100dvh;
background: black;
margin: 0;
}
JavaScript
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
const dpr = window.devicePixelRatio || 1
let cr = canvas.getBoundingClientRect()
let w = 0;
let h = 0;
let s = 1;
let mx = 0;
let my = 0;
function renderCursor() {
const radius = 32 * s;
ctx.save()
ctx.beginPath()
ctx.arc(mx, my, radius, 0, 2 * Math.PI)
let x = Math.round(Date.now() / 10) % 512
if (x > 256) x = 256 - (x - 256)
ctx.strokeStyle = `rgba(${ x }, ${ 256 - x }, ${ 256 }, 1)`
// ctx.strokeStyle = `rgba(${ x }, ${ 256 - x }, ${ (255 - x + 384) % 256 }, 1)`
ctx.lineWidth = 5 * s
ctx.stroke()
ctx.restore()
}
canvas.addEventListener('mousemove', (event) => {
const mouseX_css = event.clientX - cr.left
const mouseY_css = event.clientY - cr.top
// Scale by the ratio of canvas internal width to CSS width, and then by DPR
mx = Math.floor(mouseX_css * (canvas.width / cr.width) * s)
my = Math.floor(mouseY_css * (canvas.height / cr.height) * s)
// If ctx.scale(dpr, dpr) was used, further divide by dpr
// mx = Math.floor((mouseX_css * (canvas.width / rect.width)) / dpr)
// my = Math.floor((mouseY_css * (canvas.height / rect.height)) / dpr)
})
function resizeCanvas() {
cr = canvas.getBoundingClientRect()
w = window.innerWidth * dpr
h = window.innerHeight * dpr
canvas.width = w
canvas.height = h
}
window.addEventListener('resize', resizeCanvas, false)
function render() {
ctx.clearRect(0, 0, w, h);
renderCursor();
window.requestAnimationFrame(render);
}
resizeCanvas()
render()