Questions tagged [curtains.js]

curtains.js is a small vanilla WebGL javascript library that converts HTML elements containing images and videos into 3D WebGL textured planes, allowing you to animate them via shaders. You can define each plane size and position via CSS, add post processing, etc.

It was created by Martin Laxenaire and is released under the MIT license.

Basic example

<html> 
  <head> 
    <title>curtains.js basic example</title> 
    <style>
      body {
        /* make the body fits our viewport */
        position: relative;
        width: 100%;
        height: 100vh;
        margin: 0;
        overflow: hidden;
      }
      #canvas {
        /* make the canvas wrapper fits the document */
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
      }
      .plane {
        /* define the size of your plane */
        width: 80%;
        height: 80vh;
        margin: 10vh auto;
      }
      .plane img {
        /* hide the img element */
        display: none;
      }
    </style> 
  </head> 
  <body> 
    <!-- div that will hold our WebGL canvas -->
    <div id="canvas"></div>
    <!-- div used to create our plane -->
    <div class="plane">
      <!-- image that will be used as texture by our plane -->
      <img src="path/to/my-image.jpg" />
    </div>

    <script src="curtains.umd.min.js"></script> 
    <script> 
      const vertexShader = `
        #ifdef GL_ES
        precision mediump float;
        #endif

        // those are the mandatory attributes that the lib sets
        attribute vec3 aVertexPosition;
        attribute vec2 aTextureCoord;

        // those are mandatory uniforms that the lib sets and that contain our model view and projection matrix
        uniform mat4 uMVMatrix;
        uniform mat4 uPMatrix;

        // our texture matrix that will handle image cover
        uniform mat4 uTextureMatrix0;

        // pass your vertex and texture coords to the fragment shader
        varying vec3 vVertexPosition;
        varying vec2 vTextureCoord;

        void main() {       
          gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    
          // set the varyings
          // here we use our texture matrix to calculate the accurate texture coords
          vTextureCoord = (uTextureMatrix0 * vec4(aTextureCoord, 0.0, 1.0)).xy;
          vVertexPosition = aVertexPosition;
        }
      `;

       const fragmentShader = `
        #ifdef GL_ES
        precision mediump float;
        #endif

        // get our varyings
        varying vec3 vVertexPosition;
        varying vec2 vTextureCoord;

        // the uniform we declared inside our javascript
        uniform float uTime;

        // our texture sampler (default name, to use a different name please refer to the documentation)
        uniform sampler2D uSampler0;

        void main() {
          // get our texture coords from our varying
          vec2 textureCoord = vTextureCoord;
    
          // displace our pixels along the X axis based on our time uniform
          // textures coords are ranging from 0.0 to 1.0 on both axis
          textureCoord.x += sin(textureCoord.y * 25.0) * cos(textureCoord.x * 25.0) * (cos(uTime / 50.0)) / 25.0;
    
          // map our texture with the texture matrix coords
          gl_FragColor = texture2D(uSampler0, textureCoord);
        }
      `;

      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.querySelector(".plane");

        // set our initial parameters (basic uniforms)
        const params = {
          vertexShader: vertexShader, // our vertex shader
          fragmentShader: fragmentShader, // our fragment shader
          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 bound 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
        });
      });
    </script> 
  </body> 
</html>

Useful links

17 questions
0
votes
1 answer

Parallax effect curtains.js scroll

I am uising curtains.js from github asa a parallax effect but I want to change animation effect. When I am scrolling current element goes up but I want next elements to come above current does anyone have some ideas how to do that Thanks
Andrew Ceban
  • 118
  • 15
0
votes
1 answer

JavaScript Preventing User Text Selection

Something in this Curtains.js plug-in is preventing user text selection on my page. When I comment it out, I'm able to select text, when I put it back in, I'm not. Can someone identify it and tell me how to fix it? I'm at my wit's end.