There are some options to use Shaders with javascript/typescript.
I just saw an npm package that allows me to use fragment shader easily.
I'm using typescript
, but in this case I don't really use ts lol.
Install
npm i -S react-vfx
Usage
REACT-VFX exports VFXSpan
, VFXImg
and VFXVideo
These components works just like <span>
, <img>
and <video>
- accepts all properties they have, but they are rendered in WebGL world with shader effects!
import * as VFX from 'react-vfx';
export default () => (
<VFX.VFXProvider>
{/* Render text as image, then apply the shader effect! */}
<VFX.VFXSpan shader="rainbow">Hi there!</VFX.VFXSpan>
{/* 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
…In this post, I will show you how to use react-vfx for displaying FragmentShaders
.
Steps
Step1. Create a new react app by create-react-app
Step2. Install react-vfx
Step3. Create a new component for FragmentShader
Step4. Run the app
Step1 Create react app
In this case, we will use create-react-app
. If you have a template, you can use it.
Here is one thing you should know about create-react-app
If you've previously installed create-react-app globally via npm install -g create-react-app, we recommend you uninstall the package using npm uninstall -g create-react-app to ensure that npx always uses the latest version.
Global installs of create-react-app are no longer supported.
If you install react-create-app
globally, I recommend you to uninstall it since it may prevent you to create a new react app(Actually my case didn't create an app properly just generate package.json and a couple of files)
$ npx create-react-app myshader --template typescript
# or I used yarn since I have switched a package manager from npm to yarn
$ yarn create react-app myshader --template typescript
If you don't want to use Typescript
try the following.
$ npx create-react-app myshader
# or
$ yarn create react-app myshader
This isn't necessary, but I prefer to run before adding a component.
$ yarn start
Step2 Install react-vfx
# using styled-components
$ yarn add react-vfx styled-components
$ yarn add -D @types/styled-components <-- if you use typescript
# or
$ npm install react-vfx styled-components
$ npm install -D @types/styled-components <-- if you use typescript
Step3 Create component
In this case, I created a new file, MyShader.tsx under src
. If you are using js, the file's extension should be .jsx
import React from "react";
import * as VFX from "react-vfx";
import styled from "styled-components";
const Content = styled.div`
width: 100vw;
height: 100vh;
`;
const metal = `
uniform vec2 resolution;
uniform float time;
void main()
{
vec2 coord = gl_FragCoord.xy / resolution.xy;
vec2 st = coord;
vec3 line = vec3(0.0);
coord *= 4.;
float len;
for (int i = 0; i < 15; i++) {
len = length(vec2(coord.x, coord.y));
coord.x += cos(coord.y + sin(len)) + cos(time * .07) * 0.2;
coord.y += sin(coord.x + cos(len)) + sin(time * 0.1);
}
len *= cos(len * 0.4);
len -= 10.;
for (float i = 0.0; i < 5.0; i++) {
len += 0.11 / abs(mod(st.x, 1.09 * i) * 200.) * 1.;
}
vec3 color = vec3(cos(len + 0.2) * 1.15, cos(len + 0.1), cos(len - 0.05));
gl_FragColor = vec4(color, 1.0);
}
`;
const MyShader: React.FC = () => {
return (
<>
<VFX.VFXProvider>
<VFX.VFXSpan shader={metal}>
<Content></Content>
</VFX.VFXSpan>
</VFX.VFXProvider>
</>
);
}
export default MyShader;
As you can see the code is very simple except Fragment shader.
Import packages and create a styled tag, Content and write a Fragment Shader, metal
. Then add react-vfx
.
Actually, I tried the following. But it didn't render the content properly. Haven't checked the exact issue lol.
const MyShader: React.FC = () => {
return (
<>
<VFX.VFXProvider>
<VFX.VFXSpan shader={metal}>
</VFX.VFXSpan>
</VFX.VFXProvider>
</>
);
}
Step4 Run app
$ yarn start
If everything works well, you will see the following. (Actually, what you will see is an animation.)
I use threejs to use fragment shader which is pretty good since threejs has nice samples so I just need to modify shader part and threejs input's part. However, with typescript
the setup is a little bit troublesome to me. But, react-vfx
is very handy since it is written in typescript
so I don't need to install any @type file for it. I will use this for updating my portfolio site.
I pushed my sample code.
https://github.com/koji/typescript/tree/master/shadereact
Also, you can find out some nice samples on the creator's site.
https://amagi.dev/react-vfx/
Top comments (0)