Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Capture the two layers separately, then combine them on a third canvas. Three.js draws pixels into a WebGL <canvas>; an HTML capture library such as html2canvas reconstructs DOM content into another canvas. Render the desired Three.js frame immediately before reading its canvas, capture the HTML region, align both outputs, draw them in stacking order, and export the destination canvas as PNG or another image format.

Choose the capture boundary first

Your implementation depends on what “one screenshot” means:

  • A known in-page region: combine a Three.js canvas and a DOM element in JavaScript. This is suitable for a Save image button inside your application.
  • The exact browser pixels: use a browser-native screenshot API or automation. DOM reconstruction can differ from what the browser displayed.
  • A server-rendered image: run a real browser with Puppeteer or Playwright. This is different from a client-only export.

The code below targets the first case: a positioned HTML layer and a Three.js canvas with the same visual coordinate system.

How the two rendering systems differ

Three.js output is already a canvas

The renderer writes the scene into its canvas. Export that element with toBlob() (or toDataURL() when a data URL is specifically required). For an animated scene, call renderer.render(scene, camera) immediately before reading the canvas; the Three.js manual recommends this pattern in its canvas screenshot guidance.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Philips 24 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 241V8LB
  • CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
  • WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
  • A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents

HTML capture is reconstruction, not a screenshot

html2canvas(element) walks the DOM and computed styles, then paints a representation into a new canvas. It supports only the CSS features it implements, so shadows, filters, blend modes, fonts, pseudo-elements, and complex layout should be checked in the browsers you support. Its FAQ explains why this differs from a native browser screenshot.

Compositing creates the final image

Draw the HTML canvas and the WebGL canvas onto a destination canvas at their intended offsets. This separation follows from the documented outputs of Three.js and html2canvas; your page must supply the correct stacking order, dimensions, and pixel ratio.

Prepare matching dimensions and scale

Use one capture rectangle and make every layer agree on it. The CSS size (for example, 1200×700) is not necessarily the backing-store size (which may be 2400×1400 on a retina display). Three.js documents its renderer sizing and pixel-ratio behavior; the renderer’s canvas contains the scene pixels.

  • Give the wrapper, HTML layer, and WebGL canvas the same CSS width and height.
  • Position layers with the same origin, normally top: 0; left: 0.
  • Choose a pixel ratio deliberately. A consistent ratio avoids blurry or stretched compositing.
  • Do not resize the renderer between rendering and capture; resizing clears its drawing buffer.
  • Decide whether the DOM should be above or below the scene, then use that order when drawing.

Complete in-page implementation

This example captures a wrapper containing a Three.js canvas and an HTML overlay. It assumes renderer has already been created and the scene has been initialized.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Markup and styles

<button id="save-shot">Save combined image</button>
<div id="capture-area">
  <canvas id="three-canvas"></canvas>
  <div id="html-overlay">
    <h1>Product preview</h1>
    <p>This text is part of the exported image.</p>
  </div>
</div>

<style>
#capture-area { position: relative; width: 1200px; height: 700px; }
#three-canvas, #html-overlay { position: absolute; inset: 0; width: 100%; height: 100%; }
#three-canvas { z-index: 0; display: block; }
#html-overlay { z-index: 1; pointer-events: none; }
</style>

Load html2canvas using your package manager or the version you have approved for your application. The function below uses the global html2canvas symbol for clarity.

Rank #2
Philips 22 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 221V8LB
  • CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
  • SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors

Capture and composite

