Distortion✨ Premium

Static Noise

TV snow with no antenna drawn on a canvas, scanlines, a sliding bar and a crackling “NO SIGNAL”: the dead-channel screen, down to the pixel.

CSSJSCanvas

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Distortion has 31 effects, including 5 free. Explore the category →

3 usage examples

Switching channels on a local web TV — Static Noise example 1

① Switching channels on a local web TV

WhenOn Ombrevaux TV, the viewer clicks another channel in the list: snow fills the player with the number “CH 03” for 0.65 s, then the new channel's picture and title appear.
WhyReal-TV zapping gives instant feedback on the click and hides the loading time of the next stream.
SettingsThe root covers the player: --tvn-w: 100%, --tvn-h: 100%, --tvn-radius: 0, --tvn-opacity: .6, --tvn-text-size: 1.4rem. The scene shows it on click then hides it; without a click it zaps on its own.
Scrambled monitor to tune in an online escape game — Static Noise example 2

② Scrambled monitor to tune in an online escape game

WhenIn the “Control room” of the Sorvanne escape game, the clue sits on a monitor drowned in snow; the player turns the receiver to 473 MHz and the safe code appears.
WhyThe snow really hides the clue, which lies underneath; tuning it becomes the puzzle. A single CSS variable does all the work.
Settings276×186 px screen, --tvn-bg: #0d1a12, data-fps="30". The code is an element with no position, hence under the snow; the slider sets --tvn-opacity from .95 (far from the frequency) to .10 (on it). The scene sweeps the band until someone touches the slider.
Episode not yet aired in a series' episode list — Static Noise example 3

③ Episode not yet aired in a series' episode list

WhenIn the episode list of the series Drévoline, the first four have their picture; the fifth, “Available Friday 22 Nov”, has a snowy thumbnail marked “SOON” and a “Remind me” button.
WhyThe snowy thumbnail says “not on air yet” with no badge or padlock, and fits a series where a lighthouse “loses the signal”.
Settings76×42 px thumbnail: --tvn-w: 100%, --tvn-h: 100%, --tvn-radius: 4px, --tvn-text-size: 8px, --tvn-opacity: .6, data-fps="30".

How it works

The .tvn-screen (280×180 px, #0a0a0a background, 8 px corners) stacks four layers. At the bottom, the .tvn-canvas: on every frame the script gives each of its pixels a random grey, then shows it at 40% opacity. Above it, .tvn-lines draws a dark line every 2 px, and .tvn-bar, a 3 px light stroke, slides from top to bottom in 0.5 s. Last, the .tvn-text (“NO SIGNAL”, monospaced) carries a white glow plus red and cyan offsets, and wavers slightly (opacity 0.95 to 1 every 0.1 s).

The canvas takes the screen's size times the display density (capped at 2): the snow stays fine on a Retina display. A ResizeObserver resizes it whenever the screen changes size. The snow is redrawn at most 60 times per second (data-fps), even on a 120 Hz display, and not at all when the screen is out of view or the tab hidden (measured: 0 frames computed in 2 s off screen).

Each .tvn-screen has its own canvas and its own loop: two copies on a page snow independently (measured in Chromium 151, Firefox 153 and WebKit 26.5). The draw uses a small fast generator (xorshift) instead of Math.random(), to keep the pace on large screens.

An element placed in .tvn-screen with no position (neither absolute nor relative) is painted under the snow: the --tvn-opacity variable then sets how scrambled it looks. The escape game example does exactly that.

Accessibility

  • Reduced motion: under prefers-reduced-motion: reduce, the snow is drawn once and stays still, the scan bar is hidden and the text stops wavering. The “no signal” screen remains readable as it is.
  • Photosensitivity: the snow changes every frame, but pixel by pixel: the average brightness stays constant, no area flashes (frame-by-frame measurement, well below the WCAG 2.3.1 threshold). The text waver never exceeds 5% opacity.
  • Screen readers: canvas, lines and bar carry aria-hidden="true"; only the .tvn-text text is read. Write a useful sentence there (“Episode available Friday”) rather than a bare “NO SIGNAL” if the screen carries information.
  • Click and touch: every layer has pointer-events: none; the effect intercepts nothing.

Browser compatibility

Canvas 2D (putImageData), CSS variables, inset and 2 KB of JavaScript. Minimum version set by inset according to MDN data (Chrome 87, Firefox 66, Safari 14.1). ResizeObserver and IntersectionObserver are checked before use. Measured in Chromium 151, Firefox 153 and WebKit 26.5, and at density 2 (canvas twice as fine).

Chrome 87+✓ Full (measured)
Firefox 66+✓ Full (measured)
Safari 14.1+✓ Full (measured in WebKit)
Edge 87+✓ Full (Chromium engine)
Mobile iOS 14.5+✓ Full
Android Chrome 87+✓ Full

Without JavaScript, the screen stays black with its lines, bar and text: no snow. Without ResizeObserver, the canvas only follows window resizes.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0260-root">
  <div class="tvn-screen" data-fps="60">
    <canvas class="tvn-canvas" aria-hidden="true"></canvas>
    <div class="tvn-lines" aria-hidden="true"></div>
    <div class="tvn-bar" aria-hidden="true"></div>
    <span class="tvn-text">…</span>
  </div>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
--tvn-w / --tvn-h 280px / 180px Screen size; the canvas follows. 100% fills the container (give the root a height with --tvn-root-h).
--tvn-opacity .4 Snow density. Around .9 it covers whatever lies underneath; around .1 it is just a veil.
data-fps (on .tvn-screen) 60 (1 to 60) Snow draws per second. 20–30 is plenty for a small thumbnail and spares phones.
--tvn-bg #0a0a0a Screen background, seen between the specks.
--tvn-text-size 1.2rem Size of the .tvn-text, to shrink inside a thumbnail.
--tvn-radius 8px Corner radius of the screen.
--tvn-root-bg / --tvn-root-h #0a0a0f / 300px Background and minimum height of the root; transparent and 0 to blend it into your layout.
Text (HTML — .tvn-text) “NO SIGNAL” Replace it with your message, or delete the tag for silent snow.

FAQ

It recomputes every pixel on every frame: about 200,000 pixels at 60 frames per second for the default screen on a Retina display. That is light for a computer. On a very large area, lower data-fps to 30: the snow stays convincing. Off screen, nothing is computed.
Yes: show the root (remove hidden) when loading starts and hide it at the end. Hidden, it computes nothing; shown, it sizes itself and snows straight away. That is how the zapping example works.
In the JavaScript, the line pixels[i] = 0xff000000 | gray << 16 | gray << 8 | gray writes the same grey into all three channels. For bluish snow, keep blue full and reduce the others, for example (gray >> 1) << 8 | (gray >> 1) for green and red.