JSFiddle - React, Tailwind, and code Playground
by Josh Pullen
CSS
canvas {
/* border: 1px solid black; */
max-width: calc(100vw - 20px);
max-height: calc(100vh - 20px);
}
JavaScript
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
function drawGrid() {
ctx.beginPath();
for (let x = -3; x <= 3; x++) {
ctx.moveTo(x, -100);
ctx.lineTo(x, 100);
}
for (let y = -3; y <= 3; y++) {
ctx.moveTo(-100, y);
ctx.lineTo(100, y);
}
ctx.strokeStyle = "#ddd";
ctx.lineWidth = 0.02;
ctx.stroke();
}
function drawFunction(f) {
ctx.beginPath();
ctx.moveTo(-4, f(-4));
for (let x = -4; x <= 4; x += 0.05) {
ctx.lineTo(x, f(x));
}
ctx.strokeStyle = "black";
ctx.lineWidth = 0.05;
ctx.stroke();
}
const getMathCoords = (canvasX, canvasY) => {
return [
(canvasX - canvas.width / 2) / 100,
(canvasY - canvas.height / 2) / 100
];
}
function drawHeatmap(f) {
const imgData = ctx.createImageData(canvas.width, canvas.height);
for (let x = 0; x < imgData.width; x++) {
for (let y = 0; y < imgData.height; y++) {
const [mx, my] = getMathCoords(x, y);
const [r = 0, g = 0, b = 0, a = 1] = f(mx, my);
imgData.data[(x + y * imgData.width) * 4 + 0] = r * 255;
imgData.data[(x + y * imgData.width) * 4 + 1] = g * 255;
imgData.data[(x + y * imgData.width) * 4 + 2] = b * 255;
imgData.data[(x + y * imgData.width) * 4 + 3] = a * 255;
}
}
ctx.putImageData(imgData, 0, 0);
}
function render() {
drawGrid();
// Moving point
/* ctx.beginPath();
ctx.arc(0, 0, 1, 0, 2 * Math.PI)
ctx.fill(); */
// Heatmap
drawHeatmap((x, y) => [x, y, 0]);
// Function
drawFunction(x => Math.sin(x));
drawFunction(x => Math.sin(x + 1));
drawFunction(x => Math.sin(x + 2));
drawFunction(x => Math.sin(x + 3));
drawFunction(x => Math.sin(x + 4));
drawFunction(x => Math.sin(x + 5));
}
/*
Common patterns:
- Start with one of something, then manually create many of them, then automatically create many
*/
canvas.width = 640;
canvas.height = 480;
document.body.appendChild(canvas);
ctx.clearRect(0, 0, canvas.width,...