From our sponsor: Chromatic - Visual testing for Storybook, Playwright & Cypress. Catch UI bugs before your users do.
We’ve done some crazy polygon transitions, and before that some WebGL Image Transitions. But a lot of people have been asking how to translate those techniques into the video world. And I agree, one cannot underestimate the importance of video on the web. So let’s do this!
For today’s demos we’ll be using curtains.js, a really great WebGL tool for animating images and videos. It was created by Martin Laxenaire and the new version is packed with great features. Go check out the docs if you didn’t know about it yet!
What library?
Three.js is the industry standard for creating WebGL effects, but we already had a lot of demos using it. And there are a lot of other awesome WebGL libraries out there. All with a different kind of focus and purpose. So let’s dive into one of them!
Curtains.js
This library was made by Martin Laxenaire. It was just recently updated with a lot of cool stuff, and so I decided to use it for this demo.
The focus of this library is (from the homepage):
A lot of very good JavaScript libraries already handle WebGL but with most of them it’s kind of a headache to position your meshes relative to the DOM elements of your web page. Curtains.js was created with just that issue in mind.
Yes, exactly, connecting the DOM with WebGL! That’s pretty straightforward with curtains.js; one of the demos showcased is this:
And that’s not it! We also have a postprocessing, FBOs, and full control over all of it with our custom shaders!
Our demos
So, yeah, curtains.js is pretty cool and I really recommend you to try it. But let’s get back to our idea of animating videos in WebGL.
Turns out it’s ridiculously easy with curtains.js. Here is the HTML we will be using:
<div id="canvas"></div>
<div class="wrapper">
<div class="plane">
<video src="1.mp4" data-sampler="first"></video>
<video src="2.mp4" data-sampler="second"></video>
</div>
</div>
<!-- and some custom shaders, because we will be using them -->
<script id="vertexShader">...</script>
<script id="fragmentShader">...</script>
But, HTML has never been exciting in WebGL demos, so lets look at what JavaScript you need now to get the video in WebGL:
const curtains = new Curtains({
container: "canvas",
pixelRatio: Math.min(1.5, window.devicePixelRatio),
});
const params = {
vertexShaderID: "vertexShader",
fragmentShaderID: "fragmentShader",
uniforms: {
transition: {
name: "uTransition",
type: "1f",
value: 0,
},
},
};
const multiTexturesPlane = new Plane(
curtains,
[...document.getElementsByClassName("plane")], // could be many Planes
params
);
Well, that’s it! Because the focus of this library is shaders connected to the DOM, we don’t have any Camera or Scene concepts here. And the setup becomes pretty straightforward. That hooked me up immediately and I decided to share that with you guys, by using it in this demo.
Of course this is not the whole code. Because it’s a video we need some kind of user action to play it. And then, we also need some animation for the transition between the videos. But that part is pretty common to all those kind of effects. In curtain.js events are used for that:
multiTexturesPlane
.onReady(() => {
// navigation click events
// play button
})
.onRender(() => {
// updating time or anything
});
And with that kind code you are ready to do any shader transitions like this one:
All the magic is happening in shaders, and just to show you that images and videos are the same in WebGL, I used one of the effects from my previous demo. If you want to learn shaders, I advise you to read the amazing Book Of Shaders.
I hope you liked this short tutorial on getting videos into WebGL. Go get the source and play with the code!
References and Credits
- curtains.js by Martin Laxenaire
- Videos from MixKit and Coverr
- Play icon by Smashicons