Capítulo 849 de 859

Chapter 849: Tips (Manual)

Core Idea

A grab-bag of small, common gotchas: taking a screenshot needs to capture right after a render (browsers clear the WebGL drawing buffer by default), keyboard input needs an explicit tabindex, and making a transparent canvas or a page background needs a few specific renderer options.

Key Concepts

  • Screenshots and the cleared drawing buffer: canvas.toDataURL()/canvas.toBlob() often capture a black image because the browser clears the WebGL drawing buffer after each render for performance/compatibility reasons — call your capture code immediately after a fresh render, not on some later timer.
  • preserveDrawingBuffer: true: prevents the browser from auto-clearing the canvas between frames (useful for drawing/painting-style apps), but the canvas still clears whenever its resolution changes (e.g. on window resize) — for a real persistent-drawing app, render to a render target instead.
  • Keyboard events need tabindex: a canvas doesn't receive keyboard events by default; setting tabindex="0" (or higher) on it enables focus and keyboard input, but then also needs outline: none in CSS to avoid an unwanted focus ring.
  • Transparent canvas: pass alpha: true to the WebGLRenderer constructor, and typically set premultipliedAlpha: false to match how materials output alpha by default (the canvas itself defaults to premultipliedAlpha: true, which is a mismatch worth understanding before relying on canvas transparency).
  • Three.js as a page background: either an inline canvas with z-index: -1 behind normal page content (simplest, but your JS must coexist with the rest of the page's scripts), or an iframe styled to fill and sit behind the page (isolates the three.js code entirely from the host page's JavaScript).

Code Examples

function render() {
  // ...resize + draw...
  renderer.render(scene, camera);
}

function animate(time) {
  render();
  requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

// capture immediately after a render, not on a delayed timer:
render();
canvas.toBlob((blob) => saveBlob(blob, "screenshot.png"));
  • What it demonstrates: separating the render call from the animation loop so a screenshot can be captured immediately after a fresh render.

Key Takeaways

  1. Call your render function immediately before capturing a screenshot — the WebGL drawing buffer is cleared by default right after each render.
  2. preserveDrawingBuffer: true stops auto-clearing between frames but still clears on canvas resize; use a render target instead for a real persistent-drawing feature.
  3. Give a canvas tabindex to receive keyboard events, and pair it with outline: none in CSS to avoid an unwanted focus ring.
  4. For a transparent canvas, set both alpha: true and (usually) premultipliedAlpha: false on the WebGLRenderer.
  5. An inline background canvas (z-index: -1) is simplest; an iframe fully isolates the three.js code's JavaScript from the rest of the page.

Connects To

  • WebGLRenderer: owns the alpha/premultipliedAlpha/preserveDrawingBuffer constructor options covered here.