@vfx-js/react
v1.1.0
Published
WebGL effects for React elements
Readme
Install
npm i @vfx-js/reactUsage
@vfx-js/react exports VFXImg, VFXVideo, VFXSpan and VFXDiv.
These components works just like <img>, <video>, <span> and <div> - accepts all properties they have, but they are rendered in WebGL world with shader effects!
import * as VFX from '@vfx-js/react';
export default () => (
<VFX.VFXProvider>
{/* Render image with shader */}
<VFX.VFXImg src="cat.png" alt="image" shader="rgbShift"/>
{/* It also supports animated GIFs! */}
<VFX.VFXImg src="doge.gif" shader="pixelate"/>
{/* and videos! */}
<VFX.VFXVideo src="mind_blown.mp4"
autoplay playsinline loop muted
shader="halftone"/>
{/* Render text as image, then apply the shader effect! */}
<VFX.VFXSpan shader="rainbow">Hi there!</VFX.VFXSpan>
{/* Or even inputs! */}
<VFX.VFXDiv shader="rainbow">
<input type="text" value="hello" />
</VFX.VFXDiv>
</VFX.VFXProvider>
);NOTE: VFXSpan doesn't work if the content includes child nodes.
// OK
<a href="https://example.com"><VFXSpan>Yo</VFXSpan></a>
// NG: link styles are not rendered correctly
<VFXSpan><a href="https://example.com">Yo</a></VFXSpan>Effect API
Pass a prebuilt Effect instance (or array) from @vfx-js/effects via the effect prop:
import * as VFX from '@vfx-js/react';
import { BloomEffect, PixelateEffect } from '@vfx-js/effects';
export default () => (
<VFX.VFXProvider>
<VFX.VFXImg src="cat.png" effect={new BloomEffect({ intensity: 5 })}/>
<VFX.VFXImg src="doge.gif" effect={[
new PixelateEffect({ size: 10 }),
new BloomEffect({ intensity: 8 }),
]}/>
</VFX.VFXProvider>
);When only the effect prop changes between renders, the chain is swapped in-place without re-uploading the source texture or re-initializing effects whose reference is unchanged.
Custom Shader
import { VFXSpan } from '@vfx-js/react';
const blink = `
uniform vec2 resolution;
uniform vec2 offset;
uniform float time;
uniform sampler2D src;
out vec4 outColor;
void main() {
vec2 uv = (gl_FragCoord.xy - offset) / resolution;
outColor = texture2D(src, uv) * step(.5, fract(time));
}
`;
export default = () => (
<VFXSpan shader={blink}></VFXSpan>
);Future work
- Passing custom uniforms
- Passing custom textures
Author
LICENSE
MIT
