Belinda Ijeoma Frontend engineer | Technical writer | Tech enthusiast

Working with classes in curtains.js

5 min read 1435

Curtains.js setup example in react apps

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.

Back to basics: What does curtains do?

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.

curtains classes in version 7.0

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.

Core classes

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 class

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

We made a custom demo for .
No really. Click here to check it out.

// 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;

  • Production: this parameter receives a Boolean value and is used to specify whether or not you want the library in production mode
  • Container: this parameter specifies the HTML element that will wrap the canvas. This parameter receives either a string or an HTML element. Note that this property is optional and if not specified, curtains.js will have to wait for setContainer() to be called for the WebGL context to be set
  • watchScroll: This parameter determines if curtains.js should listen to a scroll event. It takes in a boolean as its value

The 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 context
  • disableDrawing(): prevents an already drawn scene from being drawn again. This puts the scene in a pause state and the uniforms become disabled
  • enableDrawing(): needed to re-enable an already paused scene. This is useful if you plan on starting a scene after a specific event
  • dispose(): cancels the requestAnimationFrame loop, subsequently deleting the planes and the WebGL context

Finally, using the Curtains object, we can handle events with functions like onError() and onContextLost() provided by the curtains.js library.

Plane class

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.

Textures class

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.

Frame buffer objects

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

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

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;

Conclusion

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.

Are you adding new JS libraries to improve performance or build new features? What if they’re doing the opposite?

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.

https://logrocket.com/signup/

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

Belinda Ijeoma Frontend engineer | Technical writer | Tech enthusiast

Leave a Reply