GITHUB
API
GITHUB
API

VFX-JS is a JavaScript library to add WebGL-powered effects to your website.
You can easily attach it to normal <img>, <video> elements etc.

Usage

Install via npm:

npm i @vfx-js/core

Then create VFX object in your script:


import { VFX } from '@vfx-js/core';

const img = document.querySelector('#img');

const vfx = new VFX();
vfx.add(img, { shader: "glitch", overflow: 100 });
            

This will be rendered as follows:

VFX-JS is also available on CDNs (esm.sh or jsDeliver). So you can use VFX-JS in CodePen etc:


// Load VFX-JS from esm.sh
import { VFX } from "https://esm.sh/@vfx-js/core";

// or jsDeliver
// import { VFX } from 'https://cdn.jsdelivr.net/npm/@vfx-js/core/+esm'

// Then use VFX-JS
const vfx = new VFX();
vfx.add(img { shader: 'rgbShift' });
            

Examples

Image


<img src="example.png" />
                    

vfx.add(img, { shader: "rgbShift" });
                    

Output

GIF


<img src="example.gif" />
                    

vfx.add(gif, { shader: "rainbow" });
                    

Output

Video


<video src="example.mp4" autoplay loop muted/>
                    

vfx.add(video, { shader: "halftone" });
                    

Output:

Div (experimental)


<div id="div">
    <p>You can interact with these inputs.</p>
    <input type="text" value="Edit me" />
    <input type="range" min="0" max="100" value="0" />
    <textarea>Edit me</textarea>
</div>
                        

vfx.add(div, { shader: "rgbShift", overflow: 100 });

// Update on input
input.addEventListener('input', () => vfx.update(div));

// Update on textarea resize
const mo = new MutationObserver(() => vfx.update(div));
mo.observe(textarea, { attributes: true });

                    

Output:

You can interact with these inputs.

Canvas


<!--
  VFX-JS also supports HTMLCanvasElement as the input.
  You can draw 2D graphics and text in canvas,
  then pass it to VFX-JS to add post effects.
-->
<canvas id="canvas"/>
                        

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

function drawCanvas() {
    ...

    // Update texture when the canvas has been updated
    vfx.update(canvas);

    requestAnimationFrame(drawCanvas);
}
drawCanvas();

vfx.add(canvas, { shader });
                    

Output:

Presets


vfx.add(el, { shader: "rainbow" });
                    

vfx.add(el, { shader: "rgbShift" });
                        

// Some shaders require "overflow" property
// so that they can render beyond the original area.
//
// In this example, the "glitch" shader can render
// outside the original element up to 100px.
vfx.add(el, { shader: "glitch", overflow: 100 });
                        

Parameters

Some shaders take parameters (e.g. duotone). You can pass the params to the uniforms property.


vfx.add(el, {
    shader: "duotone",
    uniforms: {
        color1: [0, 0, 1, 1],
        color2: [0, 1, 0, 1],
        speed: 0.2
    }
});
                        

Transitions

VFX-JS presets for transition animation. These animation start when the element gets in the viewport.


vfx.add(el, { shader: "slitScanTransition" });
                        

vfx.add(el, { shader: "warpTransition" });
                        

vfx.add(el, { shader: "pixelateTransition" });
                        

vfx.add(el, { shader: "focusTransition" });
                        

Custom Shaders

You can write GLSL shader by yourself.


const shader = `
precision highp float;
uniform vec2 resolution;
uniform vec2 offset;
uniform float time;
uniform sampler2D src;
uniform float scroll;
out vec4 outColor;

void main (void) {
    vec2 uv = (gl_FragCoord.xy - offset) / resolution;

    // Scroll X
    uv.x = fract(uv.x + scroll + time * 0.2);

    outColor = texture2D(src, uv);
}
`;

vfx.add(el, {
    shader,
    uniforms: {
        // Uniform functions are evaluated every frame
        scroll: () => window.scrollY / window.innerHeight,
    }
});
                        

Made by Amagi