Frontend Development 5 min read

How Konva.js Uses Random Colors for Precise Canvas Hit Detection

Konva.js detects whether a point lies inside a shape by assigning each shape a unique random color key, rendering a hidden hitCanvas with these colors, and then reading the pixel color at the click position to identify the corresponding shape, supporting up to 16.7 million objects.

KooFE Frontend Team
KooFE Frontend Team
KooFE Frontend Team
How Konva.js Uses Random Colors for Precise Canvas Hit Detection

This article is the third in a series on Canvas point‑in‑shape detection. The first two introduced geometric detection with Fabric.js and opacity‑based detection with Create.js. This piece focuses on using random colors for detection with Konva.js.

Konva.js generates a unique random color value (colorKey) for every shape on the canvas. During rendering, besides the visible sceneCanvas , an off‑screen hitCanvas is created where each shape is drawn with its colorKey instead of its visual fill. When the user clicks, the color of the pixel at the click location on the hitCanvas is read; this colorKey maps back to the original shape, allowing precise hit detection.

The hitCanvas uses the same size and position attributes as the sceneCanvas, but with the special colorKey fills. Because a 24‑bit hex color provides 16,777,216 possible values, Konva.js can theoretically support that many distinct shapes for hit testing, which is sufficient for most applications.

Konva.js generates random color keys with the following constructor code:

<code>constructor(config) {
  super(config);
  // set colorKey
  let key;
  while (true) {
    // generate random color
    key = Util.getRandomColor();
    if (key && !(key in shapes)) {
      break;
    }
  }
  this.colorKey = key;

  // window.Konva.shapes
  shapes[key] = this;
}</code>

And determines whether a point lies inside a shape using:

<code>_getIntersection(pos) {
  const ratio = this.hitCanvas.pixelRatio;
  const p = this.hitCanvas.context.getImageData(Math.round(pos.x * ratio), Math.round(pos.y * ratio), 1, 1).data;
  const p3 = p[3];
  // fully opaque pixel
  if (p3 === 255) {
    const colorKey = Util._rgbToHex(p[0], p[1], p[2]);
    const shape = shapes[HASH + colorKey];
    // found corresponding shape
    if (shape) {
      return { shape: shape };
    }
    return { antialiased: true };
  } else if (p3 > 0) {
    // antialiased pixel
    return { antialiased: true };
  }
  // empty pixel
  return {};
}</code>

When multiple shapes overlap, this method only returns the topmost shape. For cases where all intersecting shapes are needed, Konva.js provides

getAllIntersections(pos)

, which works similarly to Create.js by rendering each shape to a temporary canvas and checking opacity, though it can impact performance.

getAllIntersections(pos): get all shapes that intersect a point. Note: because this method must clear a temporary canvas and redraw every shape inside the container, it should only be used for special situations because it performs very poorly. Please use the Konva.Stage#getIntersection method if at all possible because it performs much better.
JavaScriptcanvasKonva.jshit detectionrandom color
KooFE Frontend Team
Written by

KooFE Frontend Team

Follow the latest frontend updates

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.