JSFiddle - React, Tailwind, and code Playground
by jcubed111
HTML
<canvas id="main" width=500 height=500></canvas>
JavaScript
const Vec2 = (x, y) => [x, y];
function *getLinePixelsThin([x0, y0], [x1, y1]) {
// get a smooth pixel line connecting start and end
// https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
const dx = Math.abs(x1 - x0);
const sx = x0 < x1 ? 1 : -1;
const dy = -Math.abs(y1 - y0);
const sy = y0 < y1 ? 1 : -1;
let error = dx + dy;
const totalSteps = dx - dy;
let steps = 0;
console.log('start');
while(true) {
const e2 = 2 * error;
const isHalf = steps >= (totalSteps >> 1);
console.log(x0, y0, e2, dy, dx, steps, isHalf);
yield Vec2(x0, y0);
if(x0 == x1 && y0 == y1) break;
if(e2 > dy || (isHalf && e2 == dy)) {
if(x0 == x1) break;
error += dy;
x0 += sx;
steps++;
}
if(e2 < dx || (!isHalf && e2 == dx)) {
if(y0 == y1) break;
error += dx;
y0 += sy;
steps++;
}
}
}
const canvas = document.getElementById('main');
const ctx = canvas.getContext('2d');
ctx.setTransform(20, 0, 0, -20, 0, 500);
ctx.lineWidth = 0.1;
function cb(e, debug=false) {
ctx.clearRect(0, 0, 100, 100);
ctx.strokeStyle = '#ddd';
for(let i = 0; i < 30; i++) {
ctx.strokeRect(i, 0, 1, 30);
ctx.strokeRect(0, i, 30, 1);
}
const {top, left, height} = canvas.getBoundingClientRect();
const mousePos = Vec2(
Math.floor((e.clientX - left) / 20),
Math.floor((height - (e.clientY - top)) / 20),
);
if(debug) debugger;
for(const pos of getLinePixelsThin([12, 12], mousePos)) {
ctx.fillRect(...pos, 1, 1);
}
ctx.strokeStyle = '#f00';
ctx.strokeRect(...mousePos, 1, 1);
}
canvas.addEventListener('mousemove', cb);
canvas.addEventListener('click', e => cb(e, true));