WebGL Video Transitions with Curtains.js

Some experimental video transitions using Curtains.js and shaders.

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!

Just press play, and check out this slick video transition

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!


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:

So the titles are in HTML, and the videos are distorted with WebGL. Isn’t that cool?

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>
<!-- 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(
    [...document.getElementsByClassName("plane")], // could be many Planes

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:

.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:

Can you guess where this transition is from?

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

Tagged with:

Yuri Artiukh

Yuriy is a developer from Kyiv, Ukraine. Leading a small frontend agency riverco.de, also speaking at conferences, and open for freelance projects. Curious about CSS and shaders. Loves to learn every day.

Stay in the loop: Get your dose of frontend twice a week

👾 Hey! Looking for the latest in frontend? Twice a week, we'll deliver the freshest frontend news, website inspo, cool code demos, videos and UI animations right to your inbox.

Zero fluff, all quality, to make your Mondays and Thursdays more creative!