85453da49f
regression / regression-shards (style-16-prod style-9-prod style-17-prod iframe-render-compat variables-prod mp4-h265-sdr, shard-4) (push) Has been cancelled
regression / regression-shards (style-4-prod style-11-prod style-2-prod animejs-adapter typegpu-adapter parallel-capture-regression, shard-5) (push) Has been cancelled
regression / regression-shards (style-7-prod style-8-prod style-10-prod css-spinner-render-compat webm-transparency mp4-h264-sdr webm-vp9, shard-3) (push) Has been cancelled
regression / regression-shards (sub-composition-video style-18-prod raf-ball-render-compat font-variant-numeric sub-comp-t0 sub-comp-id-selector, shard-7) (push) Has been cancelled
Windows render verification / Detect changes (push) Has been cancelled
Windows render verification / Preflight (lint + format) (push) Has been cancelled
Windows render verification / Render on windows-latest (push) Has been cancelled
Windows render verification / Tests on windows-latest (push) Has been cancelled
CI / Detect changes (push) Has been cancelled
CI / Build (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Fallow audit (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Producer: integration tests (push) Has been cancelled
CI / Producer: unit tests (push) Has been cancelled
CI / File size check (push) Has been cancelled
CI / Test: skills (push) Has been cancelled
CI / Skills: manifest in sync (push) Has been cancelled
CI / CLI: npx shim (macos-latest) (push) Has been cancelled
CI / CLI: npx shim (ubuntu-latest) (push) Has been cancelled
CI / CLI: npx shim (windows-latest) (push) Has been cancelled
CI / SDK: unit + contract + smoke (push) Has been cancelled
CI / Test: runtime contract (push) Has been cancelled
CI / Studio: load smoke (push) Has been cancelled
CI / Smoke: global install (push) Has been cancelled
CI / CLI smoke (required) (push) Has been cancelled
CI / Semantic PR title (push) Has been cancelled
Player perf / Detect changes (push) Has been cancelled
Player perf / Preflight (lint + format) (push) Has been cancelled
Player perf / player-perf (push) Has been cancelled
Player perf / Perf: drift (push) Has been cancelled
Player perf / Perf: fps (push) Has been cancelled
Player perf / Perf: parity (push) Has been cancelled
Player perf / Perf: scrub (push) Has been cancelled
Player perf / Perf: load (push) Has been cancelled
preview-regression / Detect changes (push) Has been cancelled
preview-regression / Preflight (lint + format) (push) Has been cancelled
preview-regression / Preview parity (push) Has been cancelled
preview-regression / preview-regression (push) Has been cancelled
regression / regression (push) Has been cancelled
regression / Detect changes (push) Has been cancelled
regression / Preflight (lint + format) (push) Has been cancelled
regression / regression-shards (hdr-regression style-5-prod style-3-prod mov-prores, shard-1) (push) Has been cancelled
regression / regression-shards (overlay-montage-prod style-12-prod chat missing-host-comp-id png-sequence portrait-edge-bleed, shard-6) (push) Has been cancelled
regression / regression-shards (style-13-prod style-6-prod vignelli-stacking gsap-letters-render-compat audio-mux-parity, shard-8) (push) Has been cancelled
regression / regression-shards (style-15-prod hdr-hlg-regression style-1-prod many-cuts vfr-screen-recording render-symlinked-assets, shard-2) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Docs / Validate docs (push) Has been cancelled
Sync skills to ClawHub / Publish changed skills (push) Has been cancelled
131 lines
5.5 KiB
Plaintext
131 lines
5.5 KiB
Plaintext
---
|
|
title: "HTML-in-Canvas"
|
|
description: "Render live HTML as WebGL textures — GPU shaders, 3D geometry, and cinematic effects on any DOM content."
|
|
---
|
|
|
|
# HTML-in-Canvas
|
|
|
|
The HTML-in-Canvas API (`drawElementImage`) lets you capture live, rendered DOM elements directly into a canvas at GPU speed. This means you can take any HTML — dashboards, forms, landing pages, app UIs — and render them as textures in WebGL scenes with shaders, 3D transformations, and post-processing effects.
|
|
|
|
<Warning>
|
|
**Chrome flag required.** The `drawElementImage` API is experimental and must be enabled manually:
|
|
|
|
1. Open `chrome://flags/#canvas-draw-element` in Chrome or Brave
|
|
2. Set **CanvasDrawElement** to **Enabled**
|
|
3. Restart the browser
|
|
|
|
HyperFrames enables this flag automatically during rendering (`--enable-features=CanvasDrawElement`), so rendered videos work without manual setup. The flag is only needed for live preview in the Studio.
|
|
</Warning>
|
|
|
|
## How it works
|
|
|
|
1. Place HTML content inside a `<canvas layoutsubtree>` element
|
|
2. The browser renders the HTML children as normal DOM
|
|
3. Call `ctx.drawElementImage(element, x, y, w, h)` to capture the rendered pixels into the canvas
|
|
4. Use the canvas as a Three.js texture, apply shaders, map to 3D geometry
|
|
|
|
```html
|
|
<!-- 1. HTML content lives inside the canvas -->
|
|
<canvas id="capture" layoutsubtree width="1920" height="1080">
|
|
<div class="my-dashboard">
|
|
<h1>Revenue: $4.2M</h1>
|
|
<div class="chart">...</div>
|
|
</div>
|
|
</canvas>
|
|
|
|
<!-- 2. WebGL canvas for 3D rendering -->
|
|
<canvas id="theater" width="1920" height="1080"></canvas>
|
|
```
|
|
|
|
```javascript
|
|
// 3. Capture HTML to canvas
|
|
var capCanvas = document.getElementById("capture");
|
|
var ctx = capCanvas.getContext("2d");
|
|
ctx.drawElementImage(capCanvas.querySelector(".my-dashboard"), 0, 0, 1920, 1080);
|
|
|
|
// 4. Use as Three.js texture
|
|
var texture = new THREE.CanvasTexture(capCanvas);
|
|
var material = new THREE.MeshBasicMaterial({ map: texture });
|
|
```
|
|
|
|
## What makes this different
|
|
|
|
Traditional approaches like `html2canvas` re-parse and re-render the DOM in JavaScript — they're slow, lossy, and miss CSS features like `backdrop-filter`, complex shadows, and web fonts. The `drawElementImage` API uses the browser's own compositor, so:
|
|
|
|
- **Pixel-perfect** — every CSS feature is supported because the browser renders it natively
|
|
- **GPU-accelerated** — captures at 60fps, fast enough for real-time animation
|
|
- **Live content** — the HTML can animate, scroll, and change between captures
|
|
- **Multiple captures simultaneously** — no nesting restrictions, multiple `<canvas layoutsubtree>` elements can capture different content in the same composition
|
|
|
|
## Feature detection
|
|
|
|
Always feature-detect before using the API. Compositions should fall back gracefully for browsers without the flag enabled.
|
|
|
|
```javascript
|
|
function isSupported() {
|
|
var tc = document.createElement("canvas");
|
|
if (!("layoutSubtree" in tc)) return false;
|
|
tc.setAttribute("layoutsubtree", "");
|
|
var ctx = tc.getContext("2d");
|
|
return ctx && typeof ctx.drawElementImage === "function";
|
|
}
|
|
|
|
if (isSupported()) {
|
|
ctx.drawElementImage(element, 0, 0, w, h);
|
|
} else {
|
|
// Fallback: draw text directly on canvas, use static image, etc.
|
|
}
|
|
```
|
|
|
|
## Re-capturing every frame
|
|
|
|
For animated content (scrolling, transitions, counters), call `drawElementImage` inside your render loop to update the texture every frame:
|
|
|
|
```javascript
|
|
function render() {
|
|
// Update HTML state
|
|
scrollContainer.style.transform = "translateY(-" + scrollOffset + "px)";
|
|
counterEl.textContent = Math.round(currentValue);
|
|
|
|
// Re-capture
|
|
ctx.clearRect(0, 0, W, H);
|
|
ctx.drawElementImage(htmlElement, 0, 0, W, H);
|
|
texture.needsUpdate = true;
|
|
|
|
// Render 3D scene with updated texture
|
|
renderer.render(scene, camera);
|
|
}
|
|
```
|
|
|
|
## Catalog blocks
|
|
|
|
Install all HTML-in-Canvas blocks at once:
|
|
|
|
```bash
|
|
npx hyperframes add html-in-canvas
|
|
```
|
|
|
|
Or install individually:
|
|
|
|
| Block | Description | Install |
|
|
|-------|-------------|---------|
|
|
| [iOS 26 Liquid Glass Home Screen](/catalog/blocks/ios26-liquid-glass) | iPhone home screen with live Liquid Glass notifications and widgets | `npx hyperframes add ios26-liquid-glass` |
|
|
| [macOS Tahoe Liquid Glass Desktop](/catalog/blocks/macos-tahoe-liquid-glass) | MacBook desktop with liquid glass windows, dock, and notifications | `npx hyperframes add macos-tahoe-liquid-glass` |
|
|
| [Liquid Glass Notification](/catalog/blocks/liquid-glass-notification) | Native-feeling glass notification stack with progress and reply states | `npx hyperframes add liquid-glass-notification` |
|
|
| [iPhone & MacBook](/catalog/blocks/vfx-iphone-device) | Real 3D GLTF devices with live HTML screens | `npx hyperframes add vfx-iphone-device` |
|
|
| [Text Cursor](/catalog/blocks/vfx-text-cursor) | Dramatic text reveal with chromatic shadows | `npx hyperframes add vfx-text-cursor` |
|
|
| [Portal](/catalog/blocks/vfx-portal) | Dimension breach with volumetric light | `npx hyperframes add vfx-portal` |
|
|
| [Shatter](/catalog/blocks/vfx-shatter) | HTML shatters into glass fragments | `npx hyperframes add vfx-shatter` |
|
|
| [Magnetic](/catalog/blocks/vfx-magnetic) | Magnetic field particle visualization | `npx hyperframes add vfx-magnetic` |
|
|
| [Liquid Background](/catalog/blocks/vfx-liquid-background) | Organic liquid simulation | `npx hyperframes add vfx-liquid-background` |
|
|
|
|
## Rendering
|
|
|
|
HyperFrames enables the Chrome flag automatically during rendering. No special configuration needed:
|
|
|
|
```bash
|
|
npx hyperframes render --output my-video.mp4
|
|
```
|
|
|
|
For Docker renders, the flag is also enabled automatically inside the container.
|