@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 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":[]}
@@ -0,0 +1,6 @@
1
+ type Rgb = [number, number, number];
2
+ type Rgba = [number, number, number, number];
3
+ declare const hexToRgb: (hex: string) => Rgb;
4
+ declare const hexToRgba: (hex: string) => Rgba;
5
+
6
+ export { type Rgb, type Rgba, hexToRgb, hexToRgba };
package/dist/color.js ADDED
@@ -0,0 +1,9 @@
1
+ import {
2
+ hexToRgb,
3
+ hexToRgba
4
+ } from "./chunk-MPWD3FIT.js";
5
+ export {
6
+ hexToRgb,
7
+ hexToRgba
8
+ };
9
+ //# sourceMappingURL=color.js.map
@@ -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.textures = [];
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.applyCachedUniforms(gl);
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) gl.deleteTexture(texture.texture);
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
- applyUniform(gl, location, this.uniformCache.get(uniformName));
451
- } else {
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.textures = await loadTextures(
492
- gl,
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 loadTextures(gl, this.options.textures, () => this.destroyed).then(
590
- (textures) => {
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.uniformCache.set(texture.sizeUniformName, {
652
- type: "vec2",
653
- value: [texture.width, texture.height]
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 (let unit = 0; unit < this.textures.length; unit += 1) {
669
- const texture = this.textures[unit];
670
- if (!texture) continue;
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) continue;
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.1.1",
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": [