Javascript

Instagram Style Video Preload Static Effect

Instagram reels, a relatively new feature to instagram, have this interesting noise effect before the video loads. Recently, my airpods have had some issue connecting to instagram and I often get this static effect before the app catches up and connects to them.

This noise effect is pretty cool, and it's nostalgic of old TV sets. It got me thinking about how we could do this for videos on the web or in Javascript applications. Let's take a look at how to do that, with some perlin noise.

Perlin Noise

First off, we need a good perlin noise function. Perlin noise is a way of generating random noise which we can use to create the static effect we're after.

I'm going to be using the code from this repository. This code gives us a function called noise which we can use to generate our noise context. Let's use this to generate some noise:

html Copy
let video = document.getElementById('video'); let canvas = document.getElementById('noise-canvas'); canvas.width = 250; canvas.height = 250; let ctx = canvas.getContext('2d'); function generateNoise() { var image = ctx.createImageData(canvas.width, canvas.height); var data = image.data; for (var x = 0; x < canvas.width; x++) { noise.seed(Math.random()); for (var y = 0; y < canvas.height; y++) { var value = Math.abs(noise.perlin2(x / 2, y / 2)); value *= 500; var cell = (x + y * canvas.width) * 4; data[cell] = data[cell + 1] = data[cell + 2] = value; data[cell + 3] = 255; // alpha. } } ctx.putImageData(image, 0, 0); } function animation(timestamp) { generateNoise(); window.requestAnimationFrame(animation); } window.requestAnimationFrame(animation);
html Copy
<div id="video-container"> <video id="video" muted=""> <source src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/mp4"> </video> <div id="canvas-overlay"></div> <canvas id="noise-canvas"></canvas> </div>

Essentially this code goes pixel by pixel and generates an image which has random colors for each pixel. For this demo, the canvas width and height are set to 250px in this code on the 4th and 5th line. You might have to change this if your video is much bigger.

I've also created a canvas overlay div which has a slight gradient on it. The styles for this look like this:

css Copy
canvas, #canvas-overlay { position: absolute; top: 0; left: 0; width: 100%; background: black; height: 100%; z-index: 9999; } #canvas-overlay { z-index: 9999999; background: linear-gradient(-135deg, #343fa99e, #2ed29d1c); } video { height: 100%; width: auto; position: absolute; } #video-container { position: relative; width: 250px; box-shadow: 0 5px 25px rgb(0 0 0 / 7%), 0 2px 5px rgb(0 0 0 / 15%), 0 15px 30px rgb(0 0 0 / 10%), 0 0 0px 5px #00000000, 0 0 3px 1px #00000000; border-radius: 15px; overflow: hidden; height: 250px; }

Video autoplay

The next step takes advantage of the Javascript Video API. When the video is loaded, we will hide the static canvas and the canvas overlay:

javascript Copy
video.addEventListener('loadeddata', function() { canvas.style.display = 'none'; document.getElementById('canvas-overlay').style.display = 'none'; video.play(); }, false);

And that's it

Full code below:

Last Updated Sunday, 14 March 2021