canvas-sketch cheatsheet

Ming Sun

Ming Sun / May 06, 2023

8 min read––– views

Example 1: static

const canvasSketch = require("canvas-sketch");

const settings = {
  // Output resolution, we can use 300PPI for print
  pixelsPerInch: 600,
  // Standard business card size
  dimensions: [3.5, 2],
  // all our dimensions and rendering units will use inches
  units: "in",
};

const sketch = ({ context }) => {
  console.log(context);
  // Utility to draw a circle with or without a fill
  const circle = (x, y, radius, fill = false) => {
    context.beginPath();
    context.arc(x, y, radius, 0, Math.PI * 2, false);
    if (fill) context.fill();
    context.stroke();
  };

  return ({ context, width, height, frame }) => {
    // Fill page with solid color
    // The 'width' and 'height' will be in inches here
    context.fillStyle = "#a00";
    context.fillRect(0, 0, width, height);

    context.strokeStyle = "#fff";
    context.fillStyle = "#fff";
    context.lineWidth = 0.01;
    for (let i = 0; i < 5; i++) {
      const x = (i / 4) * width;
      const y = height / 2;
      const radius = i % 2 === 0 ? 0.5 : 0.25;
      const fill = i % 4 === 0;
      circle(x, y, radius, fill);
    }
  };
};

canvasSketch(sketch, settings);
eg1

Example 2: animation

const canvasSketch = require("canvas-sketch");
const {
  fract,
  lerp,
  clamp,
  mapRange,
  clamp01,
  sign,
} = require("canvas-sketch-util/math");

const settings = {
  // Enable an animation loop
  animate: true,
  // Set loop duration to 3 seconds
  duration: 30,
  // Use a small size for our GIF output
  dimensions: [1920, 1080],
  // Optionally specify an export frame rate, defaults to 30
  fps: 36,
};

function drawLine(context, x1, y1, x2, y2) {
  context.beginPath();
  context.lineTo(x1, y1);
  context.lineTo(x2, y2);
  context.closePath();
  context.stroke();
}

// Start the sketch
const sketch = ({ width, height }) => {
  const render = ({ context, width, height, playhead }) => {
    context.fillStyle = "#000";
    context.fillRect(0, 0, width, height);

    context.translate(width / 10 - 30, height / 2);

    context.strokeStyle = "#fff";
    context.lineCap = "round";
    context.lineWidth = 3;
    let xwidth = (width / 10) * 8;
    let yheight = (height / 5) * 1.5;
    drawLine(context, 0, 0, xwidth + 60, 0);
    drawLine(context, 0, yheight, 0, -yheight);

    let N = 10000;
    let cycles = 3;
    let step = xwidth / N;
    context.lineWidth = 10;
    context.strokeStyle = "cyan";
    let amplitude = yheight * 0.8;
    context.beginPath();
    for (let i = 0; i < N * playhead; i++) {
      let x = i * step;
      let y = -amplitude * Math.sin((i / N) * 2 * Math.PI * cycles);
      context.lineTo(x, y);
    }
    context.stroke();

    let x = xwidth * playhead;
    let y = -amplitude * Math.sin(playhead * 2 * Math.PI * cycles);
    context.fillStyle = "red";
    context.beginPath();
    context.arc(x, y, 20, 0, 2 * Math.PI);
    context.closePath();
    context.fill();

    context.fillStyle = "#fff";
    context.font = "40px Arial";
    context.fillText("y=sin(x) animation", xwidth / 2 - 150, -height / 2 + 100);

    context.strokeStyle = "#fff";
    context.lineWidth = 2;
    context.setLineDash([2, 5]);
    drawLine(context, 0, y, x, y);
    drawLine(context, x, yheight - 20, x, y);

    context.textAlign = "center";
    context.fillText("0", -20, 40);
    context.fillText(
      Math.round(Math.sin(playhead * 2 * Math.PI * cycles) * 100) / 100,
      -60,
      y + 10
    );
    context.fillText(
      Math.round(playhead * 2 * Math.PI * cycles * 100) / 100,
      x,
      yheight + 20
    );

    context.textAlign = "center";
    context.fillText("π", xwidth / 6, 40);
    context.fillText("2π", xwidth / 3, 40);
    context.fillText("3π", xwidth / 2, 40);
    context.fillText("4π", (xwidth / 6) * 4, 40);
    context.fillText("5π", (xwidth / 6) * 5, 40);
    context.fillText("6π", xwidth, 40);

    context.restore();
  };
  return render;
};

canvasSketch(sketch, settings);
eg2

References and materials

[1] canvas-sketch repo


HomeWikis
SnippetsAbout
Google ScholarLinkedIn