Skip to content

Instantly share code, notes, and snippets.

@luizbills
Last active July 15, 2025 14:41
Show Gist options
  • Save luizbills/08d378ac497388c55d2beca1a8c7e04e to your computer and use it in GitHub Desktop.
Save luizbills/08d378ac497388c55d2beca1a8c7e04e to your computer and use it in GitHub Desktop.
Tutorial: Pixel Manipulation in Litecanvas

Pixel Manipulation in Litecanvas

Include these two functions

function loadPixels() {
  const imageData = ctx().getImageData(0, 0, W, H);
  const pixels = imageData.data
  pixels.parent = imageData
  return pixels
}

function updatePixels(pixels) {
  ctx().putImageData(pixels.parent, 0, 0);
}

See https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas for more details.

Demo

code based on https://processing.org/examples/mandelbrot.html

litecanvas({
  width: 710,
  height: 400,
  animate: false, // disable loop and draw once
  autoscale: false
})

function draw() {
  cls(0);

  // Establish a range of values on the complex plane
  // A different range will allow us to "zoom" in or out on the fractal

  // It all starts with the width, try higher or lower values
  const w = 4;
  const h = (w * H) / W;

  // Start at negative half the width and height
  const xmin = -w/2;
  const ymin = -h/2;

  // Make sure we can write to the pixels[] array.
  // Only need to do this once since we don't do any other drawing.
  const pixels = loadPixels();

  // Maximum number of iterations for each point on the complex plane
  const maxiterations = 100;

  // x goes from xmin to xmax
  const xmax = xmin + w;
  // y goes from ymin to ymax
  const ymax = ymin + h;

  // Calculate amount we increment x,y for each pixel
  const dx = (xmax - xmin) / (W);
  const dy = (ymax - ymin) / (H);

  // Start y
  let y = ymin;
  for (let j = 0; j < H; j++) {
    // Start x
    let x = xmin;
    for (let i = 0; i < W; i++) {

      // Now we test, as we iterate z = z^2 + cm does z tend towards infinity?
      let a = x;
      let b = y;
      let n = 0;
      while (n < maxiterations) {
        const aa = a * a;
        const bb = b * b;
        const twoab = 2.0 * a * b;
        a = aa - bb + x;
        b = twoab + y;
        // Infinty in our finite world is simple, let's just consider it 16
        if (dist(aa, bb, 0, 0) > 16) {
          break;  // Bail
        }
        n++;
      }

      // We color each pixel based on how long it takes to get to infinity
      // If we never got there, let's pick the color black
      const pix = (i+j*W)*4;
      const norm = map(n, 0, maxiterations, 0, 1);
      let bright = map(sqrt(norm), 0, 1, 0, 255);
      if (n == maxiterations) {
        bright = 0;
      } else {
        // Gosh, we could make fancy colors here if we wanted
        pixels[pix + 0] = bright;
        pixels[pix + 1] = bright;
        pixels[pix + 2] = bright;
        pixels[pix + 3] = 255;
      }
      x += dx;
    }
    y += dy;
  }
  updatePixels(pixels);
}

Live Demo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment