curtains.js

repository·master·Indexed 23 days ago

https://github.com/martinlaxenaire/curtainsjs

A lightweight vanilla WebGL library that converts HTML elements containing images and videos into 3D WebGL textured planes. It allows developers to define plane size and position via CSS and animate them using shaders, bridging the gap between the DOM and WebGL.

Tokens
4.8K
Snippets
3
Records
38
Agent score
78%

What's inside curtainsjs

  1. How curtains.js works: HTML elements to WebGL planes

    master

    curtains.js is a vanilla WebGL library that converts HTML elements (containing images or videos) into 3D WebGL textured planes.

    Key Workflow:

    1. Define Layout in CSS: You define the size and position of your planes using standard CSS. This allows for responsive WebGL elements that follow your web page layout.
    2. Create a Canvas Container: A Curtains instance appends a canvas to a specified container to manage the WebGL context, resize events, and the animation loop.
    3. Bind Planes to Elements: You create Plane objects by binding them to specific HTML elements. These elements act as the source for the textures used in the WebGL planes.
    4. Animate via Shaders: Once bound, you can pass uniforms (like time) to vertex and fragment shaders to create complex 3D interactions and animations.
    import {Curtains, Plane} from 'curtainsjs';
    
    const curtains = new Curtains({
        container: "canvas"
    });
    
    const plane = new Plane(curtains, document.querySelector("#plane"));
  2. Initialize curtains.js and create a Plane

    master

    To get started, initialize the Curtains instance with a container element, then create a Plane by passing the curtains instance, a DOM element, and a configuration object containing shader IDs and uniforms.

    Example Setup

    HTML Structure:

    <div id="canvas"></div>
    <div class="plane">
        <img src="path/to/my-image.jpg" crossorigin="" />
    </div>

    CSS Requirements: Ensure the #canvas container covers the desired area and the .plane element has defined dimensions. Note that the img inside the plane should typically be hidden (display: none) as it is used as a texture source.

    JavaScript Implementation:

    import {Curtains, Plane} from 'curtainsjs';
    
    window.addEventListener("load", () => {
        const curtains = new Curtains({
            container: "canvas"
        });
        
        const planeElement = document.getElementsByClassName("plane")[0];
        
        const params = {
            vertexShaderID: "plane-vs",
            fragmentShaderID: "plane-fs",
            uniforms: {
                time: {
                    name: "uTime",
                    type: "1f",
                    value: 0,
                },
            },
        };
        
        const plane = new Plane(curtains, planeElement, params);
        
        plane.onRender(() => {
            plane.uniforms.time.value++;
        });
    });
  3. Install curtains.js

    master

    You can install curtainsjs via npm or use the UMD files directly in the browser.

    Using npm

    npm i curtainsjs

    Using ES6 Modules (Direct Download)

    Import directly from your local source path:

    import {Curtains, Plane} from 'path/to/src/index.mjs';

    Using UMD (Browser Script Tag)

    Include the minified UMD file from the dist directory:

    <script src="dist/curtains.umd.min.js"></script>
  4. How PlaneTextureLoader manages parent assets

    master

    The PlaneTextureLoader automatically organizes loaded assets into the appropriate arrays on the parent object (the Plane or ShaderPass) based on the sourceType.

    When a texture is created via this loader, it performs two actions:

    1. Asset Categorization: It adds the source to the parent's internal asset arrays:
      • image sources are added to parent.images.
      • video sources are added to parent.videos.
      • canvas sources are added to parent.canvases.
    2. Parent Linking: It calls texture.addParent(this._parent) to ensure the texture is correctly associated with the plane or shader pass using it.

    Note: The loader prevents duplicate entries by checking if a source with the same src (for images/videos) or the same node (for canvases) already exists in the parent's array before adding it.

  5. How the Scene rendering order works

    master

    The Scene optimizes rendering by stacking objects into specific arrays and drawing them in a strict order. This minimizes state changes and WebGL calls. The default draw order is:

    1. Ping Pong Planes: Special planes used for specific effects.
    2. Shader Pass Enablement: If scene passes are used, the first frame buffer is bound.
    3. Render Targets: Planes that are rendered onto a specific render target.
    4. Render Passes: The content of the render targets created in the previous step.
    5. Opaque Planes: Rendered with blending disabled.
    6. Transparent Planes: Rendered with blending enabled, ordered by renderOrder, Z position, geometry IDs, and addition index.
    7. Scene Passes: The final scene pass content.
  6. Reference: Core classes in curtains.js

    master

    The following classes are exported in src/index.mjs and are intended for direct use:

    • Curtains: Appends a canvas to a container and instantiates the WebGL context. Manages scroll/resize events and the requestAnimationFrame loop.
    • Plane: Creates a new Plane object bound to a specific HTML element.
    • Textures: Creates a new Texture object.
  7. Reference: Advanced modules in curtains.js

    master

    The library includes specialized modules for advanced WebGL workflows:

    Frame Buffer Objects (FBOs)

    • RenderTarget: Creates a frame buffer object.
    • ShaderPass: Creates a post-processing pass using a RenderTarget object.

    Loader

    • TextureLoader: Loads HTML media elements (images, videos, canvases) and creates Texture objects.

    Math

    • Vec2: Vector 2
    • Vec3: Vector 3
    • Mat4: Matrix 4
    • Quat: Quaternion

    Extras

    • PingPongPlane: A plane that uses FBO ping-ponging to read/write a texture.
    • FXAAPass: An antialiasing FXAA pass using a ShaderPass object.
  8. Load an image source

    master

    Use loadImage to convert an image URL or an HTML <img> element into a Texture object.

    • source: A string (URL) or an HTML <img> element.
    • textureOptions: An object containing texture parameters (e.g., sampler, repeat, wrapS, wrapT, minFilter, magFilter, anisotropy).
    • successCallback: A function called when the texture is ready. It receives the texture object as an argument.
    • errorCallback: A function called if loading fails. It receives the source and the error object.
  9. Load a video source

    master

    Use loadVideo to convert a video URL or an HTML <video> element into a Texture object. The loader automatically sets the video to muted, loop, and playsinline to ensure compatibility and autoplay.

    • source: A string (URL) or an HTML <video> element.
    • textureOptions: An object containing texture parameters.
    • successCallback: A function called when the video is ready to play (canplaythrough event). It receives the texture object.
    • errorCallback: A function called if loading fails.
  10. Initialize the Scene class

    master

    The Scene class manages the collection of objects (planes) and lights in the WebGL context. It organizes them into specialized stacks to optimize the rendering order and minimize WebGL calls. To instantiate a Scene, you must provide an existing Renderer instance.

    Note: The Scene requires the Renderer to have a valid WebGL context (gl).

  11. Initialize the Camera class

    master

    The Camera class creates a perspective camera and its projection matrix. The projection matrix is used by Plane class objects to render correctly in the WebGL scene. You can configure the field of view, clipping planes, and aspect ratio during instantiation.

    Constructor Parameters:

    • fov (float, optional): Perspective field of view (1-179). Default: 50.
    • near (float, optional): Near clipping plane (closest point drawn). Default: 0.1.
    • far (float, optional): Far clipping plane (farthest point drawn). Default: 150.
    • width (float, optional): Width used for aspect ratio calculation.
    • height (float, optional): Height used for aspect ratio calculation.
    • pixelRatio (float, optional): Pixel ratio for aspect ratio calculation. Default: 1.
  12. Remove a Plane or ShaderPass from the Scene

    master

    To remove objects from the rendering pipeline, use the following methods:

    • removePlane(plane): Removes a plane from its respective stack (pingPong, renderTargets, transparent, or opaque).
    • removeShaderPass(shaderPass): Removes shader passes by resetting the shader pass stacks (rebuilding them from the renderer's current shader passes).