DavidHDev/react-bits · error · Error

Could not get 2d context

Error message

Could not get 2d context

What it means

createTextTexture allocates an offscreen canvas to rasterize a disc title into a GL texture via a 2D context. getContext('2d') returns null only when a 2D context cannot be created (context cap, memory pressure, or non-browser env), so it throws before measureText/fillText can run.

Source

Thrown at src/ts-tailwind/Components/CircularGallery/CircularGallery.tsx:135

    console.error('CircularGallery: unable to load font from', fontUrl, error);
    return font;
  }
}

function getFontSize(font: string): number {
  const match = font.match(/(\d+)px/);
  return match ? parseInt(match[1], 10) : 30;
}

function createTextTexture(
  gl: GL,
  text: string,
  font: string = 'bold 30px monospace',
  color: string = 'black'
): { texture: Texture; width: number; height: number } {
  const canvas = document.createElement('canvas');
  const context = canvas.getContext('2d');
  if (!context) throw new Error('Could not get 2d context');

  context.font = font;
  const metrics = context.measureText(text);
  const textWidth = Math.ceil(metrics.width);
  const fontSize = getFontSize(font);
  const textHeight = Math.ceil(fontSize * 1.2);

  canvas.width = textWidth + 20;
  canvas.height = textHeight + 20;

  context.font = font;
  context.fillStyle = color;
  context.textBaseline = 'middle';
  context.textAlign = 'center';
  context.clearRect(0, 0, canvas.width, canvas.height);
  context.fillText(text, canvas.width / 2, canvas.height / 2);

  const texture = new Texture(gl, { generateMipmaps: false });

View on GitHub (pinned to c7109dccb4)

Solutions

  1. Reduce total live canvas/WebGL contexts on the page; pool and reuse a single offscreen 2D canvas for all labels.
  2. Guard getContext('2d') and return a placeholder/empty texture when unavailable.
  3. Pre-render labels server-side or cache textures instead of allocating per item.
  4. Ensure the code executes in a real browser with canvas 2D support.

Example fix

// before
const context = canvas.getContext('2d');
if (!context) throw new Error('Could not get 2d context');

// after (shared, guarded)
const context = shared2DCanvas.getContext('2d');
if (!context) return { texture: emptyTexture(gl), width: 1, height: 1 };
Defensive patterns

Strategy: validation

Validate before calling

function canGet2D(): boolean {
  try { return !!document.createElement('canvas').getContext('2d'); }
  catch { return false; }
}

Type guard

function get2D(canvas: HTMLCanvasElement): CanvasRenderingContext2D | null {
  return canvas.getContext('2d');
}

Try / catch

const context = canvas.getContext('2d');
if (!context) {
  return { texture: emptyTexture(gl), width: 1, height: 1 };
}

Prevention

When it happens

Trigger: document.createElement('canvas').getContext('2d') returns null at src/ts-tailwind/Components/CircularGallery/CircularGallery.tsx:135 inside createTextTexture, which is called per gallery item to build label textures.

Common situations: A page with many canvases/WebGL contexts hitting the browser context cap; SSR/jsdom where 2D canvas is unavailable; heavy memory pressure; the canvas element was already bound to an incompatible context type; rapid creation of text textures without cleanup.

Related errors


AI-assisted analysis of DavidHDev/react-bits@c7109dccb4 (2026-08-13). Data as JSON: /api/errors/267ac3c6823cd4e0. Report an issue: GitHub.