### Install and Initialize curtains.js Source: https://www.curtainsjs.com/index.html Installation via npm and basic initialization using the UMD browser script. ```bash npm i curtainsjs ``` ```javascript import {Curtains, Plane} from 'curtainsjs'; ``` ```html ``` ```javascript // "canvas" is the ID of our HTML container element const curtains = new Curtains({ container: "canvas" }); const plane = new Plane(curtains, document.getElementById("my-plane")); ``` -------------------------------- ### Texture Options Example Source: https://www.curtainsjs.com/texture-class.html Configure texture properties like filtering, anisotropy, wrapping, and alpha blending during creation. Use `curtains.gl` for WebGL constants. ```javascript const curtains = new Curtains({ container: "canvas" }); const texture = new Texture(curtains, { sampler: "uTexture", premultiplyAlpha: true, minFilter: curtains.gl.LINEAR_MIPMAP_NEAREST, anisotropy: 16, floatingPoint: "half-float" }); ``` -------------------------------- ### Chain Quat methods Source: https://www.curtainsjs.com/quat-class.html Most Quat methods return the instance, allowing for method chaining. This example sets the axis order and then creates a quaternion from a Vec3. ```javascript const quaternion = new Quat().setAxisOrder("YXZ").setFromVec3(new Vec3(1, 1, 1)); ``` -------------------------------- ### Quat Class - Basic Usage and Creation Source: https://www.curtainsjs.com/quat-class.html Demonstrates how to create and initialize Quat objects, including default values and chaining methods. ```APIDOC ## Quat Class Quat is the class used for rotation quaternions manipulations. Quaternions are used to represent rotations in the 3D space. ### Basic Usage #### Creation To create a new Quat, just use its constructor. If used without parameters, it will create a quaternion representing a rotation of angle 0 along X, Y and Z axes with "XYZ" as axis order: [0, 0, 0, 1]. ```javascript // create a new Quat quaternion const quaternion = new Quat(); ``` ### Use Chaining Since most of the Quat methods return the quaternion itself, you can use chaining. ```javascript // create a new Quat quaternion and chain methods const quaternion = new Quat().setAxisOrder("YXZ").setFromVec3(new Vec3(1, 1, 1)); ``` ### Parameters * **elements** (array of floats of length 4, optional) - Values to use for that quaternion. Default to [0, 0, 0, 1]. * **axisOrder** (string, optional) - Axis order to use for the rotation calculations. Default to "XYZ". ``` -------------------------------- ### Animating Vertex Z Position Source: https://www.curtainsjs.com/get-started.html Example of modifying vertex Z position using a sinusoidal function based on X coordinates and time. ```GLSL vec3 vertexPosition = aVertexPosition; vertexPosition.z = sin(vertexPosition.x * 3.141592 + uTime * 0.0375) * 0.05; gl_Position = uPMatrix * uMVMatrix * vec4(vertexPosition, 1.0); ``` -------------------------------- ### TextureLoader Creation and Usage Source: https://www.curtainsjs.com/texture-loader-class.html Demonstrates how to create a TextureLoader instance and use it to load an image, with options for texture parameters and callbacks for success or error. ```APIDOC ## TextureLoader Creation and Usage ### Description Instantiate a TextureLoader to preload images and create textures. This is useful for loading all website textures to the GPU before initializing other components, such as Planes or ShaderPasses. ### Method `new TextureLoader(curtains)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```javascript // Initialize Curtains const curtains = new Curtains({ container: "canvas" }); // Create a new TextureLoader instance const loader = new TextureLoader(curtains); // Prepare an image element const image = new Image(); image.crossOrigin = "anonymous"; image.src = "path/to/my-image.jpg"; // Load the image using the TextureLoader loader.loadImage(image, { // Texture options sampler: "uTexture" }, (texture) => { // Success callback: texture is ready to use console.log("Texture loaded successfully:", texture); }, (image, error) => { // Error callback: handle loading errors console.error("Error loading image:", error); }); ``` ### Response #### Success Response (Texture Object) - **texture** (object): The created texture object, ready to be used. #### Response Example ```json { "texture": { ... } // Texture object details } ``` ### Error Handling Errors during image loading are handled by the provided error callback function. ``` -------------------------------- ### ShaderPass Initialization Source: https://www.curtainsjs.com/shader-pass-class.html Configuration parameters for creating a new ShaderPass instance. ```APIDOC ## ShaderPass Initialization ### Description Defines the parameters used to initialize a ShaderPass object. ### Parameters #### Request Body - **curtains** (Curtains class object) - Required - Your Curtains class object. - **params** (object) - Optional - An object containing the plane parameters: - **vertexShader** (string) - Optional - Your vertex shader as a string. - **vertexShaderID** (string) - Optional - The vertex shader ID. - **fragmentShader** (string) - Optional - Your fragment shader as a string. - **fragmentShaderID** (string) - Optional - The fragment shader ID. - **renderOrder** (int) - Optional - Defines in which order the shader passes are drawn. Default to 0. - **depthTest** (bool) - Optional - If your shader pass should enable or disable the depth test. Default to true. - **depth** (bool) - Optional - Whether the shader pass render target should use a depth buffer. Default to false. - **clear** (bool) - Optional - Whether the shader pass render target content should be cleared. Default to true. - **renderTarget** (RenderTarget class object) - Optional - An already existing render target to use. - **texturesOptions** (object) - Optional - Default options to apply to the textures. - **crossOrigin** (string) - Optional - Defines the crossOrigin process to load images. - **uniforms** (object) - Optional - The uniforms that will be passed to the shaders. ``` -------------------------------- ### Initialize a Plane with parameters Source: https://www.curtainsjs.com/plane-class.html Configure a Plane with custom shaders and uniforms by passing a parameters object as the third argument. ```javascript // "canvas" is the ID of our HTML container element const curtains = new Curtains({ container: "canvas" }); const planeElement = document.getElementById("my-plane"); const params = { vertexShaderID: "my-plane-vs", // ID of your vertex shader script tag fragmentShaderID: "my-plane-fs", // ID of your fragment shader script tag uniforms: { // uniforms are what will allow you to interact with your plane time: { name: "uTime", // uniform name that will be passed to our shaders type: "1f", // this means our uniform is a float value: 0, // initial value of the uniform }, }, }; // create our plane with the above parameters const plane = new Plane(curtains, planeElement, params); ``` -------------------------------- ### Vec2 Class - Basic Usage and Creation Source: https://www.curtainsjs.com/vec-2-class.html Demonstrates how to create Vec2 instances, including a null vector and a vector with initial values. It also shows the chaining capability of Vec2 methods. ```APIDOC ## Vec2 Class - Basic Usage and Creation ### Description This section covers the fundamental usage of the Vec2 class, including its instantiation and the concept of method chaining. ### Creation To create a new Vec2, use its constructor. If no parameters are provided, it defaults to a null vector (X and Y components equal to 0). ```javascript // Create a null vector const nullVector = new Vec2(); // Create a vector with initial values const vector = new Vec2(1, 1); ``` ### Chaining Methods Most Vec2 methods return the vector instance itself, allowing for method chaining to perform multiple operations sequentially. ```javascript // Create a new Vec2 vector and chain methods const chainedVector = new Vec2().addScalar(2).normalize(); ``` ### onChange Callback The Vec2 class supports an `onChange` callback that executes whenever a vector component (x or y) is modified. This is achieved using getters and setters. ```javascript // Create a new Vec2 vector and listen to its changes const vectorWithCallback = new Vec2().onChange(() => { console.log('Vector component changed!'); }); // This will trigger the onChange callback vectorWithCallback.x = 1; // This will also trigger the onChange callback vectorWithCallback.y = 2; ``` ### Parameters * **X** (float, optional): Value along the X axis. Defaults to 0. * **Y** (float, optional): Value along the Y axis. Defaults to 0. ``` -------------------------------- ### Create a PingPongPlane instance Source: https://www.curtainsjs.com/ping-pong-plane-class.html Initializes a new PingPongPlane and sets up a display plane to render the resulting texture. ```javascript // "canvas" is the ID of our HTML container element const curtains = new Curtains({ container: "canvas" }); const pingPongPlaneElement = document.getElementById("my-ping-pong-plane"); const params = { vertexShaderID: "ping-pong-vs", // ID of your vertex shader script tag fragmentShaderID: "ping-pong-fs", // ID of your fragment shader script tag sampler: "uTexture", // sampler to use in your fragment shader. Default to "uPingPongTexture" uniforms: { // uniforms are what will allow you to interact with your plane time: { name: "uTime", // uniform name that will be passed to our shaders type: "1f", // this means our uniform is a float value: 0, // initial value of the uniform }, }, }; // create our ping pong plane with the above parameters const pingPongPlane = new PingPongPlane(curtains, pingPongPlaneElement, params); // create a plane to use our ping pong plane effect const planeElement = document.getElementById("my-plane"); const plane = new Plane(curtains, planeElement); // create a texture that will contain the result of our ping pong effect const pingPongTexture = plane.createTexture({ sampler: "uTexture", fromTexture: pingPongPlane.getTexture() }); ``` -------------------------------- ### CurtainsJS Methods Source: https://www.curtainsjs.com/curtains-class.html Methods for initializing and managing the CurtainsJS instance. ```APIDOC ## setPixelRatio ### Description Sets a new pixel ratio and resizes the canvas accordingly. Useful for performance optimization by limiting the pixel ratio. ### Method `setPixelRatio(pixelRatio, triggerCallback)` ### Parameters #### Parameters - **pixelRatio** (float) - The new pixel ratio to set. - **triggerCallback** (bool, optional) - Whether to trigger the onAfterResize callback. Defaults to false. ### Request Example ```javascript curtains.setPixelRatio(1.5, true); ``` ## updateScrollValues ### Description Updates the scroll values. Should be called before updating plane positions when scrolling. ### Method `updateScrollValues(xOffset, yOffset)` ### Parameters #### Parameters - **xOffset** (float) - Scroll value along the X axis. - **yOffset** (float) - Scroll value along the Y axis. ### Request Example ```javascript curtains.updateScrollValues(window.scrollX, window.scrollY); ``` ``` -------------------------------- ### Constructor: new Curtains() Source: https://www.curtainsjs.com/curtains-class.html Initializes a new Curtains instance to manage the WebGL scene. ```APIDOC ## Constructor: new Curtains() ### Description Creates a new Curtains object that handles the scene, WebGL context, canvas creation, and the requestAnimationFrame loop. ### Parameters #### Request Body - **container** (HTML Element or string) - Optional - The HTML Element or ID of the element that will wrap the canvas. - **alpha** (bool) - Optional - Whether the WebGL context should handle transparency. Default: true. - **antialias** (bool) - Optional - Whether the WebGL context should use default antialiasing. Default: true. - **premultipliedAlpha** (bool) - Optional - Whether the WebGL context should handle premultiplied alpha. Default: false. - **depth** (bool) - Optional - Whether the WebGL context should handle depth. Default: true. - **preserveDrawingBuffer** (bool) - Optional - Whether the WebGL context should preserve the drawing buffer. Default: false. - **failIfMajorPerformanceCaveat** (bool) - Optional - Whether the WebGL context creation should fail in case of major performance caveat. Default: true. - **stencil** (bool) - Optional - Whether the WebGL context should handle stencil. Default: false. - **autoRender** (bool) - Optional - Whether the library should create a request animation frame loop. Default: true. - **autoResize** (bool) - Optional - Whether the library should listen to window resize events. Default: true. - **pixelRatio** (float) - Optional - Defines the pixel ratio value. Default: window.devicePixelRatio. - **renderingScale** (float) - Optional - Downscale the rendering canvas (0.25 to 1). Default: 1. - **watchScroll** (bool) - Optional - Whether the library should listen to window scroll events. Default: true. - **production** (bool) - Optional - Whether the library should throw useful console warnings. Default: false. ### Request Example const curtains = new Curtains({ container: "canvas", production: true }); ``` -------------------------------- ### Create a basic ShaderPass Source: https://www.curtainsjs.com/shader-pass-class.html Initialize a ShaderPass applied to the entire scene using the Curtains object. ```javascript // "canvas" is the ID of our HTML container element const curtains = new Curtains({ container: "canvas" }); // create a new shader pass using our curtains object const shaderPass = new ShaderPass(curtains); ``` -------------------------------- ### JavaScript Initialization Source: https://www.curtainsjs.com/get-started.html Initializes the WebGL context and creates a plane with custom uniforms. ```javascript import {Curtains, Plane} from "curtainsjs"; // wait for everything to be ready window.addEventListener("load", () => { // set up our WebGL context and append the canvas to our wrapper const curtains = new Curtains({ container: "canvas" }); // get our plane element const planeElement = document.getElementsByClassName("plane")[0]; // set our initial parameters (basic uniforms) const params = { vertexShaderID: "plane-vs", // our vertex shader ID fragmentShaderID: "plane-fs", // our fragment shader ID uniforms: { time: { name: "uTime", // uniform name that will be passed to our shaders type: "1f", // this means our uniform is a float value: 0, }, }, }; // create our plane using our curtains object, the HTML element and the parameters const plane = new Plane(curtains, planeElement, params); plane.onRender(() => { // use the onRender method of our plane fired at each requestAnimationFrame call plane.uniforms.time.value++; // update our time uniform value }); }); ``` -------------------------------- ### Configure ShaderPass with parameters Source: https://www.curtainsjs.com/shader-pass-class.html Define custom shaders and uniforms for a ShaderPass during initialization. ```javascript // "canvas" is the ID of our HTML container element const curtains = new Curtains({ container: "canvas" }); const shaderPassParams = { vertexShaderID: "my-shader-pass-vs", // ID of your vertex shader script tag fragmentShaderID: "my-shader-pass-fs", // ID of your fragment shader script tag uniforms: { // uniforms are what will allow you to interact with your shader pass time: { name: "uTime", // uniform name that will be passed to our shaders type: "1f", // this means our uniform is a float value: 0, // initial value of the uniform }, }, }; // create a new shader pass using our curtains object and the above parameters var shaderPass = new ShaderPass(curtains, shaderPassParams); ``` -------------------------------- ### Vec3 Class - Basic Usage Source: https://www.curtainsjs.com/vec-3-class.html Demonstrates the creation and basic usage patterns of the Vec3 class, including constructor usage, chaining methods, and setting up an onChange callback for component changes. ```APIDOC ## Vec3 Class - Basic Usage ### Description Vec3 is the class used for all 3 dimensions vector manipulations. ### Creation To create a new Vec3, just use its constructor. If used without parameters, it will create a null vector Vec3 with X, Y and Z components equal to 0. ### Chaining Since most of the Vec3 methods return the vector itself, you can use chaining. ### onChange Callback Vec3 class is using getters and setters, allowing to execute a function each time one of the vector components changes. ### Code Examples ```javascript // create two new Vec3 vectors const nullVector = new Vec3(); const vector = new Vec3(1, 1, 1); // create a new Vec3 vector and chain methods const chainedVector = new Vec3().addScalar(2).normalize(); // create a new Vec3 vector and listen to its changes const observableVector = new Vec3().onChange(() => { // one of the vector component just changed, do something... console.log('Vector component changed!'); }); // this will trigger our onChange callback observableVector.x = 1; // be careful, this will trigger onChange again! observableVector.y = 2; ``` ``` -------------------------------- ### Plane Initialization Parameters Source: https://www.curtainsjs.com/plane-class.html This section outlines the parameters used when creating a new Plane object. These parameters control various aspects of the plane's appearance, behavior, and rendering. ```APIDOC ## POST /api/planes ### Description Initializes a new Plane object with specified parameters. ### Method POST ### Endpoint /api/planes ### Parameters #### Request Body - **curtains** (object) - Required - Your Curtains class object. - **planeElement** (HTMLElement) - Required - The HTML element to be used for the plane. - **params** (object) - Optional - An object containing various parameters for the plane: - **vertexShader** (string) - Optional - Your custom vertex shader code. - **vertexShaderID** (string) - Optional - The ID of a predefined vertex shader. - **fragmentShader** (string) - Optional - Your custom fragment shader code. - **fragmentShaderID** (string) - Optional - The ID of a predefined fragment shader. - **widthSegments** (integer) - Optional - The number of segments along the X axis (default: 1). - **heightSegments** (integer) - Optional - The number of segments along the Y axis (default: 1). - **renderOrder** (int) - Optional - The rendering order of the plane (default: 0). - **depthTest** (boolean) - Optional - Enables or disables depth testing (default: true). - **transparent** (boolean) - Optional - Handles plane transparency for rendering order (default: false). - **cullFace** (string) - Optional - Which face of the plane to cull ('back', 'front', or 'none') (default: 'back'). - **alwaysDraw** (boolean) - Optional - Whether to always draw the plane, bypassing frustum culling (default: false). - **visible** (boolean) - Optional - Whether the plane should be drawn (default: true). - **drawCheckMargins** (object) - Optional - Additional margins for draw check calculations: - **top** (float) - Margin for the top side (default: 0). - **right** (float) - Margin for the right side (default: 0). - **bottom** (float) - Margin for the bottom side (default: 0). - **left** (float) - Margin for the left side (default: 0). - **watchScroll** (boolean) - Optional - Auto-update plane position on scroll (default: false). - **autoloadSources** (boolean) - Optional - Automatically load sources on initialization (default: true). - **texturesOptions** (object) - Optional - Default options for plane textures. - **crossOrigin** (string) - Optional - Cross-origin setting for texture loading (default: 'anonymous'). - **fov** (integer) - Optional - Field of view for perspective (default: 50). - **uniforms** (object) - Optional - Uniforms to pass to the shaders: - **name** (string) - Required - The name of the uniform. - **type** (string) - Required - The type of the uniform. - **value** (any) - Required - The value of the uniform (type depends on uniform type). ### Request Example ```json { "curtains": "yourCurtainsObject", "planeElement": "yourHTMLElement", "params": { "vertexShader": "\n void main() {\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ", "fragmentShader": "\n void main() {\n gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n }\n ", "widthSegments": 10, "heightSegments": 10, "uniforms": [ { "name": "uTime", "type": "1f", "value": 0.0 } ] } } ``` ### Response #### Success Response (200) - **plane** (object) - The newly created Plane object. #### Response Example ```json { "plane": "yourCreatedPlaneObject" } ``` ``` -------------------------------- ### Initialize CurtainsJS and Create a Plane Source: https://www.curtainsjs.com/get-started.html Sets up the WebGL context, creates a plane element, and defines basic shader parameters with an animated time uniform. Handles canvas texture animation by drawing a rotating rectangle. ```javascript import {Curtains, Plane} from "curtainsjs"; // wait for everything to be ready window.addEventListener("load", () => { // set up our WebGL context and append the canvas to our wrapper const curtains = new Curtains({ container: "canvas" }); // get our plane element const planeElement = document.getElementsByClassName("plane")[0]; // set our initial parameters (basic uniforms) const params = { vertexShaderID: "plane-vs", // our vertex shader ID fragmentShaderID: "plane-fs", // our fragment shader ID uniforms: { time: { name: "uTime", // uniform name that will be passed to our shaders type: "1f", // this means our uniform is a float value: 0, }, }, }; // create our plane using our curtains object, the HTML element and the parameters const plane = new Plane(curtains, planeElement, params); // our texture canvas const textureCanvas = document.getElementById("canvas-texture"); const textureCanvasContext = textureCanvas.getContext("2d"); // get our plane dimensions without triggering reflow const planeBoundingRect = plane.getBoundingRect(); // set the size of our canvas textureCanvas.width = planeBoundingRect.width; textureCanvas.height = planeBoundingRect.height; // use the onRender method of our plane fired at each requestAnimationFrame call plane.onRender(() => { plane.uniforms.time.value++; // update our time uniform value // here we will handle our canvas texture animation // clear scene textureCanvasContext.clearRect(0, 0, textureCanvas.width, textureCanvas.height); // continuously rotate the canvas textureCanvasContext.translate(textureCanvas.width / 2, textureCanvas.height / 2); textureCanvasContext.rotate(Math.PI / 360); textureCanvasContext.translate(-textureCanvas.width / 2, -textureCanvas.height / 2); // draw a red rectangle textureCanvasContext.fillStyle = "#ff0000"; textureCanvasContext.fillRect(textureCanvas.width / 2 - textureCanvas.width / 8, textureCanvas.height / 2 - textureCanvas.height / 8, textureCanvas.width / 4, textureCanvas.height / 4); }); }); ``` -------------------------------- ### Create and Use TextureLoader Source: https://www.curtainsjs.com/texture-loader-class.html Instantiate a TextureLoader with a Curtains object and use its loadImage method to load an image. Provide a callback for success and another for errors. The texture options allow setting properties like the sampler name. ```javascript const curtains = new Curtains({ container: "canvas" }); // create a new texture loader const loader = new TextureLoader(curtains); // load an image with the loader const image = new Image(); image.crossOrigin = "anonymous"; image.src = "path/to/my-image.jpg"; loader.loadImage(image, { // texture options (we're only setting its sampler name here) sampler: "uTexture" }, (texture) => { // texture has been successfully created, you can safely use it }, (image, error) => { // there has been an error while loading the image }); ``` -------------------------------- ### HTML for Multiple Textures (Image and Videos) Source: https://www.curtainsjs.com/get-started.html Combine images and videos as textures by assigning them different 'data-sampler' attributes for distinct uniform names in shaders. ```html