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();
}

function drawHeatmap(f) {
	const imgData = ctx.createImageData(canvas.width, canvas.height);
  for (let x = 0; x < canvas.width; x++) {
    for (let y = 0; y < canvas.height; y++) {
      const value = f(x, y);
      imgData.data[(x + y * canvas.height) * 4 + 0] = value;
      imgData.data[(x + y * canvas.height) * 4 + 1] = value;
      imgData.data[(x + y * canvas.height) * 4 + 2] = value;
      imgData.data[(x + y * canvas.height) * 4 + 3] = value;
    }
  }
  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) => 120);
  
  // 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, canvas.height);
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.scale(100, -100);
render(canvas, ctx);