Instagram Style Video Preload Static Effect
📣 Sponsor
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:
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);
<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:
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:
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:
More Tips and Tricks for Javascript
- How to Make Payments with the Javascript Payments API
- Websockets Tutorial: Creating a real-time Websocket Server
- What are the three dots (...) or spread operator in Javascript?
- How Events work in Javascript
- Javascript Errors
- How Promises and Await work in Javascript
- Javascript Objects Cheatsheet
- Checking if a value is a number in Javascript with isNaN()
- Check if an Object Contains all Keys in Array in Javascript
- Art Generator with Javascript and WebGL