How to Make a TV Static Effect With HTML Canvas and JavaScript
Television static is thousands of random grey dots, redrawn many times a second. That makes it a perfect first canvas project: the idea is simple, the result is dramatic, and it teaches how pictures are stored as numbers.

The complete code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>No Signal</title>
<style>
body { margin: 0; height: 100vh; background: #000; overflow: hidden; }
canvas { width: 100%; height: 100%; display: block; image-rendering: pixelated; }
#label {
position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
background: #000; color: #fff; padding: 12px 24px;
font: bold 28px "Courier New", monospace; letter-spacing: 3px;
}
</style>
</head>
<body>
<canvas id="screen" width="320" height="180"></canvas>
<div id="label">NO SIGNAL</div>
<script>
const canvas = document.getElementById("screen");
const ctx = canvas.getContext("2d");
const image = ctx.createImageData(canvas.width, canvas.height);
const pixels = image.data;
function drawNoise() {
for (let i = 0; i < pixels.length; i += 4) {
const grey = Math.floor(Math.random() * 256);
pixels[i] = grey; // red
pixels[i + 1] = grey; // green
pixels[i + 2] = grey; // blue
pixels[i + 3] = 255; // fully visible
}
ctx.putImageData(image, 0, 0);
}
setInterval(drawNoise, 60);
</script>
</body>
</html>
How to use this code
- Get the file. Press Download above the code to save it as
tv-static.html. Or press Copy code, paste it into a plain text editor (Notepad on Windows, TextEdit in plain-text mode on a Mac, or a code editor such as VS Code) and save it astv-static.html. The name must end in.html, not.txt. - Open it. Double-click the file. It opens in your web browser and starts working straight away.
- Change it. Open the same file in the text editor, edit something, save, and refresh the browser page to see the result.
Nothing needs to be installed, and the file works without an internet connection.
The static flickers quickly. Do not use it if you or your viewers are sensitive to flashing images.
How the code works
A small canvas, stretched
The canvas is only 320 by 180 pixels, but the CSS stretches it across the whole window. That has two benefits: the dots are big enough to see, like real static, and the computer has far fewer pixels to fill. image-rendering: pixelated keeps the stretched dots sharp instead of blurred.
Pixels are four numbers each
createImageData gives you a long list of numbers that describes every pixel. Each pixel uses four numbers in a row: red, green, blue and opacity, each from 0 to 255.
- The loop moves forward four at a time (
i += 4), so each pass handles one pixel. Math.floor(Math.random() * 256)picks a random whole number from 0 to 255.- Setting red, green and blue to the same number always gives a shade of grey, from black (0) to white (255).
- The fourth number, 255, makes the pixel fully visible.
Showing and repeating
putImageData copies the list of numbers onto the canvas in one go. setInterval(drawNoise, 60) repeats the whole thing every 60 milliseconds, about 16 times a second, with new random values each time.
Easy changes to try
| To change | Edit this |
|---|---|
| The message | The text inside the label div, or delete the div for static only |
| Dot size | The canvas width and height. Smaller numbers give bigger dots |
| Speed | The 60 in setInterval |
| Colour static | Give red, green and blue three separate random numbers |
| Darker static | Change 256 to 120 |
| Green "night vision" static | Set red and blue to 0 and keep green random |
FAQ
Why use canvas for static?
Static needs tens of thousands of dots changing many times a second. A canvas can set them all in one step, which HTML elements cannot do efficiently.
Can I add the hissing sound?
Yes, with the Web Audio API, by filling an audio buffer with random numbers in the same way. Browsers only allow sound to start after a click.
How do I make it full screen?
Press F11, or Control+Command+F on a Mac.