diff --git a/examples/radial-waves/frag.glsl b/examples/radial-waves/frag.glsl new file mode 100644 index 0000000..5296419 --- /dev/null +++ b/examples/radial-waves/frag.glsl @@ -0,0 +1,16 @@ +precision lowp float; + +varying vec2 vPosition; /* pixel position, X & Y in [-1, +1] */ +uniform vec4 uColor; /* injected from JS */ +uniform float uTime; /* time in seconds since canvas loaded */ + +// Animation code +void main() { + float theta = atan(vPosition.y, vPosition.x); + float rho = length(vPosition.xy); + float v = mod(rho - uTime/10., .2); + float alpha = smoothstep(.1, .2, v); + alpha *= 1. - smoothstep(0., 1., rho); + float fadeIn = smoothstep(0., 1., uTime); + gl_FragColor = fadeIn * alpha * uColor; +} diff --git a/examples/radial-waves/index.ts b/examples/radial-waves/index.ts new file mode 100644 index 0000000..4e2224d --- /dev/null +++ b/examples/radial-waves/index.ts @@ -0,0 +1,12 @@ +import { animate, getComputedStylePropRGBA } from "quad-shader"; +import frag from "./frag.glsl?raw" // PROC: REMOVE +const canvas = document.querySelector("#glcanvas-radial-waves") as HTMLCanvasElement; // PROC: REMOVE +const qs = animate( + canvas, /* the HTMLCanvasElement to draw on */ + frag, /* fragment shader, as a string */ +); + +/* register a callback that updates "uColor" on render */ +/* 'getComputedStylePropRGBA' is a helper that returns the */ +/* given CSS property as a RGBA value */ +qs.uniform4f("uColor", () => getComputedStylePropRGBA(canvas, "accent-color")); // PROC: REPLACE "accent-color" "color" diff --git a/index.html b/index.html index 12ccd7e..7e41ce7 100644 --- a/index.html +++ b/index.html @@ -52,55 +52,34 @@

Easy 2D shader setup with quad-shader

Getting started with quad-shader

-

Let's take the following animation as an example:

+

+ We'll go through the steps required for displaying the following + animation: +

- +
-

- First install quad-shader with - npm install quad-shader. -

+

First install quad-shader:

-

- After having installed the library, all it takes is (literally) three - lines of JavaScript and a fairly short fragment shader, inlined as a - string here for simplicity: -

+

npm install quad-shader

- +

Then include the following code in your page:

+ +

- Assuming you have a canvas element on the page, you should - see the animation. Congrats! + The canvas should be an HTMLCanvasElement. The + frag should be a string with the following content:

+

+ +

You should now see the animation on your page!

+

Passing inputs as uniforms

@@ -192,34 +171,32 @@

Passing inputs as uniforms

+ + diff --git a/index.ts b/index.ts index a1b2696..ea50e6d 100644 --- a/index.ts +++ b/index.ts @@ -61,3 +61,36 @@ export function main() { t = performance.now() / 1000; }); } + +/* + Example source processing: + + `// PROC: REMOVE` -> line is removed + `// PROC: REPLACE "foo" "bar"` -> "foo" is replaced with "bar" in line +*/ + +const RE_REMOVE = new RegExp("\\s*//\\s*PROC:\\s*REMOVE\\s*$"); + +const RE_REPLACE = new RegExp( + "\\s*//\\s*PROC:\\s*REPLACE\\s+(\"|')(?.*?)\\1\\s+(\"|')(?.*?)\\3\\s*$", +); + +export const processLines = (multiline: string): string => { + return multiline + .split("\n") + .map((line: string) => { + if (RE_REMOVE.test(line)) return null; // filter out "REMOVE" lines + + const m = line.match(RE_REPLACE); // perform substitution for "REPLACE" lines + if (m) { + const { from, to } = m.groups!; + // keep only the code part, strip the directive (comment) + const body = line.slice(0, m.index); + return body.replace(from, to); + } + + return line; + }) + .filter(Boolean) // drop removed lines + .join("\n"); +}; diff --git a/tsconfig.json b/tsconfig.json index 5e84997..9e35b9f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,7 +18,12 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true + "noFallthroughCasesInSwitch": true, + + "paths": { + "quad-shader": ["./src"] + + } }, - "include": ["src", "index.ts", "types.d.ts"] + "include": ["src", "index.ts", "types.d.ts", "examples"] }