async function captureCombined({ renderer, scene, camera }) {
  const area = document.querySelector('#capture-area');
  const webglCanvas = renderer.domElement;
  const rect = area.getBoundingClientRect();
  const cssWidth = Math.round(rect.width);
  const cssHeight = Math.round(rect.height);
  const ratio = window.devicePixelRatio || 1;

  // Ensure the renderer has the intended backing dimensions.
  renderer.setPixelRatio(ratio);
  renderer.setSize(cssWidth, cssHeight, false);

  // For an animated scene, render the exact frame to be exported now.
  renderer.render(scene, camera);

  const htmlCanvas = await html2canvas(area, {
    backgroundColor: null,
    scale: ratio,
    useCORS: true
  });

  const output = document.createElement('canvas');
  output.width = Math.round(cssWidth * ratio);
  output.height = Math.round(cssHeight * ratio);
  const ctx = output.getContext('2d');

  // Draw in visual stacking order: scene first, HTML overlay second.
  ctx.drawImage(webglCanvas, 0, 0, output.width, output.height);
  ctx.drawImage(htmlCanvas, 0, 0, output.width, output.height);

  return new Promise((resolve, reject) => {
    output.toBlob(blob => {
      if (!blob) return reject(new Error('The browser could not encode the image'));
      resolve(blob);
    }, 'image/png');
  });
}

document.querySelector('#save-shot').addEventListener('click', async () => {
  try {
    const blob = await captureCombined({ renderer, scene, camera });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = 'three-html.png';
    link.click();
    URL.revokeObjectURL(url);
  } catch (error) {
    console.error('Combined capture failed:', error);
  }
});

If the DOM overlay is intended to sit behind the scene, reverse the two drawImage calls. If you capture only a child element rather than the whole wrapper, composite both sources into that child’s coordinate system and account for its offset within the renderer canvas.

Export formats and transparent backgrounds

PNG preserves transparency and is the safest default for UI overlays. Use image/jpeg with a quality value when a smaller, opaque file is more important:

output.toBlob(blob => {
  // upload or download blob
}, 'image/jpeg', 0.9);

WebP is also available in browsers that support it. A JPEG destination fills transparent pixels with the canvas background, so set a deliberate background before drawing if transparency is not wanted.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The WebGL drawing-buffer trap

WebGL commonly clears its drawing buffer after compositing. Three.js documents preserveDrawingBuffer as false by default, and the WebGL specification warns that preserving the buffer “can cause significant performance loss on some platforms.” The reliable first choice is synchronous capture: render and read the canvas in the same function, as the example does.

Only use a persistent buffer when your design requires reading the canvas later. Create the renderer with the option enabled and test on target hardware:

Rank #3
Sale
Dell 24 Monitor - SE2426H - 23.8-inch FHD (1920x1080) 144Hz 1ms Display, in-Plane Switching (IPS) Technology, AMD FreeSync™, TÜV 3-Star 2X HDMI, Tilt
  • Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
  • Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
  • Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
  • In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
  • Ultra-thin bezels: Maximize your viewing experience with thin bezels.
const renderer = new THREE.WebGLRenderer({
  antialias: true,
  preserveDrawingBuffer: true
});

Keeping the buffer can reduce performance and does not prevent a clear caused by resizing. It also does not fix an incorrectly sized or misaligned composite.

Cross-origin content and iframe limits

  • Images and textures: an image loaded from another origin can taint a canvas. Configure the asset server for CORS and set the image’s crossOrigin property before assigning its URL. Browser security rules cannot be bypassed by html2canvas.
  • Cross-origin iframes: html2canvas cannot inspect a frame’s content document. Same-origin frames can be handled recursively; otherwise capture the frame separately where you have permission.
  • Web fonts: wait for document.fonts.ready before capture so fallback fonts do not get painted.
  • Late-loading content: await images, data requests, and layout updates before calling the function. A capture records the state at that instant.

Animation, interaction, and layout timing

Pause your animation loop or use a deterministic frame state while exporting. Calling render immediately before capture ensures the desired frame, but it does not stop another requestAnimationFrame callback from changing the scene afterward. For a stable export, set a flag that skips animation updates during the operation, render once, capture, then resume.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Hide transient controls with a CSS class before invoking html2canvas, force a layout read such as area.getBoundingClientRect(), and remove the class after the blob is created. Ensure tooltips, menus, and focus outlines are intentionally included or excluded; html2canvas paints the DOM state it receives.

When a real browser screenshot is the better method

Path Best fit Main trade-off
Three.js export + html2canvas + compositing Client-side Save button for a known region DOM reconstruction can differ from browser pixels; CSS and cross-origin restrictions apply.
Browser-native screenshot API Extension capturing the displayed viewport Availability and capture scope depend on the browser and extension context.
Puppeteer or Playwright Server-side screenshots of a real page Requires a browser automation runtime and server workflow.

