Skip to content

VHS: any barrel > 0 blacks out wrapped content when html-in-canvas is unavailable #29

Description

@nick-inkeep

Component

VHS

What happened?

Without html-in-canvas, VHS at default props is a clean no-op (0 px difference against a page without the component), which matches the fallback contract. But with barrel set to anything above zero, the fallback paints an opaque near-black field over the wrapped content. Headline, text and buttons are all invisible. The DOM underneath stays focusable and clickable, so DOM-level assertions still pass while the user sees nothing.

It behaves like a gate, not a distortion artifact: barrel: 0.000001 produces the identical blackout to 0.6 (mean luminance 254 to 3.2 in my harness, flat across five orders of magnitude). With the capability on, the same sweep stays at ~252 and content is fully legible, so the option itself works as designed. The bug is the delta between those two arms.

Where I think it lives (line numbers from the copied registry file, fetched 2026-08-07): the fallback contract is only implicit. Output alpha follows content alpha (L239), and uContent stays the transparent 1x1 placeholder because uploadContent() early-returns while !htmlInCanvas (L403). The barrel branch then forces alpha = 1.0 unconditionally (L243), and the bezel ring paints opaque independently (L168-171), so gating only the alpha line wouldn't be enough. uBarrel is uploaded ungated (L466) from the block that already has htmlInCanvas in scope. ParticleReveal and DecryptReveal handle this exact situation with uCrisp = reducedMotion || !htmlInCanvas ? 1 : 0; VHS has no equivalent.

All six docs demos use barrel: 0, which is probably why it hasn't come up.

Steps to reproduce

  1. npx shadcn@latest add @canvas-ui/vhs-react
  2. <VHS barrel={0.6}><h1>Hello</h1></VHS> over any visible content
  3. Open in Chrome without the flag or an origin-trial token. The content area renders as a near-black barrel-shaped field.

Browser and version

Chrome 151 / Chromium 151.0.7922.34, macOS

Is the html-in-canvas flag enabled?

No (WebGL overlay fallback)

Framework

React 19

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions