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.
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' });
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:
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 });
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
}
});
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" });
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,
}
});