The html2canvas FAQ specifically identifies native extension screenshot APIs as more reliable for extension use and names Puppeteer and Playwright for server-side screenshots. Choose those paths when exact browser pixels, cross-origin frames, or full-page capture matter more than a client-only export.

Common failures and fixes

The Three.js portion is blank or shows an old frame

Render immediately before reading renderer.domElement. Check that the camera sees the scene and that no resize occurs between rendering and compositing. If delayed reading is unavoidable, test preserveDrawingBuffer: true and measure the performance cost.

Rank #4
Sale
Samsung 27" Essential S3 (S36GD) Series FHD 1800R Curved Computer Monitor
  • CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
  • SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
  • MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
  • KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
  • INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient

The HTML looks different from the page

That is a limitation of DOM reconstruction, not necessarily a bug in your compositor. Check unsupported CSS, loaded fonts, pseudo-elements, filters, and animations. For pixel accuracy, switch to a browser screenshot workflow.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

toDataURL or toBlob throws a security error

A cross-origin image, texture, or canvas has probably tainted the drawing surface. Serve assets with suitable CORS headers, set crossOrigin before loading, or remove the offending asset. You cannot read pixels from an origin that has not granted access.

The two layers are shifted or stretched

Compare CSS dimensions with backing dimensions. Use one measured wrapper rectangle, one pixel ratio, and identical origins. Do not assume canvas.width equals its CSS width on a high-density display.

An iframe or embedded widget is missing

html2canvas cannot read a cross-origin frame. Capture it in its own permitted context or use a real browser screenshot of the complete page.

The export captures a popup or loading spinner

Set an “exporting” class, hide transient selectors, wait for network-driven content and fonts, then capture. Restore the UI in a finally block so a failed export does not leave the page altered.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Sale
Sceptre New 22-Inch Gaming Monitor, FHD 1080p, Up to 144Hz, HDMI, DisplayPort, Built-in Speakers, Machine Black (E225W-FW144 Series, 2026)
  • 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
  • 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
  • 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

For a server or automation workflow, ScreenshotNeo accepts one GET request and returns a PNG, JPEG, WebP, or PDF. It handles the complete browser page rather than asking you to reconstruct DOM and WebGL layers yourself. Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing result.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
const buffer = Buffer.from(await res.arrayBuffer());
require('fs').writeFileSync('shot.webp', buffer);

See the ScreenshotNeo documentation for request options. It includes full-page capture with lazy images, CSS-selector element capture, custom CSS and JavaScript, clicks, waits, blocking rules, headers, cookies, user agents, authorization, timezone and geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed links, asynchronous jobs, webhooks, bulk capture, usage data, and PDF output. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.

The Free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try the one-call workflow.

Performance and reliability checklist

  • Render once for the export instead of capturing every animation frame.
  • Use the smallest capture boundary that meets the requirement.
  • Keep pixel ratio proportional to the output needed; very large backing canvases consume substantial memory.
  • Release object URLs after downloads and avoid retaining large blobs.
  • Validate on a low-density and a high-density display, plus every browser you support.
  • Log whether failure occurred during DOM capture, WebGL readback, compositing, or image encoding.
  • For server jobs, wait for fonts and network content and use a browser workflow when exact pixels are required.

FAQ

Can html2canvas capture a WebGL canvas by itself?

It may copy the canvas element’s available pixels, but you should explicitly export and composite the Three.js canvas so rendering timing, dimensions, and stacking are under your control.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I always enable preserveDrawingBuffer?

No. It is false by default for a reason. Capture immediately after rendering first; enable preservation only when delayed readback is a real requirement and performance testing is acceptable.

Will this produce a full-page screenshot?

Only if your capture boundary and layout represent the full page. For browser-accurate full-page output, use browser automation or a screenshot service.

Can I capture a cross-origin iframe from client JavaScript?

Not with html2canvas, because browser same-origin policy prevents inspecting the frame’s document.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.