@frapx/shader 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -0
- package/dist/chunk-MPWD3FIT.js +37 -0
- package/dist/chunk-MPWD3FIT.js.map +1 -0
- package/dist/color.d.ts +6 -0
- package/dist/color.js +9 -0
- package/dist/color.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +144 -36
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -40,6 +40,46 @@ fx.setUniform("progress", 0.4);
|
|
|
40
40
|
// GLSL: uniform float u_progress;
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
This naming rule also applies to initial custom uniforms:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
createShaderBackground({
|
|
47
|
+
target: ".hero",
|
|
48
|
+
fragment,
|
|
49
|
+
uniforms: {
|
|
50
|
+
progress: 0
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The shader must declare `uniform float u_progress;`, not `uniform float progress;`.
|
|
56
|
+
Uniforms set before `ready` are cached and applied on the first render.
|
|
57
|
+
|
|
58
|
+
## Color Uniforms
|
|
59
|
+
|
|
60
|
+
Use `hexToRgb()` and `hexToRgba()` to convert hex colors into `vec3` and `vec4` uniform values.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { createShaderBackground, glsl, hexToRgb, hexToRgba } from "@frapx/shader";
|
|
64
|
+
|
|
65
|
+
const fx = createShaderBackground({
|
|
66
|
+
target: ".hero",
|
|
67
|
+
fragment,
|
|
68
|
+
uniforms: {
|
|
69
|
+
baseColor: hexToRgb("#7dd3fc"),
|
|
70
|
+
overlayColor: hexToRgba("#0f172acc")
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```glsl
|
|
76
|
+
uniform vec3 u_baseColor;
|
|
77
|
+
uniform vec4 u_overlayColor;
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The helpers support `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`, and the same forms without `#`.
|
|
81
|
+
The returned values are sRGB channels normalized to `0..1`. Invalid hex values throw an `Error`.
|
|
82
|
+
|
|
43
83
|
## Textures
|
|
44
84
|
|
|
45
85
|
```ts
|
|
@@ -67,6 +107,23 @@ uniform vec2 u_imageSize;
|
|
|
67
107
|
|
|
68
108
|
Supported v1 sources are image URL, `HTMLImageElement`, and `HTMLCanvasElement`.
|
|
69
109
|
|
|
110
|
+
Textures can be updated at runtime. Updates are async because URL sources must
|
|
111
|
+
load before they can be uploaded to WebGL.
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
await fx.setTexture("image", "/next-hero.webp");
|
|
115
|
+
|
|
116
|
+
await fx.setTextures({
|
|
117
|
+
image: "/next-hero.webp",
|
|
118
|
+
mask: nextMaskCanvas
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`setTextures()` is a partial update: omitted texture names are left unchanged.
|
|
123
|
+
If a runtime texture update fails, the previous texture remains active and the
|
|
124
|
+
returned promise rejects. In `"demand"` render mode, successful texture updates
|
|
125
|
+
request a render.
|
|
126
|
+
|
|
70
127
|
## External Uniforms
|
|
71
128
|
|
|
72
129
|
Scroll is intentionally not built in. Use any scroll or animation library and push values into uniforms.
|
|
@@ -154,6 +211,8 @@ fx.stop();
|
|
|
154
211
|
fx.render();
|
|
155
212
|
fx.resize();
|
|
156
213
|
fx.destroy();
|
|
214
|
+
await fx.setTexture("image", "/next-hero.webp");
|
|
215
|
+
await fx.setTextures({ image: "/next-hero.webp" });
|
|
157
216
|
fx.setUniform("progress", 0.5);
|
|
158
217
|
fx.setUniforms({ progress: 0.5, color: [1, 0, 0] });
|
|
159
218
|
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// src/color.ts
|
|
2
|
+
var hexToRgb = (hex) => {
|
|
3
|
+
const value = normalizeHex(hex);
|
|
4
|
+
return [
|
|
5
|
+
parseChannel(value.slice(0, 2)),
|
|
6
|
+
parseChannel(value.slice(2, 4)),
|
|
7
|
+
parseChannel(value.slice(4, 6))
|
|
8
|
+
];
|
|
9
|
+
};
|
|
10
|
+
var hexToRgba = (hex) => {
|
|
11
|
+
const value = normalizeHex(hex);
|
|
12
|
+
return [
|
|
13
|
+
parseChannel(value.slice(0, 2)),
|
|
14
|
+
parseChannel(value.slice(2, 4)),
|
|
15
|
+
parseChannel(value.slice(4, 6)),
|
|
16
|
+
value.length === 8 ? parseChannel(value.slice(6, 8)) : 1
|
|
17
|
+
];
|
|
18
|
+
};
|
|
19
|
+
var normalizeHex = (hex) => {
|
|
20
|
+
const value = hex.startsWith("#") ? hex.slice(1) : hex;
|
|
21
|
+
if (!/^(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(
|
|
22
|
+
value
|
|
23
|
+
)) {
|
|
24
|
+
throw new Error(`Invalid hex color: ${hex}`);
|
|
25
|
+
}
|
|
26
|
+
if (value.length === 3 || value.length === 4) {
|
|
27
|
+
return Array.from(value, (char) => `${char}${char}`).join("");
|
|
28
|
+
}
|
|
29
|
+
return value;
|
|
30
|
+
};
|
|
31
|
+
var parseChannel = (hex) => Number.parseInt(hex, 16) / 255;
|
|
32
|
+
|
|
33
|
+
export {
|
|
34
|
+
hexToRgb,
|
|
35
|
+
hexToRgba
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=chunk-MPWD3FIT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/color.ts"],"sourcesContent":["export type Rgb = [number, number, number];\nexport type Rgba = [number, number, number, number];\n\nexport const hexToRgb = (hex: string): Rgb => {\n const value = normalizeHex(hex);\n return [\n parseChannel(value.slice(0, 2)),\n parseChannel(value.slice(2, 4)),\n parseChannel(value.slice(4, 6)),\n ];\n};\n\nexport const hexToRgba = (hex: string): Rgba => {\n const value = normalizeHex(hex);\n return [\n parseChannel(value.slice(0, 2)),\n parseChannel(value.slice(2, 4)),\n parseChannel(value.slice(4, 6)),\n value.length === 8 ? parseChannel(value.slice(6, 8)) : 1,\n ];\n};\n\nconst normalizeHex = (hex: string): string => {\n const value = hex.startsWith(\"#\") ? hex.slice(1) : hex;\n\n if (\n !/^(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(\n value,\n )\n ) {\n throw new Error(`Invalid hex color: ${hex}`);\n }\n\n if (value.length === 3 || value.length === 4) {\n return Array.from(value, (char) => `${char}${char}`).join(\"\");\n }\n\n return value;\n};\n\nconst parseChannel = (hex: string): number => Number.parseInt(hex, 16) / 255;\n"],"mappings":";AAGO,IAAM,WAAW,CAAC,QAAqB;AAC5C,QAAM,QAAQ,aAAa,GAAG;AAC9B,SAAO;AAAA,IACL,aAAa,MAAM,MAAM,GAAG,CAAC,CAAC;AAAA,IAC9B,aAAa,MAAM,MAAM,GAAG,CAAC,CAAC;AAAA,IAC9B,aAAa,MAAM,MAAM,GAAG,CAAC,CAAC;AAAA,EAChC;AACF;AAEO,IAAM,YAAY,CAAC,QAAsB;AAC9C,QAAM,QAAQ,aAAa,GAAG;AAC9B,SAAO;AAAA,IACL,aAAa,MAAM,MAAM,GAAG,CAAC,CAAC;AAAA,IAC9B,aAAa,MAAM,MAAM,GAAG,CAAC,CAAC;AAAA,IAC9B,aAAa,MAAM,MAAM,GAAG,CAAC,CAAC;AAAA,IAC9B,MAAM,WAAW,IAAI,aAAa,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI;AAAA,EACzD;AACF;AAEA,IAAM,eAAe,CAAC,QAAwB;AAC5C,QAAM,QAAQ,IAAI,WAAW,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI;AAEnD,MACE,CAAC,oEAAoE;AAAA,IACnE;AAAA,EACF,GACA;AACA,UAAM,IAAI,MAAM,sBAAsB,GAAG,EAAE;AAAA,EAC7C;AAEA,MAAI,MAAM,WAAW,KAAK,MAAM,WAAW,GAAG;AAC5C,WAAO,MAAM,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,EAAE,EAAE,KAAK,EAAE;AAAA,EAC9D;AAEA,SAAO;AACT;AAEA,IAAM,eAAe,CAAC,QAAwB,OAAO,SAAS,KAAK,EAAE,IAAI;","names":[]}
|
package/dist/color.d.ts
ADDED
package/dist/color.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { Rgb, Rgba, hexToRgb, hexToRgba } from './color.js';
|
|
1
2
|
export { glsl, glslUtils } from './glsl.js';
|
|
2
3
|
|
|
3
4
|
type ShaderLayer = "background" | "overlay";
|
|
@@ -71,6 +72,8 @@ type ShaderBackgroundInstance<TUniforms extends UniformInputMap = UniformInputMa
|
|
|
71
72
|
render(): void;
|
|
72
73
|
resize(): void;
|
|
73
74
|
destroy(): void;
|
|
75
|
+
setTexture(name: string, input: TextureInput): Promise<void>;
|
|
76
|
+
setTextures(values: TextureMap): Promise<void>;
|
|
74
77
|
setUniform<K extends keyof TUniforms & string>(name: K, value: UniformRuntimeValue<TUniforms[K]>): void;
|
|
75
78
|
setUniform(name: string, value: UniformInput): void;
|
|
76
79
|
setUniforms(values: Record<string, UniformInput>): void;
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hexToRgb,
|
|
3
|
+
hexToRgba
|
|
4
|
+
} from "./chunk-MPWD3FIT.js";
|
|
1
5
|
import {
|
|
2
6
|
glsl,
|
|
3
7
|
glslUtils
|
|
@@ -91,16 +95,6 @@ var applyCanvasStyle = (canvas, options, shouldPosition) => {
|
|
|
91
95
|
var toUniformName = (name) => name.startsWith("u_") ? name : `u_${name}`;
|
|
92
96
|
|
|
93
97
|
// src/internal/textures.ts
|
|
94
|
-
var loadTextures = async (gl, textures, isDestroyed) => {
|
|
95
|
-
const entries = Object.entries(textures ?? {});
|
|
96
|
-
const loaded = [];
|
|
97
|
-
for (let index = 0; index < entries.length; index += 1) {
|
|
98
|
-
if (isDestroyed()) break;
|
|
99
|
-
const [name, input] = entries[index];
|
|
100
|
-
loaded.push(await loadTexture(gl, name, input, index));
|
|
101
|
-
}
|
|
102
|
-
return loaded;
|
|
103
|
-
};
|
|
104
98
|
var loadTexture = async (gl, name, input, unit) => {
|
|
105
99
|
const options = normalizeTextureInput(input);
|
|
106
100
|
const source = await resolveSource(options.source);
|
|
@@ -208,6 +202,10 @@ var applyUniform = (gl, location, uniform) => {
|
|
|
208
202
|
break;
|
|
209
203
|
}
|
|
210
204
|
};
|
|
205
|
+
var applyProgramUniform = (gl, program, location, uniform) => {
|
|
206
|
+
gl.useProgram(program);
|
|
207
|
+
applyUniform(gl, location, uniform);
|
|
208
|
+
};
|
|
211
209
|
var collectUniformLocations = (gl, program) => {
|
|
212
210
|
const locations = /* @__PURE__ */ new Map();
|
|
213
211
|
const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
|
|
@@ -311,8 +309,12 @@ var ShaderBackground = class {
|
|
|
311
309
|
this.dom = null;
|
|
312
310
|
this.program = null;
|
|
313
311
|
this.buffer = null;
|
|
312
|
+
this.attribLocation = -1;
|
|
314
313
|
this.uniformLocations = /* @__PURE__ */ new Map();
|
|
315
|
-
this.
|
|
314
|
+
this.textureInputs = /* @__PURE__ */ new Map();
|
|
315
|
+
this.textures = /* @__PURE__ */ new Map();
|
|
316
|
+
this.textureUnits = /* @__PURE__ */ new Map();
|
|
317
|
+
this.textureVersions = /* @__PURE__ */ new Map();
|
|
316
318
|
this.resizeObserver = null;
|
|
317
319
|
this.intersectionObserver = null;
|
|
318
320
|
this.rafId = 0;
|
|
@@ -384,15 +386,14 @@ var ShaderBackground = class {
|
|
|
384
386
|
if (!gl) return;
|
|
385
387
|
this.inRender = true;
|
|
386
388
|
this.resize();
|
|
389
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
387
390
|
gl.viewport(0, 0, this.width, this.height);
|
|
388
391
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
389
392
|
gl.useProgram(this.program);
|
|
390
393
|
this.applyBuiltInUniforms(gl);
|
|
391
|
-
this.applyCachedUniforms(gl);
|
|
392
|
-
this.applyTextures(gl);
|
|
393
394
|
const state = this.createRenderState(gl);
|
|
394
395
|
this.options.onBeforeRender?.(state);
|
|
395
|
-
this.
|
|
396
|
+
this.prepareDrawState(gl);
|
|
396
397
|
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
397
398
|
this.options.onAfterRender?.(state);
|
|
398
399
|
this.frame += 1;
|
|
@@ -425,7 +426,9 @@ var ShaderBackground = class {
|
|
|
425
426
|
this.removeListeners = [];
|
|
426
427
|
const gl = this.dom?.canvas.getContext("webgl");
|
|
427
428
|
if (gl) {
|
|
428
|
-
for (const texture of this.textures
|
|
429
|
+
for (const texture of this.textures.values()) {
|
|
430
|
+
gl.deleteTexture(texture.texture);
|
|
431
|
+
}
|
|
429
432
|
if (this.buffer) gl.deleteBuffer(this.buffer);
|
|
430
433
|
if (this.program) gl.deleteProgram(this.program);
|
|
431
434
|
}
|
|
@@ -446,9 +449,14 @@ var ShaderBackground = class {
|
|
|
446
449
|
this.uniformCache.set(uniformName, normalizeUniform(value));
|
|
447
450
|
const gl = this.dom?.canvas.getContext("webgl");
|
|
448
451
|
const location = this.uniformLocations.get(uniformName);
|
|
449
|
-
if (gl && location) {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
+
if (gl && this.program && location) {
|
|
453
|
+
applyProgramUniform(
|
|
454
|
+
gl,
|
|
455
|
+
this.program,
|
|
456
|
+
location,
|
|
457
|
+
this.uniformCache.get(uniformName)
|
|
458
|
+
);
|
|
459
|
+
} else if (this.program) {
|
|
452
460
|
this.warnUnknownUniform(uniformName);
|
|
453
461
|
}
|
|
454
462
|
if (this.options.renderMode === "demand" && !this.inRender && this.onscreen) {
|
|
@@ -460,6 +468,54 @@ var ShaderBackground = class {
|
|
|
460
468
|
this.setUniform(name, value);
|
|
461
469
|
}
|
|
462
470
|
}
|
|
471
|
+
async setTexture(name, input) {
|
|
472
|
+
if (this.destroyed) return;
|
|
473
|
+
let gl = this.dom?.canvas.getContext("webgl");
|
|
474
|
+
if (!gl) {
|
|
475
|
+
await this.ready;
|
|
476
|
+
if (this.destroyed) return;
|
|
477
|
+
gl = this.dom?.canvas.getContext("webgl");
|
|
478
|
+
}
|
|
479
|
+
if (!gl) {
|
|
480
|
+
const error = new TextureLoadError(
|
|
481
|
+
"Cannot set texture before WebGL is ready."
|
|
482
|
+
);
|
|
483
|
+
this.options.onError?.(error);
|
|
484
|
+
throw error;
|
|
485
|
+
}
|
|
486
|
+
const version = (this.textureVersions.get(name) ?? 0) + 1;
|
|
487
|
+
this.textureVersions.set(name, version);
|
|
488
|
+
try {
|
|
489
|
+
const unit = this.resolveTextureUnit(gl, name);
|
|
490
|
+
const loaded = await loadTexture(gl, name, input, unit);
|
|
491
|
+
if (this.destroyed || this.textureVersions.get(name) !== version) {
|
|
492
|
+
gl.deleteTexture(loaded.texture);
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
const previous = this.textures.get(name);
|
|
496
|
+
this.textureInputs.set(name, input);
|
|
497
|
+
this.textures.set(name, loaded);
|
|
498
|
+
if (previous) gl.deleteTexture(previous.texture);
|
|
499
|
+
this.applyTextureSizeUniform(loaded);
|
|
500
|
+
if (this.options.renderMode === "demand" && !this.inRender && this.onscreen) {
|
|
501
|
+
this.render();
|
|
502
|
+
}
|
|
503
|
+
} catch (error) {
|
|
504
|
+
if (!this.textures.has(name) && !this.textureInputs.has(name)) {
|
|
505
|
+
this.textureUnits.delete(name);
|
|
506
|
+
}
|
|
507
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
508
|
+
this.options.onError?.(normalized);
|
|
509
|
+
throw normalized;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
async setTextures(values) {
|
|
513
|
+
await Promise.all(
|
|
514
|
+
Object.entries(values).map(
|
|
515
|
+
([name, input]) => this.setTexture(name, input)
|
|
516
|
+
)
|
|
517
|
+
);
|
|
518
|
+
}
|
|
463
519
|
async init() {
|
|
464
520
|
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
465
521
|
this.failUnsupported(new UnsupportedError("WebGL requires a browser."));
|
|
@@ -488,11 +544,8 @@ var ShaderBackground = class {
|
|
|
488
544
|
this.setupContextEvents();
|
|
489
545
|
this.setupProgram(gl);
|
|
490
546
|
this.resize();
|
|
491
|
-
this.
|
|
492
|
-
|
|
493
|
-
this.options.textures,
|
|
494
|
-
() => this.destroyed
|
|
495
|
-
);
|
|
547
|
+
this.textureInputs = new Map(Object.entries(this.options.textures ?? {}));
|
|
548
|
+
await this.loadTextureInputs(gl);
|
|
496
549
|
if (this.destroyed) return;
|
|
497
550
|
this.applyTextureSizeUniforms();
|
|
498
551
|
this.currentStatus = "ready";
|
|
@@ -517,8 +570,22 @@ var ShaderBackground = class {
|
|
|
517
570
|
);
|
|
518
571
|
gl.useProgram(this.program);
|
|
519
572
|
this.buffer = createFullscreenBuffer(gl, this.program);
|
|
573
|
+
this.attribLocation = gl.getAttribLocation(this.program, "a_position");
|
|
520
574
|
this.uniformLocations = collectUniformLocations(gl, this.program);
|
|
521
575
|
}
|
|
576
|
+
// Re-bind the core's program, fullscreen geometry, textures and uniforms so a
|
|
577
|
+
// draw is correct regardless of GL state changed by onBeforeRender/onAfterRender.
|
|
578
|
+
prepareDrawState(gl) {
|
|
579
|
+
if (!this.program) return;
|
|
580
|
+
gl.useProgram(this.program);
|
|
581
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
582
|
+
if (this.attribLocation >= 0) {
|
|
583
|
+
gl.enableVertexAttribArray(this.attribLocation);
|
|
584
|
+
gl.vertexAttribPointer(this.attribLocation, 2, gl.FLOAT, false, 0, 0);
|
|
585
|
+
}
|
|
586
|
+
this.applyTextures(gl);
|
|
587
|
+
this.applyCachedUniforms(gl);
|
|
588
|
+
}
|
|
522
589
|
setupDomObservers() {
|
|
523
590
|
if (!this.dom) return;
|
|
524
591
|
if (this.options.autoResize ?? true) {
|
|
@@ -586,9 +653,8 @@ var ShaderBackground = class {
|
|
|
586
653
|
try {
|
|
587
654
|
this.setupProgram(gl);
|
|
588
655
|
this.applyCachedUniforms(gl);
|
|
589
|
-
void
|
|
590
|
-
(
|
|
591
|
-
this.textures = textures;
|
|
656
|
+
void this.loadTextureInputs(gl).then(
|
|
657
|
+
() => {
|
|
592
658
|
this.applyTextureSizeUniforms();
|
|
593
659
|
if (this.contextRestoredShouldRun) this.start();
|
|
594
660
|
else this.render();
|
|
@@ -647,11 +713,22 @@ var ShaderBackground = class {
|
|
|
647
713
|
this.applyCachedUniforms(gl);
|
|
648
714
|
}
|
|
649
715
|
applyTextureSizeUniforms() {
|
|
650
|
-
for (const texture of this.textures) {
|
|
651
|
-
this.
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
716
|
+
for (const texture of this.textures.values()) {
|
|
717
|
+
this.applyTextureSizeUniform(texture);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
applyTextureSizeUniform(texture) {
|
|
721
|
+
const uniform = {
|
|
722
|
+
type: "vec2",
|
|
723
|
+
value: [texture.width, texture.height]
|
|
724
|
+
};
|
|
725
|
+
this.uniformCache.set(texture.sizeUniformName, uniform);
|
|
726
|
+
const gl = this.dom?.canvas.getContext("webgl");
|
|
727
|
+
const location = this.uniformLocations.get(texture.sizeUniformName);
|
|
728
|
+
if (gl && this.program && location) {
|
|
729
|
+
applyProgramUniform(gl, this.program, location, uniform);
|
|
730
|
+
} else if (this.program) {
|
|
731
|
+
this.warnUnknownUniform(texture.sizeUniformName);
|
|
655
732
|
}
|
|
656
733
|
}
|
|
657
734
|
applyCachedUniforms(gl) {
|
|
@@ -665,16 +742,45 @@ var ShaderBackground = class {
|
|
|
665
742
|
}
|
|
666
743
|
}
|
|
667
744
|
applyTextures(gl) {
|
|
668
|
-
for (
|
|
669
|
-
const
|
|
670
|
-
if (
|
|
745
|
+
for (const texture of this.textures.values()) {
|
|
746
|
+
const unit = this.textureUnits.get(texture.name);
|
|
747
|
+
if (unit === void 0) continue;
|
|
671
748
|
const location = this.uniformLocations.get(texture.uniformName);
|
|
672
|
-
if (!location)
|
|
749
|
+
if (!location) {
|
|
750
|
+
this.warnUnknownUniform(texture.uniformName);
|
|
751
|
+
continue;
|
|
752
|
+
}
|
|
673
753
|
gl.activeTexture(gl.TEXTURE0 + unit);
|
|
674
754
|
gl.bindTexture(gl.TEXTURE_2D, texture.texture);
|
|
675
755
|
gl.uniform1i(location, unit);
|
|
676
756
|
}
|
|
677
757
|
}
|
|
758
|
+
async loadTextureInputs(gl) {
|
|
759
|
+
const loadedTextures = /* @__PURE__ */ new Map();
|
|
760
|
+
for (const [name, input] of this.textureInputs) {
|
|
761
|
+
if (this.destroyed) break;
|
|
762
|
+
const unit = this.resolveTextureUnit(gl, name);
|
|
763
|
+
loadedTextures.set(name, await loadTexture(gl, name, input, unit));
|
|
764
|
+
}
|
|
765
|
+
for (const texture of this.textures.values()) {
|
|
766
|
+
gl.deleteTexture(texture.texture);
|
|
767
|
+
}
|
|
768
|
+
this.textures = loadedTextures;
|
|
769
|
+
}
|
|
770
|
+
resolveTextureUnit(gl, name) {
|
|
771
|
+
const existing = this.textureUnits.get(name);
|
|
772
|
+
if (existing !== void 0) return existing;
|
|
773
|
+
const maxUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
|
|
774
|
+
for (let unit = 0; unit < maxUnits; unit += 1) {
|
|
775
|
+
if (![...this.textureUnits.values()].includes(unit)) {
|
|
776
|
+
this.textureUnits.set(name, unit);
|
|
777
|
+
return unit;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
throw new TextureLoadError(
|
|
781
|
+
`Texture unit limit exceeded while loading texture: ${name}`
|
|
782
|
+
);
|
|
783
|
+
}
|
|
678
784
|
createRenderState(gl) {
|
|
679
785
|
return {
|
|
680
786
|
instance: this,
|
|
@@ -722,6 +828,8 @@ export {
|
|
|
722
828
|
UnsupportedError,
|
|
723
829
|
createShaderBackground,
|
|
724
830
|
glsl,
|
|
725
|
-
glslUtils
|
|
831
|
+
glslUtils,
|
|
832
|
+
hexToRgb,
|
|
833
|
+
hexToRgba
|
|
726
834
|
};
|
|
727
835
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/errors.ts","../src/internal/dom.ts","../src/internal/names.ts","../src/internal/textures.ts","../src/internal/uniforms.ts","../src/internal/webgl.ts","../src/createShaderBackground.ts"],"sourcesContent":["export class ShaderError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\nexport class UnsupportedError extends ShaderError {}\nexport class TargetNotFoundError extends ShaderError {}\nexport class ShaderCompileError extends ShaderError {}\nexport class TextureLoadError extends ShaderError {}\nexport class DestroyedError extends ShaderError {}\n","import type { CreateShaderBackgroundOptions, DprOption } from \"../types\";\n\nexport type DomSetup = {\n target: Element;\n canvas: HTMLCanvasElement;\n createdCanvas: boolean;\n restoredPosition: string | null;\n};\n\nexport const resolveElement = (\n target: string | Element | undefined\n): Element | null => {\n if (!target) return null;\n if (typeof target === \"string\") return document.querySelector(target);\n return target;\n};\n\nexport const setupCanvas = (\n options: CreateShaderBackgroundOptions\n): DomSetup | null => {\n const target = resolveElement(options.target);\n const canvas = options.canvas ?? document.createElement(\"canvas\");\n const measurementTarget = target ?? options.canvas;\n\n if (!measurementTarget) return null;\n\n const createdCanvas = !options.canvas;\n const restoredPosition =\n target && getComputedStyle(target).position === \"static\"\n ? (target as HTMLElement).style.position\n : null;\n\n if (target && restoredPosition !== null) {\n (target as HTMLElement).style.position = \"relative\";\n }\n\n applyCanvasStyle(canvas, options, createdCanvas);\n\n if (options.canvasClass) {\n canvas.classList.add(options.canvasClass);\n }\n\n if (options.canvasStyle) {\n Object.assign(canvas.style, options.canvasStyle);\n }\n\n if (createdCanvas && target) {\n if ((options.layer ?? \"background\") === \"overlay\") {\n target.append(canvas);\n } else {\n target.prepend(canvas);\n }\n }\n\n return {\n target: measurementTarget,\n canvas,\n createdCanvas,\n restoredPosition\n };\n};\n\nexport const resolveDpr = (\n dpr: DprOption | undefined,\n maxDpr: number | undefined\n): number => {\n const raw =\n typeof dpr === \"function\"\n ? dpr()\n : typeof dpr === \"number\"\n ? dpr\n : typeof window === \"undefined\"\n ? 1\n : window.devicePixelRatio || 1;\n\n return Math.max(1, Math.min(raw, maxDpr ?? 2));\n};\n\nexport const resizeCanvasToTarget = (\n canvas: HTMLCanvasElement,\n target: Element,\n dpr: number\n): {\n width: number;\n height: number;\n viewportWidth: number;\n viewportHeight: number;\n} => {\n const rect = target.getBoundingClientRect();\n const viewportWidth = Math.max(1, rect.width || canvas.clientWidth || 1);\n const viewportHeight = Math.max(1, rect.height || canvas.clientHeight || 1);\n const width = Math.max(1, Math.round(viewportWidth * dpr));\n const height = Math.max(1, Math.round(viewportHeight * dpr));\n\n if (canvas.width !== width) canvas.width = width;\n if (canvas.height !== height) canvas.height = height;\n\n return { width, height, viewportWidth, viewportHeight };\n};\n\nconst applyCanvasStyle = (\n canvas: HTMLCanvasElement,\n options: CreateShaderBackgroundOptions,\n shouldPosition: boolean\n): void => {\n canvas.dataset.frapxShaderCanvas = \"\";\n\n if (!shouldPosition) return;\n\n const layer = options.layer ?? \"background\";\n Object.assign(canvas.style, {\n position: \"absolute\",\n inset: \"0\",\n width: \"100%\",\n height: \"100%\",\n display: \"block\",\n pointerEvents: \"none\",\n zIndex: layer === \"overlay\" ? \"1\" : \"0\"\n });\n};\n","export const toUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name : `u_${name}`;\n\nexport const fromUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name.slice(2) : name;\n","import type { TextureInput, TextureOptions, TextureSource } from \"../types\";\nimport { TextureLoadError } from \"./errors\";\nimport { toUniformName } from \"./names\";\n\nexport type LoadedTexture = {\n name: string;\n uniformName: string;\n sizeUniformName: string;\n texture: WebGLTexture;\n width: number;\n height: number;\n};\n\nexport const loadTextures = async (\n gl: WebGLRenderingContext,\n textures: Record<string, TextureInput> | undefined,\n isDestroyed: () => boolean\n): Promise<LoadedTexture[]> => {\n const entries = Object.entries(textures ?? {});\n const loaded: LoadedTexture[] = [];\n\n for (let index = 0; index < entries.length; index += 1) {\n if (isDestroyed()) break;\n const [name, input] = entries[index] as [string, TextureInput];\n loaded.push(await loadTexture(gl, name, input, index));\n }\n\n return loaded;\n};\n\nconst loadTexture = async (\n gl: WebGLRenderingContext,\n name: string,\n input: TextureInput,\n unit: number\n): Promise<LoadedTexture> => {\n const options = normalizeTextureInput(input);\n const source = await resolveSource(options.source);\n const texture = gl.createTexture();\n\n if (!texture) {\n throw new TextureLoadError(`Failed to create texture: ${name}`);\n }\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, options.flipY ?? true);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);\n\n const wrap = getWrap(gl, options.wrap ?? \"clamp\");\n const filter = getFilter(gl, options.filter ?? \"linear\");\n\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n return {\n name,\n uniformName: toUniformName(name),\n sizeUniformName: toUniformName(`${name}Size`),\n texture,\n width: getSourceWidth(source),\n height: getSourceHeight(source)\n };\n};\n\nconst normalizeTextureInput = (input: TextureInput): TextureOptions => {\n if (typeof input === \"string\" || isTextureSource(input)) {\n return { source: input };\n }\n\n return input;\n};\n\nconst resolveSource = async (\n source: TextureSource\n): Promise<HTMLImageElement | HTMLCanvasElement> => {\n if (typeof source !== \"string\") {\n return source;\n }\n\n const image = new Image();\n image.crossOrigin = \"anonymous\";\n image.src = source;\n\n try {\n await image.decode();\n } catch (error) {\n throw new TextureLoadError(`Failed to load texture: ${source}`);\n }\n\n return image;\n};\n\nconst getWrap = (\n gl: WebGLRenderingContext,\n wrap: NonNullable<TextureOptions[\"wrap\"]>\n): number => {\n if (wrap === \"repeat\") return gl.REPEAT;\n if (wrap === \"mirror\") return gl.MIRRORED_REPEAT;\n return gl.CLAMP_TO_EDGE;\n};\n\nconst getFilter = (\n gl: WebGLRenderingContext,\n filter: NonNullable<TextureOptions[\"filter\"]>\n): number => (filter === \"nearest\" ? gl.NEAREST : gl.LINEAR);\n\nconst isTextureSource = (input: unknown): input is HTMLImageElement | HTMLCanvasElement =>\n typeof HTMLImageElement !== \"undefined\" &&\n (input instanceof HTMLImageElement || input instanceof HTMLCanvasElement);\n\nconst getSourceWidth = (source: HTMLImageElement | HTMLCanvasElement): number =>\n \"naturalWidth\" in source ? source.naturalWidth : source.width;\n\nconst getSourceHeight = (source: HTMLImageElement | HTMLCanvasElement): number =>\n \"naturalHeight\" in source ? source.naturalHeight : source.height;\n","import type { ExplicitUniformInput, UniformInput, UniformType } from \"../types\";\nimport { toUniformName } from \"./names\";\n\nexport type NormalizedUniform = {\n type: UniformType;\n value: number[] | Float32Array;\n};\n\nexport const normalizeUniform = (input: UniformInput): NormalizedUniform => {\n if (typeof input === \"number\") {\n return { type: \"float\", value: [input] };\n }\n\n if (input instanceof Float32Array) {\n if (input.length === 9) return { type: \"mat3\", value: input };\n if (input.length === 16) return { type: \"mat4\", value: input };\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n if (isExplicitUniform(input)) {\n return { type: input.type, value: input.value };\n }\n\n if (Array.isArray(input)) {\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n return { type: \"float\", value: [0] };\n};\n\nexport const applyUniform = (\n gl: WebGLRenderingContext,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n const value = uniform.value;\n\n switch (uniform.type) {\n case \"float\":\n gl.uniform1f(location, value[0] ?? 0);\n break;\n case \"vec2\":\n gl.uniform2f(location, value[0] ?? 0, value[1] ?? 0);\n break;\n case \"vec3\":\n gl.uniform3f(location, value[0] ?? 0, value[1] ?? 0, value[2] ?? 0);\n break;\n case \"vec4\":\n gl.uniform4f(\n location,\n value[0] ?? 0,\n value[1] ?? 0,\n value[2] ?? 0,\n value[3] ?? 0\n );\n break;\n case \"mat3\":\n gl.uniformMatrix3fv(location, false, value);\n break;\n case \"mat4\":\n gl.uniformMatrix4fv(location, false, value);\n break;\n }\n};\n\nexport const collectUniformLocations = (\n gl: WebGLRenderingContext,\n program: WebGLProgram\n): Map<string, WebGLUniformLocation> => {\n const locations = new Map<string, WebGLUniformLocation>();\n const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS) as number;\n\n for (let index = 0; index < count; index += 1) {\n const active = gl.getActiveUniform(program, index);\n if (!active) continue;\n\n const name = active.name.replace(/\\[0\\]$/, \"\");\n const location = gl.getUniformLocation(program, name);\n if (location) {\n locations.set(name, location);\n }\n }\n\n return locations;\n};\n\nexport const createUniformCache = (\n uniforms: Record<string, UniformInput> | undefined\n): Map<string, NormalizedUniform> => {\n const cache = new Map<string, NormalizedUniform>();\n\n for (const [name, value] of Object.entries(uniforms ?? {})) {\n cache.set(toUniformName(name), normalizeUniform(value));\n }\n\n return cache;\n};\n\nconst isExplicitUniform = (input: unknown): input is ExplicitUniformInput => {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) return false;\n return \"type\" in input && \"value\" in input;\n};\n","import { ShaderCompileError } from \"./errors\";\n\nexport const defaultVertexShader = `\nattribute vec2 a_position;\nvarying vec2 v_uv;\n\nvoid main() {\n v_uv = a_position * 0.5 + 0.5;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}\n`;\n\nexport const createProgram = (\n gl: WebGLRenderingContext,\n vertexSource: string,\n fragmentSource: string\n): WebGLProgram => {\n const vertex = compileShader(gl, gl.VERTEX_SHADER, vertexSource);\n const fragment = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);\n const program = gl.createProgram();\n\n if (!program) {\n throw new ShaderCompileError(\"Failed to create WebGL program.\");\n }\n\n gl.attachShader(program, vertex);\n gl.attachShader(program, fragment);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const log = gl.getProgramInfoLog(program) ?? \"Unknown program link error.\";\n gl.deleteProgram(program);\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n throw new ShaderCompileError(log);\n }\n\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n return program;\n};\n\nexport const createFullscreenBuffer = (\n gl: WebGLRenderingContext,\n program: WebGLProgram\n): WebGLBuffer => {\n const buffer = gl.createBuffer();\n if (!buffer) {\n throw new ShaderCompileError(\"Failed to create fullscreen buffer.\");\n }\n\n const location = gl.getAttribLocation(program, \"a_position\");\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]),\n gl.STATIC_DRAW\n );\n\n if (location >= 0) {\n gl.enableVertexAttribArray(location);\n gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n};\n\nconst compileShader = (\n gl: WebGLRenderingContext,\n type: number,\n source: string\n): WebGLShader => {\n const shader = gl.createShader(type);\n if (!shader) {\n throw new ShaderCompileError(\"Failed to create WebGL shader.\");\n }\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const log = gl.getShaderInfoLog(shader) ?? \"Unknown shader compile error.\";\n gl.deleteShader(shader);\n throw new ShaderCompileError(log);\n }\n\n return shader;\n};\n","import type {\n CreateShaderBackgroundOptions,\n RenderState,\n ShaderBackgroundInstance,\n ShaderStatus,\n UniformInput,\n UniformInputMap,\n UniformRuntimeValue\n} from \"./types\";\nimport {\n DestroyedError,\n TargetNotFoundError,\n UnsupportedError\n} from \"./internal/errors\";\nimport {\n resolveDpr,\n resizeCanvasToTarget,\n setupCanvas,\n type DomSetup\n} from \"./internal/dom\";\nimport { toUniformName } from \"./internal/names\";\nimport { loadTextures, type LoadedTexture } from \"./internal/textures\";\nimport {\n applyUniform,\n collectUniformLocations,\n createUniformCache,\n normalizeUniform,\n type NormalizedUniform\n} from \"./internal/uniforms\";\nimport {\n createFullscreenBuffer,\n createProgram,\n defaultVertexShader\n} from \"./internal/webgl\";\n\nconst MAX_DELTA_SECONDS = 0.1;\n\nexport const createShaderBackground = <\n TUniforms extends UniformInputMap = UniformInputMap\n>(\n options: CreateShaderBackgroundOptions<TUniforms>\n): ShaderBackgroundInstance<TUniforms> => {\n return new ShaderBackground<TUniforms>(options);\n};\n\nclass ShaderBackground<TUniforms extends UniformInputMap>\n implements ShaderBackgroundInstance<TUniforms>\n{\n readonly ready: Promise<void>;\n\n private readonly options: CreateShaderBackgroundOptions<TUniforms>;\n private readonly uniformCache: Map<string, NormalizedUniform>;\n private readonly warnedUniforms = new Set<string>();\n private readyResolve: (() => void) | null = null;\n private readyReject: ((error: Error) => void) | null = null;\n private dom: DomSetup | null = null;\n private program: WebGLProgram | null = null;\n private buffer: WebGLBuffer | null = null;\n private uniformLocations = new Map<string, WebGLUniformLocation>();\n private textures: LoadedTexture[] = [];\n private resizeObserver: ResizeObserver | null = null;\n private intersectionObserver: IntersectionObserver | null = null;\n private rafId = 0;\n private running = false;\n private inRender = false;\n private destroyed = false;\n private onscreen = true;\n private frame = 0;\n private elapsed = 0;\n private lastTimestamp = 0;\n private pixelRatio = 1;\n private width = 1;\n private height = 1;\n private viewportWidth = 1;\n private viewportHeight = 1;\n private pointer = { x: 0, y: 0, uvX: 0, uvY: 0, active: 0 };\n private removeListeners: Array<() => void> = [];\n private currentStatus: ShaderStatus = \"idle\";\n private contextRestoredShouldRun = false;\n\n constructor(options: CreateShaderBackgroundOptions<TUniforms>) {\n this.options = options;\n this.uniformCache = createUniformCache(options.uniforms);\n this.ready = new Promise<void>((resolve, reject) => {\n this.readyResolve = resolve;\n this.readyReject = reject;\n });\n\n queueMicrotask(() => {\n void this.init();\n });\n }\n\n get canvas(): HTMLCanvasElement | null {\n return this.dom?.canvas ?? null;\n }\n\n get gl(): WebGLRenderingContext | null {\n return this.dom?.canvas.getContext(\"webgl\") ?? null;\n }\n\n get status(): ShaderStatus {\n return this.currentStatus;\n }\n\n get supported(): boolean {\n return ![\"unsupported\", \"destroyed\"].includes(this.currentStatus);\n }\n\n start(): void {\n if (this.destroyed || this.currentStatus === \"unsupported\") return;\n this.running = true;\n\n if (!this.onscreen && (this.options.pauseWhenOffscreen ?? true)) {\n this.currentStatus = \"paused\";\n return;\n }\n\n if (this.options.renderMode === \"demand\") {\n this.currentStatus = \"running\";\n this.render();\n return;\n }\n\n this.currentStatus = \"running\";\n this.scheduleFrame();\n }\n\n stop(): void {\n this.running = false;\n this.cancelFrame();\n if (!this.destroyed && this.currentStatus !== \"unsupported\") {\n this.currentStatus = \"paused\";\n }\n }\n\n render(): void {\n if (\n this.destroyed ||\n !this.dom ||\n !this.program ||\n this.currentStatus === \"unsupported\" ||\n (this.options.pauseWhenOffscreen ?? true) && !this.onscreen\n ) {\n return;\n }\n\n const gl = this.dom.canvas.getContext(\"webgl\");\n if (!gl) return;\n\n this.inRender = true;\n this.resize();\n gl.viewport(0, 0, this.width, this.height);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.useProgram(this.program);\n this.applyBuiltInUniforms(gl);\n this.applyCachedUniforms(gl);\n this.applyTextures(gl);\n\n const state = this.createRenderState(gl);\n this.options.onBeforeRender?.(state);\n this.applyCachedUniforms(gl);\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n this.options.onAfterRender?.(state);\n this.frame += 1;\n this.inRender = false;\n }\n\n resize(): void {\n if (this.destroyed || !this.dom) return;\n this.pixelRatio = resolveDpr(this.options.dpr, this.options.maxDpr);\n const size = resizeCanvasToTarget(\n this.dom.canvas,\n this.dom.target,\n this.pixelRatio\n );\n this.width = size.width;\n this.height = size.height;\n this.viewportWidth = size.viewportWidth;\n this.viewportHeight = size.viewportHeight;\n\n if (this.options.renderMode === \"demand\" && !this.inRender) {\n this.render();\n }\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.running = false;\n this.cancelFrame();\n this.resizeObserver?.disconnect();\n this.intersectionObserver?.disconnect();\n\n for (const remove of this.removeListeners) remove();\n this.removeListeners = [];\n\n const gl = this.dom?.canvas.getContext(\"webgl\");\n if (gl) {\n for (const texture of this.textures) gl.deleteTexture(texture.texture);\n if (this.buffer) gl.deleteBuffer(this.buffer);\n if (this.program) gl.deleteProgram(this.program);\n }\n\n if (this.dom?.createdCanvas) {\n this.dom.canvas.remove();\n }\n\n const dom = this.dom;\n if (dom?.restoredPosition !== null && dom && this.options.target) {\n const target = dom.target as HTMLElement;\n target.style.position = dom.restoredPosition;\n }\n\n this.currentStatus = \"destroyed\";\n this.readyReject?.(new DestroyedError(\"Shader background was destroyed.\"));\n }\n\n setUniform<K extends keyof TUniforms & string>(\n name: K,\n value: UniformRuntimeValue<TUniforms[K]>\n ): void;\n setUniform(name: string, value: UniformInput): void;\n setUniform(name: string, value: UniformInput): void {\n if (this.destroyed) return;\n const uniformName = toUniformName(name);\n this.uniformCache.set(uniformName, normalizeUniform(value));\n\n const gl = this.dom?.canvas.getContext(\"webgl\");\n const location = this.uniformLocations.get(uniformName);\n if (gl && location) {\n applyUniform(gl, location, this.uniformCache.get(uniformName)!);\n } else {\n this.warnUnknownUniform(uniformName);\n }\n\n if (\n this.options.renderMode === \"demand\" &&\n !this.inRender &&\n this.onscreen\n ) {\n this.render();\n }\n }\n\n setUniforms(values: Record<string, UniformInput>): void {\n for (const [name, value] of Object.entries(values)) {\n this.setUniform(name, value);\n }\n }\n\n private async init(): Promise<void> {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n this.failUnsupported(new UnsupportedError(\"WebGL requires a browser.\"));\n return;\n }\n\n this.dom = setupCanvas(this.options);\n if (!this.dom) {\n this.failUnsupported(new TargetNotFoundError(\"Target or canvas not found.\"));\n return;\n }\n\n const gl = this.dom.canvas.getContext(\"webgl\", {\n alpha: true,\n antialias: false,\n depth: false,\n stencil: false,\n premultipliedAlpha: true,\n preserveDrawingBuffer: false\n });\n\n if (!gl) {\n this.failUnsupported(new UnsupportedError(\"WebGL is not supported.\"));\n return;\n }\n\n this.currentStatus = \"loading\";\n\n try {\n this.setupDomObservers();\n this.setupContextEvents();\n this.setupProgram(gl);\n this.resize();\n this.textures = await loadTextures(\n gl,\n this.options.textures,\n () => this.destroyed\n );\n if (this.destroyed) return;\n this.applyTextureSizeUniforms();\n this.currentStatus = \"ready\";\n this.readyResolve?.();\n this.options.onReady?.(this);\n\n if (this.running || (this.options.autoStart ?? true)) {\n this.start();\n } else if (this.options.renderMode === \"demand\") {\n this.render();\n }\n } catch (error) {\n this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n private setupProgram(gl: WebGLRenderingContext): void {\n if (this.program) gl.deleteProgram(this.program);\n if (this.buffer) gl.deleteBuffer(this.buffer);\n\n this.program = createProgram(\n gl,\n this.options.vertex ?? defaultVertexShader,\n this.options.fragment\n );\n gl.useProgram(this.program);\n this.buffer = createFullscreenBuffer(gl, this.program);\n this.uniformLocations = collectUniformLocations(gl, this.program);\n }\n\n private setupDomObservers(): void {\n if (!this.dom) return;\n\n if (this.options.autoResize ?? true) {\n this.resizeObserver = new ResizeObserver(() => {\n this.resize();\n });\n this.resizeObserver.observe(this.dom.target);\n }\n\n if (this.options.pauseWhenOffscreen ?? true) {\n this.intersectionObserver = new IntersectionObserver((entries) => {\n const entry = entries[0];\n this.onscreen = Boolean(entry?.isIntersecting);\n if (!this.onscreen) {\n this.cancelFrame();\n if (this.running) this.currentStatus = \"paused\";\n return;\n }\n\n if (this.running) {\n this.start();\n } else if (this.options.renderMode === \"demand\") {\n this.render();\n }\n });\n this.intersectionObserver.observe(this.dom.target);\n }\n\n const onPointerMove = (event: Event) => {\n if (!this.dom) return;\n const pointerEvent = event as PointerEvent;\n const rect = this.dom.target.getBoundingClientRect();\n const x = pointerEvent.clientX - rect.left;\n const y = pointerEvent.clientY - rect.top;\n this.pointer.x = x * this.pixelRatio;\n this.pointer.y = (rect.height - y) * this.pixelRatio;\n this.pointer.uvX = rect.width > 0 ? x / rect.width : 0;\n this.pointer.uvY = rect.height > 0 ? 1 - y / rect.height : 0;\n this.pointer.active = 1;\n\n if (this.options.renderMode === \"demand\") this.render();\n };\n const onPointerLeave = () => {\n this.pointer.active = 0;\n if (this.options.renderMode === \"demand\") this.render();\n };\n\n this.dom.target.addEventListener(\"pointermove\", onPointerMove);\n this.dom.target.addEventListener(\"pointerenter\", onPointerMove);\n this.dom.target.addEventListener(\"pointerleave\", onPointerLeave);\n this.removeListeners.push(() => {\n this.dom?.target.removeEventListener(\"pointermove\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerenter\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerleave\", onPointerLeave);\n });\n }\n\n private setupContextEvents(): void {\n if (!this.dom) return;\n\n const onLost = (event: Event) => {\n event.preventDefault();\n this.contextRestoredShouldRun = this.running;\n this.cancelFrame();\n this.currentStatus = \"context-lost\";\n this.options.onError?.(new UnsupportedError(\"WebGL context lost.\"));\n };\n\n const onRestored = () => {\n if (!this.dom || this.destroyed) return;\n const gl = this.dom.canvas.getContext(\"webgl\");\n if (!gl) return;\n\n try {\n this.setupProgram(gl);\n this.applyCachedUniforms(gl);\n void loadTextures(gl, this.options.textures, () => this.destroyed).then(\n (textures) => {\n this.textures = textures;\n this.applyTextureSizeUniforms();\n if (this.contextRestoredShouldRun) this.start();\n else this.render();\n },\n (error: unknown) =>\n this.fail(error instanceof Error ? error : new Error(String(error)))\n );\n } catch (error) {\n this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n };\n\n this.dom.canvas.addEventListener(\"webglcontextlost\", onLost);\n this.dom.canvas.addEventListener(\"webglcontextrestored\", onRestored);\n this.removeListeners.push(() => {\n this.dom?.canvas.removeEventListener(\"webglcontextlost\", onLost);\n this.dom?.canvas.removeEventListener(\"webglcontextrestored\", onRestored);\n });\n }\n\n private scheduleFrame(): void {\n if (this.rafId || this.options.renderMode === \"demand\") return;\n\n this.rafId = requestAnimationFrame((timestamp) => {\n this.rafId = 0;\n if (!this.running || this.destroyed) return;\n\n const seconds = timestamp / 1000;\n const rawDelta = this.lastTimestamp ? seconds - this.lastTimestamp : 0;\n const delta = Math.min(Math.max(rawDelta, 0), MAX_DELTA_SECONDS);\n this.lastTimestamp = seconds;\n this.elapsed += delta;\n this.setBuiltInTime(delta);\n this.render();\n this.scheduleFrame();\n });\n }\n\n private cancelFrame(): void {\n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = 0;\n }\n this.lastTimestamp = 0;\n }\n\n private setBuiltInTime(delta: number): void {\n this.uniformCache.set(\"u_time\", { type: \"float\", value: [this.elapsed] });\n this.uniformCache.set(\"u_delta\", { type: \"float\", value: [delta] });\n }\n\n private applyBuiltInUniforms(gl: WebGLRenderingContext): void {\n const builtIns: Record<string, UniformInput> = {\n resolution: [this.width, this.height],\n viewportSize: [this.viewportWidth, this.viewportHeight],\n pixelRatio: this.pixelRatio,\n pointer: [this.pointer.x, this.pointer.y],\n pointerUv: [this.pointer.uvX, this.pointer.uvY],\n pointerActive: this.pointer.active\n };\n\n for (const [name, value] of Object.entries(builtIns)) {\n this.uniformCache.set(toUniformName(name), normalizeUniform(value));\n }\n\n this.applyCachedUniforms(gl);\n }\n\n private applyTextureSizeUniforms(): void {\n for (const texture of this.textures) {\n this.uniformCache.set(texture.sizeUniformName, {\n type: \"vec2\",\n value: [texture.width, texture.height]\n });\n }\n }\n\n private applyCachedUniforms(gl: WebGLRenderingContext): void {\n for (const [name, uniform] of this.uniformCache) {\n const location = this.uniformLocations.get(name);\n if (!location) {\n this.warnUnknownUniform(name);\n continue;\n }\n applyUniform(gl, location, uniform);\n }\n }\n\n private applyTextures(gl: WebGLRenderingContext): void {\n for (let unit = 0; unit < this.textures.length; unit += 1) {\n const texture = this.textures[unit];\n if (!texture) continue;\n const location = this.uniformLocations.get(texture.uniformName);\n if (!location) continue;\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture.texture);\n gl.uniform1i(location, unit);\n }\n }\n\n private createRenderState(\n gl: WebGLRenderingContext\n ): RenderState<TUniforms> {\n return {\n instance: this,\n gl,\n canvas: this.dom!.canvas,\n time: this.elapsed,\n delta: this.uniformCache.get(\"u_delta\")?.value[0] ?? 0,\n frame: this.frame,\n width: this.width,\n height: this.height,\n viewportWidth: this.viewportWidth,\n viewportHeight: this.viewportHeight,\n pixelRatio: this.pixelRatio\n };\n }\n\n private warnUnknownUniform(name: string): void {\n if (!this.options.debug || this.warnedUniforms.has(name)) return;\n this.warnedUniforms.add(name);\n console.warn(`[frapx/shader] Uniform not found or optimized out: ${name}`);\n }\n\n private failUnsupported(error: Error): void {\n this.currentStatus = \"unsupported\";\n this.debugWarn(error.message);\n this.options.onError?.(error);\n this.readyReject?.(error);\n }\n\n private fail(error: Error): void {\n this.currentStatus = \"error\";\n this.debugWarn(error.message);\n this.options.onError?.(error);\n this.readyReject?.(error);\n }\n\n private debugWarn(message: string): void {\n if (this.options.debug) {\n console.warn(`[frapx/shader] ${message}`);\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/errors.ts","../src/internal/dom.ts","../src/internal/names.ts","../src/internal/textures.ts","../src/internal/uniforms.ts","../src/internal/webgl.ts","../src/createShaderBackground.ts"],"sourcesContent":["export class ShaderError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\nexport class UnsupportedError extends ShaderError {}\nexport class TargetNotFoundError extends ShaderError {}\nexport class ShaderCompileError extends ShaderError {}\nexport class TextureLoadError extends ShaderError {}\nexport class DestroyedError extends ShaderError {}\n","import type { CreateShaderBackgroundOptions, DprOption } from \"../types\";\n\nexport type DomSetup = {\n target: Element;\n canvas: HTMLCanvasElement;\n createdCanvas: boolean;\n restoredPosition: string | null;\n};\n\nexport const resolveElement = (\n target: string | Element | undefined\n): Element | null => {\n if (!target) return null;\n if (typeof target === \"string\") return document.querySelector(target);\n return target;\n};\n\nexport const setupCanvas = (\n options: CreateShaderBackgroundOptions\n): DomSetup | null => {\n const target = resolveElement(options.target);\n const canvas = options.canvas ?? document.createElement(\"canvas\");\n const measurementTarget = target ?? options.canvas;\n\n if (!measurementTarget) return null;\n\n const createdCanvas = !options.canvas;\n const restoredPosition =\n target && getComputedStyle(target).position === \"static\"\n ? (target as HTMLElement).style.position\n : null;\n\n if (target && restoredPosition !== null) {\n (target as HTMLElement).style.position = \"relative\";\n }\n\n applyCanvasStyle(canvas, options, createdCanvas);\n\n if (options.canvasClass) {\n canvas.classList.add(options.canvasClass);\n }\n\n if (options.canvasStyle) {\n Object.assign(canvas.style, options.canvasStyle);\n }\n\n if (createdCanvas && target) {\n if ((options.layer ?? \"background\") === \"overlay\") {\n target.append(canvas);\n } else {\n target.prepend(canvas);\n }\n }\n\n return {\n target: measurementTarget,\n canvas,\n createdCanvas,\n restoredPosition\n };\n};\n\nexport const resolveDpr = (\n dpr: DprOption | undefined,\n maxDpr: number | undefined\n): number => {\n const raw =\n typeof dpr === \"function\"\n ? dpr()\n : typeof dpr === \"number\"\n ? dpr\n : typeof window === \"undefined\"\n ? 1\n : window.devicePixelRatio || 1;\n\n return Math.max(1, Math.min(raw, maxDpr ?? 2));\n};\n\nexport const resizeCanvasToTarget = (\n canvas: HTMLCanvasElement,\n target: Element,\n dpr: number\n): {\n width: number;\n height: number;\n viewportWidth: number;\n viewportHeight: number;\n} => {\n const rect = target.getBoundingClientRect();\n const viewportWidth = Math.max(1, rect.width || canvas.clientWidth || 1);\n const viewportHeight = Math.max(1, rect.height || canvas.clientHeight || 1);\n const width = Math.max(1, Math.round(viewportWidth * dpr));\n const height = Math.max(1, Math.round(viewportHeight * dpr));\n\n if (canvas.width !== width) canvas.width = width;\n if (canvas.height !== height) canvas.height = height;\n\n return { width, height, viewportWidth, viewportHeight };\n};\n\nconst applyCanvasStyle = (\n canvas: HTMLCanvasElement,\n options: CreateShaderBackgroundOptions,\n shouldPosition: boolean\n): void => {\n canvas.dataset.frapxShaderCanvas = \"\";\n\n if (!shouldPosition) return;\n\n const layer = options.layer ?? \"background\";\n Object.assign(canvas.style, {\n position: \"absolute\",\n inset: \"0\",\n width: \"100%\",\n height: \"100%\",\n display: \"block\",\n pointerEvents: \"none\",\n zIndex: layer === \"overlay\" ? \"1\" : \"0\"\n });\n};\n","export const toUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name : `u_${name}`;\n\nexport const fromUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name.slice(2) : name;\n","import type { TextureInput, TextureOptions, TextureSource } from \"../types\";\nimport { TextureLoadError } from \"./errors\";\nimport { toUniformName } from \"./names\";\n\nexport type LoadedTexture = {\n name: string;\n uniformName: string;\n sizeUniformName: string;\n texture: WebGLTexture;\n width: number;\n height: number;\n};\n\nexport const loadTextures = async (\n gl: WebGLRenderingContext,\n textures: Record<string, TextureInput> | undefined,\n isDestroyed: () => boolean\n): Promise<LoadedTexture[]> => {\n const entries = Object.entries(textures ?? {});\n const loaded: LoadedTexture[] = [];\n\n for (let index = 0; index < entries.length; index += 1) {\n if (isDestroyed()) break;\n const [name, input] = entries[index] as [string, TextureInput];\n loaded.push(await loadTexture(gl, name, input, index));\n }\n\n return loaded;\n};\n\nexport const loadTexture = async (\n gl: WebGLRenderingContext,\n name: string,\n input: TextureInput,\n unit: number\n): Promise<LoadedTexture> => {\n const options = normalizeTextureInput(input);\n const source = await resolveSource(options.source);\n const texture = gl.createTexture();\n\n if (!texture) {\n throw new TextureLoadError(`Failed to create texture: ${name}`);\n }\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, options.flipY ?? true);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);\n\n const wrap = getWrap(gl, options.wrap ?? \"clamp\");\n const filter = getFilter(gl, options.filter ?? \"linear\");\n\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n return {\n name,\n uniformName: toUniformName(name),\n sizeUniformName: toUniformName(`${name}Size`),\n texture,\n width: getSourceWidth(source),\n height: getSourceHeight(source)\n };\n};\n\nconst normalizeTextureInput = (input: TextureInput): TextureOptions => {\n if (typeof input === \"string\" || isTextureSource(input)) {\n return { source: input };\n }\n\n return input;\n};\n\nconst resolveSource = async (\n source: TextureSource\n): Promise<HTMLImageElement | HTMLCanvasElement> => {\n if (typeof source !== \"string\") {\n return source;\n }\n\n const image = new Image();\n image.crossOrigin = \"anonymous\";\n image.src = source;\n\n try {\n await image.decode();\n } catch (error) {\n throw new TextureLoadError(`Failed to load texture: ${source}`);\n }\n\n return image;\n};\n\nconst getWrap = (\n gl: WebGLRenderingContext,\n wrap: NonNullable<TextureOptions[\"wrap\"]>\n): number => {\n if (wrap === \"repeat\") return gl.REPEAT;\n if (wrap === \"mirror\") return gl.MIRRORED_REPEAT;\n return gl.CLAMP_TO_EDGE;\n};\n\nconst getFilter = (\n gl: WebGLRenderingContext,\n filter: NonNullable<TextureOptions[\"filter\"]>\n): number => (filter === \"nearest\" ? gl.NEAREST : gl.LINEAR);\n\nconst isTextureSource = (input: unknown): input is HTMLImageElement | HTMLCanvasElement =>\n typeof HTMLImageElement !== \"undefined\" &&\n (input instanceof HTMLImageElement || input instanceof HTMLCanvasElement);\n\nconst getSourceWidth = (source: HTMLImageElement | HTMLCanvasElement): number =>\n \"naturalWidth\" in source ? source.naturalWidth : source.width;\n\nconst getSourceHeight = (source: HTMLImageElement | HTMLCanvasElement): number =>\n \"naturalHeight\" in source ? source.naturalHeight : source.height;\n","import type { ExplicitUniformInput, UniformInput, UniformType } from \"../types\";\nimport { toUniformName } from \"./names\";\n\nexport type NormalizedUniform = {\n type: UniformType;\n value: number[] | Float32Array;\n};\n\nexport const normalizeUniform = (input: UniformInput): NormalizedUniform => {\n if (typeof input === \"number\") {\n return { type: \"float\", value: [input] };\n }\n\n if (input instanceof Float32Array) {\n if (input.length === 9) return { type: \"mat3\", value: input };\n if (input.length === 16) return { type: \"mat4\", value: input };\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n if (isExplicitUniform(input)) {\n return { type: input.type, value: input.value };\n }\n\n if (Array.isArray(input)) {\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n return { type: \"float\", value: [0] };\n};\n\nexport const applyUniform = (\n gl: WebGLRenderingContext,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n const value = uniform.value;\n\n switch (uniform.type) {\n case \"float\":\n gl.uniform1f(location, value[0] ?? 0);\n break;\n case \"vec2\":\n gl.uniform2f(location, value[0] ?? 0, value[1] ?? 0);\n break;\n case \"vec3\":\n gl.uniform3f(location, value[0] ?? 0, value[1] ?? 0, value[2] ?? 0);\n break;\n case \"vec4\":\n gl.uniform4f(\n location,\n value[0] ?? 0,\n value[1] ?? 0,\n value[2] ?? 0,\n value[3] ?? 0\n );\n break;\n case \"mat3\":\n gl.uniformMatrix3fv(location, false, value);\n break;\n case \"mat4\":\n gl.uniformMatrix4fv(location, false, value);\n break;\n }\n};\n\nexport const applyProgramUniform = (\n gl: WebGLRenderingContext,\n program: WebGLProgram,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n gl.useProgram(program);\n applyUniform(gl, location, uniform);\n};\n\nexport const collectUniformLocations = (\n gl: WebGLRenderingContext,\n program: WebGLProgram\n): Map<string, WebGLUniformLocation> => {\n const locations = new Map<string, WebGLUniformLocation>();\n const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS) as number;\n\n for (let index = 0; index < count; index += 1) {\n const active = gl.getActiveUniform(program, index);\n if (!active) continue;\n\n const name = active.name.replace(/\\[0\\]$/, \"\");\n const location = gl.getUniformLocation(program, name);\n if (location) {\n locations.set(name, location);\n }\n }\n\n return locations;\n};\n\nexport const createUniformCache = (\n uniforms: Record<string, UniformInput> | undefined\n): Map<string, NormalizedUniform> => {\n const cache = new Map<string, NormalizedUniform>();\n\n for (const [name, value] of Object.entries(uniforms ?? {})) {\n cache.set(toUniformName(name), normalizeUniform(value));\n }\n\n return cache;\n};\n\nconst isExplicitUniform = (input: unknown): input is ExplicitUniformInput => {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) return false;\n return \"type\" in input && \"value\" in input;\n};\n","import { ShaderCompileError } from \"./errors\";\n\nexport const defaultVertexShader = `\nattribute vec2 a_position;\nvarying vec2 v_uv;\n\nvoid main() {\n v_uv = a_position * 0.5 + 0.5;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}\n`;\n\nexport const createProgram = (\n gl: WebGLRenderingContext,\n vertexSource: string,\n fragmentSource: string\n): WebGLProgram => {\n const vertex = compileShader(gl, gl.VERTEX_SHADER, vertexSource);\n const fragment = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);\n const program = gl.createProgram();\n\n if (!program) {\n throw new ShaderCompileError(\"Failed to create WebGL program.\");\n }\n\n gl.attachShader(program, vertex);\n gl.attachShader(program, fragment);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const log = gl.getProgramInfoLog(program) ?? \"Unknown program link error.\";\n gl.deleteProgram(program);\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n throw new ShaderCompileError(log);\n }\n\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n return program;\n};\n\nexport const createFullscreenBuffer = (\n gl: WebGLRenderingContext,\n program: WebGLProgram\n): WebGLBuffer => {\n const buffer = gl.createBuffer();\n if (!buffer) {\n throw new ShaderCompileError(\"Failed to create fullscreen buffer.\");\n }\n\n const location = gl.getAttribLocation(program, \"a_position\");\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]),\n gl.STATIC_DRAW\n );\n\n if (location >= 0) {\n gl.enableVertexAttribArray(location);\n gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n};\n\nconst compileShader = (\n gl: WebGLRenderingContext,\n type: number,\n source: string\n): WebGLShader => {\n const shader = gl.createShader(type);\n if (!shader) {\n throw new ShaderCompileError(\"Failed to create WebGL shader.\");\n }\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const log = gl.getShaderInfoLog(shader) ?? \"Unknown shader compile error.\";\n gl.deleteShader(shader);\n throw new ShaderCompileError(log);\n }\n\n return shader;\n};\n","import type {\n CreateShaderBackgroundOptions,\n RenderState,\n ShaderBackgroundInstance,\n ShaderStatus,\n TextureInput,\n TextureMap,\n UniformInput,\n UniformInputMap,\n UniformRuntimeValue\n} from \"./types\";\nimport {\n DestroyedError,\n TargetNotFoundError,\n TextureLoadError,\n UnsupportedError\n} from \"./internal/errors\";\nimport {\n resolveDpr,\n resizeCanvasToTarget,\n setupCanvas,\n type DomSetup\n} from \"./internal/dom\";\nimport { toUniformName } from \"./internal/names\";\nimport { loadTexture, type LoadedTexture } from \"./internal/textures\";\nimport {\n applyProgramUniform,\n applyUniform,\n collectUniformLocations,\n createUniformCache,\n normalizeUniform,\n type NormalizedUniform\n} from \"./internal/uniforms\";\nimport {\n createFullscreenBuffer,\n createProgram,\n defaultVertexShader\n} from \"./internal/webgl\";\n\nconst MAX_DELTA_SECONDS = 0.1;\n\nexport const createShaderBackground = <\n TUniforms extends UniformInputMap = UniformInputMap\n>(\n options: CreateShaderBackgroundOptions<TUniforms>\n): ShaderBackgroundInstance<TUniforms> => {\n return new ShaderBackground<TUniforms>(options);\n};\n\nclass ShaderBackground<TUniforms extends UniformInputMap>\n implements ShaderBackgroundInstance<TUniforms>\n{\n readonly ready: Promise<void>;\n\n private readonly options: CreateShaderBackgroundOptions<TUniforms>;\n private readonly uniformCache: Map<string, NormalizedUniform>;\n private readonly warnedUniforms = new Set<string>();\n private readyResolve: (() => void) | null = null;\n private readyReject: ((error: Error) => void) | null = null;\n private dom: DomSetup | null = null;\n private program: WebGLProgram | null = null;\n private buffer: WebGLBuffer | null = null;\n private attribLocation = -1;\n private uniformLocations = new Map<string, WebGLUniformLocation>();\n private textureInputs = new Map<string, TextureInput>();\n private textures = new Map<string, LoadedTexture>();\n private textureUnits = new Map<string, number>();\n private textureVersions = new Map<string, number>();\n private resizeObserver: ResizeObserver | null = null;\n private intersectionObserver: IntersectionObserver | null = null;\n private rafId = 0;\n private running = false;\n private inRender = false;\n private destroyed = false;\n private onscreen = true;\n private frame = 0;\n private elapsed = 0;\n private lastTimestamp = 0;\n private pixelRatio = 1;\n private width = 1;\n private height = 1;\n private viewportWidth = 1;\n private viewportHeight = 1;\n private pointer = { x: 0, y: 0, uvX: 0, uvY: 0, active: 0 };\n private removeListeners: Array<() => void> = [];\n private currentStatus: ShaderStatus = \"idle\";\n private contextRestoredShouldRun = false;\n\n constructor(options: CreateShaderBackgroundOptions<TUniforms>) {\n this.options = options;\n this.uniformCache = createUniformCache(options.uniforms);\n this.ready = new Promise<void>((resolve, reject) => {\n this.readyResolve = resolve;\n this.readyReject = reject;\n });\n\n queueMicrotask(() => {\n void this.init();\n });\n }\n\n get canvas(): HTMLCanvasElement | null {\n return this.dom?.canvas ?? null;\n }\n\n get gl(): WebGLRenderingContext | null {\n return this.dom?.canvas.getContext(\"webgl\") ?? null;\n }\n\n get status(): ShaderStatus {\n return this.currentStatus;\n }\n\n get supported(): boolean {\n return ![\"unsupported\", \"destroyed\"].includes(this.currentStatus);\n }\n\n start(): void {\n if (this.destroyed || this.currentStatus === \"unsupported\") return;\n this.running = true;\n\n if (!this.onscreen && (this.options.pauseWhenOffscreen ?? true)) {\n this.currentStatus = \"paused\";\n return;\n }\n\n if (this.options.renderMode === \"demand\") {\n this.currentStatus = \"running\";\n this.render();\n return;\n }\n\n this.currentStatus = \"running\";\n this.scheduleFrame();\n }\n\n stop(): void {\n this.running = false;\n this.cancelFrame();\n if (!this.destroyed && this.currentStatus !== \"unsupported\") {\n this.currentStatus = \"paused\";\n }\n }\n\n render(): void {\n if (\n this.destroyed ||\n !this.dom ||\n !this.program ||\n this.currentStatus === \"unsupported\" ||\n (this.options.pauseWhenOffscreen ?? true) && !this.onscreen\n ) {\n return;\n }\n\n const gl = this.dom.canvas.getContext(\"webgl\");\n if (!gl) return;\n\n this.inRender = true;\n this.resize();\n // Reset to the default framebuffer each frame so a render-target left bound\n // by an extension (e.g. in onAfterRender) cannot leak into this frame.\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.viewport(0, 0, this.width, this.height);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.useProgram(this.program);\n this.applyBuiltInUniforms(gl);\n\n const state = this.createRenderState(gl);\n this.options.onBeforeRender?.(state);\n // Re-establish all of the core's draw state after the user hook so any GL\n // side-effects (program, array buffer, attrib pointer, textures) cannot\n // corrupt the core draw. This is what makes the core a safe FBO host.\n this.prepareDrawState(gl);\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n this.options.onAfterRender?.(state);\n this.frame += 1;\n this.inRender = false;\n }\n\n resize(): void {\n if (this.destroyed || !this.dom) return;\n this.pixelRatio = resolveDpr(this.options.dpr, this.options.maxDpr);\n const size = resizeCanvasToTarget(\n this.dom.canvas,\n this.dom.target,\n this.pixelRatio\n );\n this.width = size.width;\n this.height = size.height;\n this.viewportWidth = size.viewportWidth;\n this.viewportHeight = size.viewportHeight;\n\n if (this.options.renderMode === \"demand\" && !this.inRender) {\n this.render();\n }\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.running = false;\n this.cancelFrame();\n this.resizeObserver?.disconnect();\n this.intersectionObserver?.disconnect();\n\n for (const remove of this.removeListeners) remove();\n this.removeListeners = [];\n\n const gl = this.dom?.canvas.getContext(\"webgl\");\n if (gl) {\n for (const texture of this.textures.values()) {\n gl.deleteTexture(texture.texture);\n }\n if (this.buffer) gl.deleteBuffer(this.buffer);\n if (this.program) gl.deleteProgram(this.program);\n }\n\n if (this.dom?.createdCanvas) {\n this.dom.canvas.remove();\n }\n\n const dom = this.dom;\n if (dom?.restoredPosition !== null && dom && this.options.target) {\n const target = dom.target as HTMLElement;\n target.style.position = dom.restoredPosition;\n }\n\n this.currentStatus = \"destroyed\";\n this.readyReject?.(new DestroyedError(\"Shader background was destroyed.\"));\n }\n\n setUniform<K extends keyof TUniforms & string>(\n name: K,\n value: UniformRuntimeValue<TUniforms[K]>\n ): void;\n setUniform(name: string, value: UniformInput): void;\n setUniform(name: string, value: UniformInput): void {\n if (this.destroyed) return;\n const uniformName = toUniformName(name);\n this.uniformCache.set(uniformName, normalizeUniform(value));\n\n const gl = this.dom?.canvas.getContext(\"webgl\");\n const location = this.uniformLocations.get(uniformName);\n if (gl && this.program && location) {\n applyProgramUniform(\n gl,\n this.program,\n location,\n this.uniformCache.get(uniformName)!\n );\n } else if (this.program) {\n this.warnUnknownUniform(uniformName);\n }\n\n if (\n this.options.renderMode === \"demand\" &&\n !this.inRender &&\n this.onscreen\n ) {\n this.render();\n }\n }\n\n setUniforms(values: Record<string, UniformInput>): void {\n for (const [name, value] of Object.entries(values)) {\n this.setUniform(name, value);\n }\n }\n\n async setTexture(name: string, input: TextureInput): Promise<void> {\n if (this.destroyed) return;\n\n let gl = this.dom?.canvas.getContext(\"webgl\");\n if (!gl) {\n await this.ready;\n if (this.destroyed) return;\n gl = this.dom?.canvas.getContext(\"webgl\");\n }\n\n if (!gl) {\n const error = new TextureLoadError(\n \"Cannot set texture before WebGL is ready.\"\n );\n this.options.onError?.(error);\n throw error;\n }\n\n const version = (this.textureVersions.get(name) ?? 0) + 1;\n this.textureVersions.set(name, version);\n\n try {\n const unit = this.resolveTextureUnit(gl, name);\n const loaded = await loadTexture(gl, name, input, unit);\n\n if (this.destroyed || this.textureVersions.get(name) !== version) {\n gl.deleteTexture(loaded.texture);\n return;\n }\n\n const previous = this.textures.get(name);\n this.textureInputs.set(name, input);\n this.textures.set(name, loaded);\n if (previous) gl.deleteTexture(previous.texture);\n this.applyTextureSizeUniform(loaded);\n\n if (\n this.options.renderMode === \"demand\" &&\n !this.inRender &&\n this.onscreen\n ) {\n this.render();\n }\n } catch (error) {\n if (!this.textures.has(name) && !this.textureInputs.has(name)) {\n this.textureUnits.delete(name);\n }\n const normalized =\n error instanceof Error ? error : new Error(String(error));\n this.options.onError?.(normalized);\n throw normalized;\n }\n }\n\n async setTextures(values: TextureMap): Promise<void> {\n await Promise.all(\n Object.entries(values).map(([name, input]) =>\n this.setTexture(name, input)\n )\n );\n }\n\n private async init(): Promise<void> {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n this.failUnsupported(new UnsupportedError(\"WebGL requires a browser.\"));\n return;\n }\n\n this.dom = setupCanvas(this.options);\n if (!this.dom) {\n this.failUnsupported(new TargetNotFoundError(\"Target or canvas not found.\"));\n return;\n }\n\n const gl = this.dom.canvas.getContext(\"webgl\", {\n alpha: true,\n antialias: false,\n depth: false,\n stencil: false,\n premultipliedAlpha: true,\n preserveDrawingBuffer: false\n });\n\n if (!gl) {\n this.failUnsupported(new UnsupportedError(\"WebGL is not supported.\"));\n return;\n }\n\n this.currentStatus = \"loading\";\n\n try {\n this.setupDomObservers();\n this.setupContextEvents();\n this.setupProgram(gl);\n this.resize();\n this.textureInputs = new Map(Object.entries(this.options.textures ?? {}));\n await this.loadTextureInputs(gl);\n if (this.destroyed) return;\n this.applyTextureSizeUniforms();\n this.currentStatus = \"ready\";\n this.readyResolve?.();\n this.options.onReady?.(this);\n\n if (this.running || (this.options.autoStart ?? true)) {\n this.start();\n } else if (this.options.renderMode === \"demand\") {\n this.render();\n }\n } catch (error) {\n this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n private setupProgram(gl: WebGLRenderingContext): void {\n if (this.program) gl.deleteProgram(this.program);\n if (this.buffer) gl.deleteBuffer(this.buffer);\n\n this.program = createProgram(\n gl,\n this.options.vertex ?? defaultVertexShader,\n this.options.fragment\n );\n gl.useProgram(this.program);\n this.buffer = createFullscreenBuffer(gl, this.program);\n this.attribLocation = gl.getAttribLocation(this.program, \"a_position\");\n this.uniformLocations = collectUniformLocations(gl, this.program);\n }\n\n // Re-bind the core's program, fullscreen geometry, textures and uniforms so a\n // draw is correct regardless of GL state changed by onBeforeRender/onAfterRender.\n private prepareDrawState(gl: WebGLRenderingContext): void {\n if (!this.program) return;\n gl.useProgram(this.program);\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n if (this.attribLocation >= 0) {\n gl.enableVertexAttribArray(this.attribLocation);\n gl.vertexAttribPointer(this.attribLocation, 2, gl.FLOAT, false, 0, 0);\n }\n this.applyTextures(gl);\n this.applyCachedUniforms(gl);\n }\n\n private setupDomObservers(): void {\n if (!this.dom) return;\n\n if (this.options.autoResize ?? true) {\n this.resizeObserver = new ResizeObserver(() => {\n this.resize();\n });\n this.resizeObserver.observe(this.dom.target);\n }\n\n if (this.options.pauseWhenOffscreen ?? true) {\n this.intersectionObserver = new IntersectionObserver((entries) => {\n const entry = entries[0];\n this.onscreen = Boolean(entry?.isIntersecting);\n if (!this.onscreen) {\n this.cancelFrame();\n if (this.running) this.currentStatus = \"paused\";\n return;\n }\n\n if (this.running) {\n this.start();\n } else if (this.options.renderMode === \"demand\") {\n this.render();\n }\n });\n this.intersectionObserver.observe(this.dom.target);\n }\n\n const onPointerMove = (event: Event) => {\n if (!this.dom) return;\n const pointerEvent = event as PointerEvent;\n const rect = this.dom.target.getBoundingClientRect();\n const x = pointerEvent.clientX - rect.left;\n const y = pointerEvent.clientY - rect.top;\n this.pointer.x = x * this.pixelRatio;\n this.pointer.y = (rect.height - y) * this.pixelRatio;\n this.pointer.uvX = rect.width > 0 ? x / rect.width : 0;\n this.pointer.uvY = rect.height > 0 ? 1 - y / rect.height : 0;\n this.pointer.active = 1;\n\n if (this.options.renderMode === \"demand\") this.render();\n };\n const onPointerLeave = () => {\n this.pointer.active = 0;\n if (this.options.renderMode === \"demand\") this.render();\n };\n\n this.dom.target.addEventListener(\"pointermove\", onPointerMove);\n this.dom.target.addEventListener(\"pointerenter\", onPointerMove);\n this.dom.target.addEventListener(\"pointerleave\", onPointerLeave);\n this.removeListeners.push(() => {\n this.dom?.target.removeEventListener(\"pointermove\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerenter\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerleave\", onPointerLeave);\n });\n }\n\n private setupContextEvents(): void {\n if (!this.dom) return;\n\n const onLost = (event: Event) => {\n event.preventDefault();\n this.contextRestoredShouldRun = this.running;\n this.cancelFrame();\n this.currentStatus = \"context-lost\";\n this.options.onError?.(new UnsupportedError(\"WebGL context lost.\"));\n };\n\n const onRestored = () => {\n if (!this.dom || this.destroyed) return;\n const gl = this.dom.canvas.getContext(\"webgl\");\n if (!gl) return;\n\n try {\n this.setupProgram(gl);\n this.applyCachedUniforms(gl);\n void this.loadTextureInputs(gl).then(\n () => {\n this.applyTextureSizeUniforms();\n if (this.contextRestoredShouldRun) this.start();\n else this.render();\n },\n (error: unknown) =>\n this.fail(error instanceof Error ? error : new Error(String(error)))\n );\n } catch (error) {\n this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n };\n\n this.dom.canvas.addEventListener(\"webglcontextlost\", onLost);\n this.dom.canvas.addEventListener(\"webglcontextrestored\", onRestored);\n this.removeListeners.push(() => {\n this.dom?.canvas.removeEventListener(\"webglcontextlost\", onLost);\n this.dom?.canvas.removeEventListener(\"webglcontextrestored\", onRestored);\n });\n }\n\n private scheduleFrame(): void {\n if (this.rafId || this.options.renderMode === \"demand\") return;\n\n this.rafId = requestAnimationFrame((timestamp) => {\n this.rafId = 0;\n if (!this.running || this.destroyed) return;\n\n const seconds = timestamp / 1000;\n const rawDelta = this.lastTimestamp ? seconds - this.lastTimestamp : 0;\n const delta = Math.min(Math.max(rawDelta, 0), MAX_DELTA_SECONDS);\n this.lastTimestamp = seconds;\n this.elapsed += delta;\n this.setBuiltInTime(delta);\n this.render();\n this.scheduleFrame();\n });\n }\n\n private cancelFrame(): void {\n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = 0;\n }\n this.lastTimestamp = 0;\n }\n\n private setBuiltInTime(delta: number): void {\n this.uniformCache.set(\"u_time\", { type: \"float\", value: [this.elapsed] });\n this.uniformCache.set(\"u_delta\", { type: \"float\", value: [delta] });\n }\n\n private applyBuiltInUniforms(gl: WebGLRenderingContext): void {\n const builtIns: Record<string, UniformInput> = {\n resolution: [this.width, this.height],\n viewportSize: [this.viewportWidth, this.viewportHeight],\n pixelRatio: this.pixelRatio,\n pointer: [this.pointer.x, this.pointer.y],\n pointerUv: [this.pointer.uvX, this.pointer.uvY],\n pointerActive: this.pointer.active\n };\n\n for (const [name, value] of Object.entries(builtIns)) {\n this.uniformCache.set(toUniformName(name), normalizeUniform(value));\n }\n\n this.applyCachedUniforms(gl);\n }\n\n private applyTextureSizeUniforms(): void {\n for (const texture of this.textures.values()) {\n this.applyTextureSizeUniform(texture);\n }\n }\n\n private applyTextureSizeUniform(texture: LoadedTexture): void {\n const uniform = {\n type: \"vec2\" as const,\n value: [texture.width, texture.height]\n };\n this.uniformCache.set(texture.sizeUniformName, uniform);\n\n const gl = this.dom?.canvas.getContext(\"webgl\");\n const location = this.uniformLocations.get(texture.sizeUniformName);\n if (gl && this.program && location) {\n applyProgramUniform(gl, this.program, location, uniform);\n } else if (this.program) {\n this.warnUnknownUniform(texture.sizeUniformName);\n }\n }\n\n private applyCachedUniforms(gl: WebGLRenderingContext): void {\n for (const [name, uniform] of this.uniformCache) {\n const location = this.uniformLocations.get(name);\n if (!location) {\n this.warnUnknownUniform(name);\n continue;\n }\n applyUniform(gl, location, uniform);\n }\n }\n\n private applyTextures(gl: WebGLRenderingContext): void {\n for (const texture of this.textures.values()) {\n const unit = this.textureUnits.get(texture.name);\n if (unit === undefined) continue;\n const location = this.uniformLocations.get(texture.uniformName);\n if (!location) {\n this.warnUnknownUniform(texture.uniformName);\n continue;\n }\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture.texture);\n gl.uniform1i(location, unit);\n }\n }\n\n private async loadTextureInputs(gl: WebGLRenderingContext): Promise<void> {\n const loadedTextures = new Map<string, LoadedTexture>();\n\n for (const [name, input] of this.textureInputs) {\n if (this.destroyed) break;\n const unit = this.resolveTextureUnit(gl, name);\n loadedTextures.set(name, await loadTexture(gl, name, input, unit));\n }\n\n for (const texture of this.textures.values()) {\n gl.deleteTexture(texture.texture);\n }\n this.textures = loadedTextures;\n }\n\n private resolveTextureUnit(gl: WebGLRenderingContext, name: string): number {\n const existing = this.textureUnits.get(name);\n if (existing !== undefined) return existing;\n\n const maxUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) as number;\n\n for (let unit = 0; unit < maxUnits; unit += 1) {\n if (![...this.textureUnits.values()].includes(unit)) {\n this.textureUnits.set(name, unit);\n return unit;\n }\n }\n\n throw new TextureLoadError(\n `Texture unit limit exceeded while loading texture: ${name}`\n );\n }\n\n private createRenderState(\n gl: WebGLRenderingContext\n ): RenderState<TUniforms> {\n return {\n instance: this,\n gl,\n canvas: this.dom!.canvas,\n time: this.elapsed,\n delta: this.uniformCache.get(\"u_delta\")?.value[0] ?? 0,\n frame: this.frame,\n width: this.width,\n height: this.height,\n viewportWidth: this.viewportWidth,\n viewportHeight: this.viewportHeight,\n pixelRatio: this.pixelRatio\n };\n }\n\n private warnUnknownUniform(name: string): void {\n if (!this.options.debug || this.warnedUniforms.has(name)) return;\n this.warnedUniforms.add(name);\n console.warn(`[frapx/shader] Uniform not found or optimized out: ${name}`);\n }\n\n private failUnsupported(error: Error): void {\n this.currentStatus = \"unsupported\";\n this.debugWarn(error.message);\n this.options.onError?.(error);\n this.readyReject?.(error);\n }\n\n private fail(error: Error): void {\n this.currentStatus = \"error\";\n this.debugWarn(error.message);\n this.options.onError?.(error);\n this.readyReject?.(error);\n }\n\n private debugWarn(message: string): void {\n if (this.options.debug) {\n console.warn(`[frapx/shader] ${message}`);\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frapx/shader",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Lightweight WebGL shader background runtime for websites.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"webgl",
|
|
@@ -21,6 +21,10 @@
|
|
|
21
21
|
"./glsl": {
|
|
22
22
|
"types": "./dist/glsl.d.ts",
|
|
23
23
|
"import": "./dist/glsl.js"
|
|
24
|
+
},
|
|
25
|
+
"./color": {
|
|
26
|
+
"types": "./dist/color.d.ts",
|
|
27
|
+
"import": "./dist/color.js"
|
|
24
28
|
}
|
|
25
29
|
},
|
|
26
30
|
"files": [
|