curtains.js is an easy-to-use WebGL library that converts images, videos, and canvases into 3D WebGL graphics. WebGL (Web Graphics Library) is a JavaScript API used to render 3D and 2D graphics that users can interact with. curtains.js was built as a WebGL JavaScript library.
If you had been using curtains prior to the version 7.0 release, then you would will have noticed the many changes between the old and new version. In version 7.0, curtains was rewritten for better readability and maintainability, with the new library broken down into different class modules that are easy to work with.
In this article, we will discuss these class modules in more detail, but first, we’ll review some curtains basics.
To understand this question better, we need to first look at the problems that curtains is intended to solve. According to its official website, curtains.js converts HTML elements containing images, videos, and canvases into 3D WebGL, which allows these media to be further animated with the use of shaders. This makes curtains.js 3D graphics easy to position relative to the DOM of a web page, a luxury that is not commonly found in other 3D libraries.
Moreover, because curtains.js is built with the WebGL API, it saves you the stress of working directly with things like object sizes and positions. Instead, curtains handles these developments itself under the hood, making development easy and straightforward.
Finally, curtains has clear SEO benefits, allowing you to write clean HTML code for your design that is more likely than other 3D libraries to be ranked highly by a search engine.
If you had been using curtains prior to the version 7.0 release, then you would will have noticed the many changes between the old and new version. In version 7.0, curtains was rewritten for better readability and maintainability, with the new library broken down into different class modules that are easy to work with. We will discuss these class modules in more detail below.
These core classes are essential when creating a basic WebGL scene in curtains.js. They serve as the backbone needed to create any WebGL graphics in curtains. Core classes include curtains, plane and texture.
curtains
classTo start any curtains.js project, you will need to create a Curtains
object that will handle the provided plane scenes. This object takes in the id of the HTML element that will wrap the canvas.
Below is a sample Curtains
object instance:
// the id of the given html element in this case is canvas const curtainsInstance = new Curtains({ container: document.getElementById("canvas") });
Other notable parameters to set include;
setContainer()
to be called for the WebGL context to be setThe Curtains object instance also makes use of different methods in addition to different parameters to give users more control over their project. Some methods include:
clear()
: clears both the color and depth of a WebGL contextdisableDrawing()
: prevents an already drawn scene from being drawn again. This puts the scene in a pause state and the uniforms become disabledenableDrawing()
: needed to re-enable an already paused scene. This is useful if you plan on starting a scene after a specific eventdispose()
: cancels the requestAnimationFrame
loop, subsequently deleting the planes and the WebGL contextFinally, using the Curtains object, we can handle events with functions like onError()
and onContextLost()
provided by the curtains.js library.
The plane
class provided by curtains.js creates a WebGL plane based on the provided HTML element. Plane extends from baseplane
, a class that is used to set up the WebGL .
To create a plane, you need to pass in an HTML element and an already created curtains
class as shown below:
// the id of the given html element in this case is “canvas” const curtainInstance = new Curtains({ container: document.getElementById(“canvas”) }); const planeElement = document.getElementById(“plane-element”); const plane = new Plane(curtainInstance, planeElement)
Just like in the curtains
class, the plane
class takes in a third parameter where different options can be specified, as shown here:
// the id of the given html element in this case is “canvas” const curtainInstance = new Curtains({ container: document.getElementById(“canvas”) }); const planeElement = document.getElementById(“plane-element”) const params = { vertexShaderID: "plane-element-vs", fragmentShaderID: "plane-element-fs", / uniforms: { time: { name: "uTime", type: "1f", value: 0, }, }, }; const plane = new Plane(curtainInstance, planeElement , params)
vertixShaderID
and fragmentShaderID
are used to set the vertex and fragments of the shader, while uniforms
allows you to interact with your created plane.
As the name implies, texture
class is used to create textures.
You can easily create a texture by calling its constructor, like so:
// the id of the given html element in this case is “canvas” const curtainsInstance = new Curtains({ container: document.getElementById("canvas") }); const texture = new Texture( curtainInstance , { sampler: ‘texture’ })
Alternatively, you can call the createTexture() method on your plane:
// the id of the given html element in this case is “canvas” const curtainInstance = new Curtains({ container: document.getElementById(“canvas”) }); const planeElement = document.getElementById(“plane-element”) const plane = new Plane(curtainInstance, planeElement) const myTexture = plane.createTexture({ sampler: “uTexture” })
Now that we have covered core classes, we will discuss a few more classes in curtains v7.0 that you can use when designing your webpage.
These are classes used to add after effects on a plane. They include renderTarget
and ShaderPass
class.
In the code below, we will see how to create a ShaderPass
instance; you can learn more about Frame buffer objects here.
const curtainsInstance = new Curtains({ container: document.getElementById("canvas") }); const shaderPass = new ShaderPass(curtains)
Loaders are classes that are used to implement WebGL texture based off HTML media elements. An example of this is TextureLoader
. This class creates a texture using images, videos and canvases as its source. You can use TextureLoader
to preload a website’s texture to the GPU while still displaying a loader.
A new texture loader can be created by using its constructor, as in the example below:
// the id of the given html element in this case is “canvas” const curtainsInstance = new Curtains({ container: document.getElementById("canvas") }); // create a new texture loader const loader = new TextureLoader(curtainsInstance); // load an image with the loader const image = new Image(); image.crossOrigin = "anonymous"; image.src = "path/to/my-image.jpg"; loader.loadImage(image, { // options are set here sampler: "uTexture" }, (texture) => { // successfully created a texture }, (image, error) => { // error handler });
Texture for each media is created by making use of its individual methods. The TextureLoader
class uses different methods, including loadCanvas
and loadVideo
.
The loadCanvas
function creates a texture based on the canvas passed to it. It takes in three parameters: the given canvas element, a texture option, and a callback function. An example can be found here. You can also work with an array of canvases using the provided loadCanvases()
method provided.
Similar to loadCanvas
, the loadVideo
function creates a texture based on the video passed to it, but also takes a fourth parameter for error handling. You can work with more than one video using the loadVideos()
method.
Other methods, like loadImage()
and loadSource()
work similarly to the two methods listed above.
Math classes in curtains are based on the three.js math utility classes. They are used for dimensional vector manipulation. For example, Vec2
, Vec3
, and Mat4
are used for 2D, 3D, and 4D vector calculations and manipulation, respectively.
Here’s an example using constructors:
const nullVector = new Vec2(); const vector = new Vec2(1, 1)
Note that a Vec2
and Vec3
instance makes use of a setter and getter, which allows for an action to be performed on event change.
This can be done using the onChange()
method:
// create a new Vec2 vector add an event listener const vector = new Vec2().onChange(() => { const normalizedVector = vector.normalize(); }); // the actions below triggers to different events vector.x = 4; vector.y = 6;
curtains.js has earned its reputation as the go-to library for adding 2D and 3D effects to media including images, videos, and canvases. And with recent developments in version 7.0 and beyond — including class modules for a more streamlined build — development is that much easier.
There’s no doubt that frontends are getting more complex. As you add new JavaScript libraries and other dependencies to your app, you’ll need more visibility to ensure your users don’t run into unknown issues.
LogRocket is a frontend application monitoring solution that lets you replay JavaScript errors as if they happened in your own browser so you can react to bugs more effectively.
LogRocket works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting metrics like client CPU load, client memory usage, and more.
Build confidently — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowReact Native’s New Architecture offers significant performance advantages. In this article, you’ll explore synchronous and asynchronous rendering in React Native through practical use cases.
Build scalable admin dashboards with Filament and Laravel using Form Builder, Notifications, and Actions for clean, interactive panels.
Break down the parts of a URL and explore APIs for working with them in JavaScript, parsing them, building query strings, checking their validity, etc.
In this guide, explore lazy loading and error loading as two techniques for fetching data in React apps.