react-video-ascii 1.3.0 → 1.5.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
@@ -30,6 +30,12 @@ import { VideoAscii } from 'react-video-ascii';
30
30
  const sources = ['/video1.mp4', '/video2.mp4'];
31
31
  <VideoAscii src={sources} />
32
32
 
33
+ // Sample an element you already loaded instead of a URL
34
+ // (swap between preloaded elements without any reload)
35
+ const [video, setVideo] = useState<HTMLVideoElement | null>(null);
36
+ <video ref={setVideo} src="/video.mp4" muted playsInline preload="auto" hidden />
37
+ <VideoAscii media={video} />
38
+
33
39
  // With options
34
40
  <VideoAscii
35
41
  src="/video.mp4"
@@ -65,12 +71,17 @@ const sources = ['/video1.mp4', '/video2.mp4'];
65
71
 
66
72
  > **Note 2:** The component fills its parent container. Control size via the parent element or the `className` prop.
67
73
 
74
+ > **Note 3:** With `media`, VideoAscii calls `play()` on a video when it starts sampling it and never pauses it; pausing, muting and loading are up to you. Changing `media` (or `src`) only uploads the new texture; the WebGL context, shaders and glyph atlas are kept.
75
+
76
+ > **Note 4:** `paused` only stops the render loop; the WebGL context, shaders and media are still set up, so a paused instance can be mounted early (even hidden with `display: none`) and shown later with no delay. A `src` video is paused and resumed along with the render loop. A `media` video is left to you, apart from the `play()` call when sampling starts. A reveal effect starts when the first frame is drawn, so it plays on unpause rather than while paused.
77
+
68
78
  ## Props
69
79
 
70
80
  | Prop | Type | Default | Range | Description |
71
81
  |------|------|---------|-------|-------------|
72
- | `src` | `string \| string[]` | — | — | Video or image source URL(s). Multiple video URLs play sequentially. |
82
+ | `src` | `string \| string[]` | — | — | Video or image source URL(s). Multiple video URLs play sequentially. Required unless `media` is given. |
73
83
  | `mediaType` | `'auto' \| 'video' \| 'image'` | `'auto'` | — | How to load `src`. `auto` treats common image extensions as images and everything else as video. |
84
+ | `media` | `HTMLVideoElement \| HTMLImageElement \| null` | — | — | A loaded element to sample instead of `src`. Pass `null` while it isn't ready. |
74
85
  | `videoMode` | `boolean` | `false` | — | Show original video/image colors instead of ASCII. |
75
86
  | `numColsRaw` | `number` | `250` | `20–350` | Number of character columns. |
76
87
  | `brightnessRaw` | `number` | `1.0` | `0.0–2.0` | Brightness multiplier. |
@@ -83,6 +94,7 @@ const sources = ['/video1.mp4', '/video2.mp4'];
83
94
  | `revealEffect` | `boolean \| RevealEffectOptions` | `false` | — | Reveal animation on load. `true` uses defaults. |
84
95
  | `cropFocus` | `'left' \| 'center' \| 'right'` | `'center'` | — | Determines where to anchor the cropping around. |
85
96
  | `maxDpr` | `number` | *(uncapped)* | `1–4` | Caps the device-pixel ratio the canvas renders at (renders normally at sharpest res). |
97
+ | `paused` | `boolean` | `false` | — | Stops drawing frames while `true`. Setup and loading still happen, so unpausing is instant. |
86
98
  | `className` | `string` | — | — | CSS class on the outer container. |
87
99
 
88
100
  ---
@@ -1,3 +1,3 @@
1
1
  import { Props } from '../lib/ascii-props';
2
- declare function VideoAscii({ src, mediaType, videoMode, numColsRaw, brightnessRaw, saturationRaw, bgOpacityRaw, revealEffect, chars, mouseEffect, clickEffect, charMode, className, cropFocus, maxDpr: maxDprRaw, }: Props): import("react/jsx-runtime").JSX.Element;
2
+ declare function VideoAscii({ src, mediaType, media: mediaProp, videoMode, numColsRaw, brightnessRaw, saturationRaw, bgOpacityRaw, revealEffect, chars, mouseEffect, clickEffect, charMode, className, cropFocus, maxDpr: maxDprRaw, paused, }: Props): import("react/jsx-runtime").JSX.Element;
3
3
  export default VideoAscii;
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { default as VideoAscii } from './components/VideoAscii';
2
- export type { Props, MediaType } from './lib/ascii-props';
2
+ export type { Props, SourceProps, ElementProps, MediaType } from './lib/ascii-props';
@@ -21,9 +21,7 @@ export interface RevealEffectOptions {
21
21
  }
22
22
  export type MediaType = 'auto' | 'video' | 'image';
23
23
  export declare function resolveMediaType(src: string | string[], mediaType: MediaType): 'video' | 'image';
24
- export interface Props {
25
- src: string | string[];
26
- mediaType?: MediaType;
24
+ interface BaseProps {
27
25
  videoMode?: boolean;
28
26
  numColsRaw?: number;
29
27
  brightnessRaw?: number;
@@ -37,7 +35,19 @@ export interface Props {
37
35
  className?: string;
38
36
  cropFocus?: 'left' | 'center' | 'right';
39
37
  maxDpr?: number;
38
+ paused?: boolean;
39
+ }
40
+ export interface SourceProps extends BaseProps {
41
+ src: string | string[];
42
+ mediaType?: MediaType;
43
+ media?: undefined;
44
+ }
45
+ export interface ElementProps extends BaseProps {
46
+ media: HTMLVideoElement | HTMLImageElement | null;
47
+ src?: undefined;
48
+ mediaType?: undefined;
40
49
  }
50
+ export type Props = SourceProps | ElementProps;
41
51
  export interface ParsedProps {
42
52
  numCols: number;
43
53
  brightness: number;
@@ -66,3 +76,4 @@ export interface ParsedProps {
66
76
  maxDpr: number;
67
77
  }
68
78
  export declare function parseProps(numColsRaw: number, brightnessRaw: number, saturationRaw: number, bgOpacityRaw: number, mouseEffect: boolean | MouseEffectOptions, clickEffect: boolean | ClickEffectOptions, revealEffect: boolean | RevealEffectOptions, maxDprRaw?: number): ParsedProps;
79
+ export {};
@@ -14,6 +14,7 @@ interface MouseTrailRefs {
14
14
  }
15
15
  export declare function createMouseTrail({ brightenEnabledRef, trailLenRef, durationRef, trailDecayRef, }: MouseTrailRefs): {
16
16
  handleMouseMove(x: number, y: number, t: number): void;
17
+ reset(): void;
17
18
  tick(gl: WebGL2RenderingContext, mousePositionsLoc: WebGLUniformLocation | null, mouseLifeFracsLoc: WebGLUniformLocation | null): void;
18
19
  };
19
20
  export {};
@@ -14,6 +14,7 @@ interface ClickEffectRefs {
14
14
  }
15
15
  export declare function createClickEffect({ clickEnabledRef, clickSpeedRef, clickBrightnessRef, pixelScaleRef, }: ClickEffectRefs): {
16
16
  handleClick(e: MouseEvent, canvas: HTMLCanvasElement): void;
17
+ reset(): void;
17
18
  tick(gl: WebGL2RenderingContext, canvas: HTMLCanvasElement, ripplePositionsLoc: WebGLUniformLocation | null, rippleRadiiLoc: WebGLUniformLocation | null, rippleBrightnessesLoc: WebGLUniformLocation | null): void;
18
19
  };
19
20
  export {};
@@ -57,14 +57,14 @@ function c(e, t) {
57
57
  return s.test(n) ? "image" : "video";
58
58
  }
59
59
  function l(e, t, n, r, i, a, o, s) {
60
- let c = !!i, l = typeof i == "object" ? i : {}, u = l.style ?? "brighten", d = c && u !== "scatter", f = c && u === "scatter", p = l.scatterChars ?? "->o", m = l.trailLen ?? 15, h = l.trailDecay ?? 10, g = l.duration ?? 1, _ = l.radius ?? (u === "scatter" ? .05 : .08), v = l.brightness ?? 2, y = !!a, b = typeof a == "object" ? a : {}, x = b.style ?? "ripple", S = y && x !== "spread", C = y && x === "spread", w = b.brightness ?? 1.1, T = b.speed ?? 2, E = b.spreadExpandDuration ?? 1.5, D = b.spreadSpeed ?? 7.5, O = !!o, k = typeof o == "object" ? o : {}, A = k.type ?? "random", j = k.duration ?? .4, M = Math.max(20, Math.min(350, Math.round(e))), ee = Math.max(0, Math.min(2, t)), te = Math.max(0, Math.min(2, n)), N = Math.max(0, Math.min(1, r));
60
+ let c = !!i, l = typeof i == "object" ? i : {}, u = l.style ?? "brighten", d = c && u !== "scatter", f = c && u === "scatter", p = l.scatterChars ?? "->o", m = l.trailLen ?? 15, h = l.trailDecay ?? 10, g = l.duration ?? 1, _ = l.radius ?? (u === "scatter" ? .05 : .08), v = l.brightness ?? 2, y = !!a, b = typeof a == "object" ? a : {}, x = b.style ?? "ripple", S = y && x !== "spread", C = y && x === "spread", w = b.brightness ?? 1.1, T = b.speed ?? 2, E = b.spreadExpandDuration ?? 1.5, D = b.spreadSpeed ?? 7.5, O = !!o, k = typeof o == "object" ? o : {}, A = k.type ?? "random", j = k.duration ?? .4, M = Math.max(20, Math.min(350, Math.round(e))), N = Math.max(0, Math.min(2, t)), P = Math.max(0, Math.min(2, n)), ee = Math.max(0, Math.min(1, r));
61
61
  j = Math.max(.1, Math.min(4, j)), m = Math.max(0, Math.min(30, Math.round(m))), h = Math.max(1, Math.min(15, h)), g = Math.max(.1, Math.min(4, g)), _ = Math.max(.03, Math.min(.2, _)), v = Math.max(.2, Math.min(5, v)), w = Math.max(1.05, Math.min(2, w)), T = Math.max(.5, Math.min(4, T)), E = Math.max(.5, Math.min(5, E)), D = Math.max(.5, Math.min(10, D));
62
- let P = s === void 0 ? Infinity : Math.max(1, Math.min(4, s)), F;
62
+ let te = s === void 0 ? Infinity : Math.max(1, Math.min(4, s)), F;
63
63
  return F = O ? A === "diagonal" ? 1 : A === "radial" ? 2 : 3 : 0, {
64
64
  numCols: M,
65
- brightness: ee,
66
- saturation: te,
67
- bgOpacity: N,
65
+ brightness: N,
66
+ saturation: P,
67
+ bgOpacity: ee,
68
68
  mouseEnabled: c,
69
69
  mouseStyle: u,
70
70
  brightenEnabled: d,
@@ -85,7 +85,7 @@ function l(e, t, n, r, i, a, o, s) {
85
85
  revealType: A,
86
86
  revealDuration: j,
87
87
  revealEffectFlag: F,
88
- maxDpr: P
88
+ maxDpr: te
89
89
  };
90
90
  }
91
91
  //#endregion
@@ -269,6 +269,9 @@ function _({ brightenEnabledRef: e, trailLenRef: t, durationRef: n, trailDecayRe
269
269
  t: a
270
270
  }), i.length > t.current && i.shift());
271
271
  },
272
+ reset() {
273
+ i.length = 0;
274
+ },
272
275
  tick(a, o, s) {
273
276
  if (!e.current) return;
274
277
  let c = performance.now(), l = new Float32Array(t.current * 2), u = new Float32Array(t.current);
@@ -295,6 +298,9 @@ function y({ clickEnabledRef: e, clickSpeedRef: t, clickBrightnessRef: n, pixelS
295
298
  t: performance.now()
296
299
  }), i.length > v && i.shift();
297
300
  },
301
+ reset() {
302
+ i.length = 0;
303
+ },
298
304
  tick(a, o, s, c, l) {
299
305
  if (!e.current) return;
300
306
  let u = performance.now(), d = Math.hypot(o.width, o.height), f = t.current * r.current, p = new Float32Array(v * 2), m = new Float32Array(v), h = new Float32Array(v);
@@ -399,196 +405,231 @@ function x(e, t) {
399
405
  }
400
406
  //#endregion
401
407
  //#region src/components/VideoAscii.tsx
402
- function S({ src: i, mediaType: s = "auto", videoMode: u = !1, numColsRaw: d = 250, brightnessRaw: f = 1, saturationRaw: p = 1, bgOpacityRaw: m = .3, revealEffect: v = !1, chars: S = o, mouseEffect: C = !0, clickEffect: w = !0, charMode: T = "shape", className: E, cropFocus: D = "center", maxDpr: O }) {
403
- let k = t(null), A = t(null), j = t(null), M = t(null), ee = t(null), te = t(null), { numCols: N, brightness: P, saturation: F, bgOpacity: I, mouseEnabled: L, mouseStyle: R, brightenEnabled: z, scatterEnabled: B, scatterChars: V, trailLen: H, trailDecay: U, duration: ne, mouseRadius: re, mouseBrightness: W, clickEnabled: G, clickBrightness: K, clickSpeed: q, spreadEnabled: J, spreadExpandDuration: Y, spreadSpeed: X, revealEnabled: ie, revealDuration: ae, revealEffectFlag: oe, maxDpr: Z } = l(d, f, p, m, C, w, v, O), se = c(i, s) === "image", ce = t(P), le = t(F), ue = t(I), de = t(L), fe = t(R), pe = t(z), me = t(B), he = t(W), ge = t(re), _e = t(H), ve = t(U), ye = t(ne), Q = t(V), be = t(G), xe = t(K), Se = t(q), Ce = t(J), we = t(Y), Te = t(X), Ee = t(N), De = t(u), Oe = t(D), ke = t(0), Ae = t(0), je = t(Z), Me = t(1), Ne = t(null), Pe = t(null);
408
+ function S({ src: i, mediaType: s = "auto", media: u, videoMode: d = !1, numColsRaw: f = 250, brightnessRaw: p = 1, saturationRaw: m = 1, bgOpacityRaw: v = .3, revealEffect: S = !1, chars: C = o, mouseEffect: w = !0, clickEffect: T = !0, charMode: E = "shape", className: D, cropFocus: O = "center", maxDpr: k, paused: A = !1 }) {
409
+ let j = t(null), M = t(null), N = t(null), P = t(null), ee = t(null), te = t(null), { numCols: F, brightness: I, saturation: L, bgOpacity: R, mouseEnabled: z, mouseStyle: ne, brightenEnabled: B, scatterEnabled: V, scatterChars: H, trailLen: U, trailDecay: W, duration: G, mouseRadius: K, mouseBrightness: q, clickEnabled: J, clickBrightness: Y, clickSpeed: re, spreadEnabled: ie, spreadExpandDuration: ae, spreadSpeed: oe, revealEnabled: se, revealDuration: ce, revealEffectFlag: le, maxDpr: ue } = l(f, p, m, v, w, T, S, k), X = i === void 0, de = i !== void 0 && c(i, s) === "image", fe = t(I), pe = t(L), me = t(R), he = t(z), ge = t(ne), _e = t(B), ve = t(V), ye = t(q), be = t(K), xe = t(U), Se = t(W), Ce = t(G), Z = t(H), we = t(J), Te = t(Y), Ee = t(re), De = t(ie), Oe = t(ae), ke = t(oe), Ae = t(F), je = t(d), Me = t(O), Ne = t(0), Pe = t(0), Fe = t(ue), Ie = t(1), Q = t(null), Le = t(null), Re = t(A), ze = t(null), Be = t(null), Ve = t(null), He = t(null), Ue = t(null);
404
410
  e(() => {
405
- ce.current = P, le.current = F, ue.current = I, de.current = L, fe.current = R, pe.current = z, me.current = B, he.current = W, ge.current = re, _e.current = H, ve.current = U, ye.current = ne, Q.current !== V && $.current ? (Q.current = V, Ie.current?.()) : Q.current = V, be.current = G, xe.current = K, Se.current = q, Ce.current = J, we.current = Y, Te.current = X, Ee.current = N, De.current = u;
411
+ fe.current = I, pe.current = L, me.current = R, he.current = z, ge.current = ne, _e.current = B, ve.current = V, ye.current = q, be.current = K, xe.current = U, Se.current = W, Ce.current = G, Z.current !== H && $.current ? (Z.current = H, Ge.current?.()) : Z.current = H, we.current = J, Te.current = Y, Ee.current = re, De.current = ie, Oe.current = ae, ke.current = oe, Ae.current = F, je.current = d;
406
412
  }, [
407
- P,
408
- F,
409
413
  I,
410
414
  L,
411
415
  R,
412
416
  z,
413
- B,
414
- W,
415
- re,
416
- H,
417
- U,
418
417
  ne,
418
+ B,
419
419
  V,
420
- G,
421
- K,
422
420
  q,
421
+ K,
422
+ U,
423
+ W,
424
+ G,
425
+ H,
423
426
  J,
424
427
  Y,
425
- X,
426
- N,
427
- u
428
+ re,
429
+ ie,
430
+ ae,
431
+ oe,
432
+ F,
433
+ d
428
434
  ]);
429
- let Fe = t(null), Ie = t(null), Le = t(null), $ = t(!1);
435
+ let We = t(null), Ge = t(null), Ke = t(null), $ = t(!1);
430
436
  e(() => {
431
- $.current && Fe.current?.(N);
432
- }, [N]), e(() => {
433
- Oe.current = D, $.current && ke.current > 0 && Le.current?.(ke.current, Ae.current);
434
- }, [D]), e(() => {
435
- je.current = Z, $.current && Ne.current && Pe.current?.(Ne.current);
436
- }, [Z]), e(() => {
437
+ $.current && We.current?.(F);
438
+ }, [F]), e(() => {
439
+ Me.current = O, $.current && Ne.current > 0 && Ke.current?.(Ne.current, Pe.current);
440
+ }, [O]), e(() => {
441
+ Fe.current = ue, $.current && Q.current && Le.current?.(Q.current);
442
+ }, [ue]), e(() => {
443
+ Re.current = A, A ? ze.current?.() : Be.current?.();
444
+ }, [A]), e(() => {
437
445
  $.current = !1;
438
- let e = [], t = 0, n = 0, r = 1, o = 1, s = 0, c = 0, l = 0, u = 0, d = k.current;
439
- if (!d) return;
440
- let f = se ? j.current : A.current;
446
+ let e = [], t = 0, n = 0, r = 1, i = 1, o = 0, s = 0, c = 0, l = 0, u = null, d = null, f = j.current;
441
447
  if (!f) return;
442
- let p = f instanceof HTMLVideoElement ? f : null, m = f instanceof HTMLImageElement ? f : null, v = () => f instanceof HTMLVideoElement ? {
443
- width: f.videoWidth,
444
- height: f.videoHeight
448
+ let p = () => u instanceof HTMLVideoElement ? {
449
+ width: u.videoWidth,
450
+ height: u.videoHeight
451
+ } : u ? {
452
+ width: u.naturalWidth,
453
+ height: u.naturalHeight
445
454
  } : {
446
- width: f.naturalWidth,
447
- height: f.naturalHeight
448
- }, C = d.getContext("webgl2");
449
- if (!C) return;
450
- C.pixelStorei(C.UNPACK_ALIGNMENT, 1);
451
- let w = h(C);
452
- if (!w) return;
453
- let { program: E, pass1Program: D } = w;
454
- ee.current = w.atlasTexture, te.current = w.scatterAtlasTexture, C.uniform1i(w.shapeMatchingLoc, +(T === "shape")), C.uniform1i(w.revealEffectFlagLoc, oe), C.uniform1f(w.revealProgressLoc, 0);
455
- let O = g({
456
- scatterEnabledRef: me,
457
- mouseRadiusRef: ge,
458
- durationRef: ye,
459
- scatterCharsRef: Q
460
- }), N = _({
461
- brightenEnabledRef: pe,
462
- trailLenRef: _e,
463
- durationRef: ye,
464
- trailDecayRef: ve
465
- }), P = y({
466
- clickEnabledRef: be,
467
- clickSpeedRef: Se,
468
- clickBrightnessRef: xe,
469
- pixelScaleRef: Me
470
- }), F = b({
471
- spreadEnabledRef: Ce,
472
- scatterCharsRef: Q,
473
- spreadExpandDurationRef: we,
474
- spreadSpeedRef: Te
475
- }), I, L = -1, R = -1, z = 0, B = Array.isArray(i) ? i : [i], V = B.length > 1, H = document.createElement("canvas"), U = H.getContext("2d"), ne = (i) => {
476
- let f = l > 0 ? l : d.width, p = u > 0 ? u : d.height;
477
- r = Math.max(1, Math.floor(f / i));
478
- let m = r * 2;
479
- if (U.font = `${m}px monospace`, o = Math.max(1, Math.round(m * r / U.measureText("M").width)), t = Math.ceil(f / r), n = Math.ceil(p / o), s = Math.floor((f - t * r) / 2), c = Math.floor((p - n * o) / 2), C.viewport(0, 0, d.width, d.height), C.useProgram(E), C.uniform2f(w.resLoc, d.width, d.height), C.uniform2f(w.gridOffsetLoc, s, c), C.useProgram(D), C.uniform2f(w.p1ResLoc, d.width, d.height), C.uniform2f(w.p1GridOffsetLoc, s, c), C.useProgram(E), O.setup(C, t, n, r, o, s, c, w.scatterStateTexture), F.setup(C, t, n, r, o, s, c, w.spreadStateTexture), T === "shape") {
480
- e = a(S, r, o);
481
- let i = e.length, s = new Float32Array(i * 8);
482
- for (let t = 0; t < i; t++) {
455
+ width: 0,
456
+ height: 0
457
+ }, m = f.getContext("webgl2");
458
+ if (!m) return;
459
+ m.pixelStorei(m.UNPACK_ALIGNMENT, 1);
460
+ let v = h(m);
461
+ if (!v) return;
462
+ let { program: S, pass1Program: w } = v;
463
+ ee.current = v.atlasTexture, te.current = v.scatterAtlasTexture, m.uniform1i(v.shapeMatchingLoc, +(E === "shape")), m.uniform1i(v.revealEffectFlagLoc, le), m.uniform1f(v.revealProgressLoc, 0);
464
+ let T = g({
465
+ scatterEnabledRef: ve,
466
+ mouseRadiusRef: be,
467
+ durationRef: Ce,
468
+ scatterCharsRef: Z
469
+ }), D = _({
470
+ brightenEnabledRef: _e,
471
+ trailLenRef: xe,
472
+ durationRef: Ce,
473
+ trailDecayRef: Se
474
+ }), O = y({
475
+ clickEnabledRef: we,
476
+ clickSpeedRef: Ee,
477
+ clickBrightnessRef: Te,
478
+ pixelScaleRef: Ie
479
+ }), k = b({
480
+ spreadEnabledRef: De,
481
+ scatterCharsRef: Z,
482
+ spreadExpandDurationRef: Oe,
483
+ spreadSpeedRef: ke
484
+ }), A = 0, M = !1, N = -1, F = -1, I = document.createElement("canvas"), L = I.getContext("2d"), R = (u) => {
485
+ let d = c > 0 ? c : f.width, p = l > 0 ? l : f.height;
486
+ r = Math.max(1, Math.floor(d / u));
487
+ let h = r * 2;
488
+ if (L.font = `${h}px monospace`, i = Math.max(1, Math.round(h * r / L.measureText("M").width)), t = Math.ceil(d / r), n = Math.ceil(p / i), o = Math.floor((d - t * r) / 2), s = Math.floor((p - n * i) / 2), m.viewport(0, 0, f.width, f.height), m.useProgram(S), m.uniform2f(v.resLoc, f.width, f.height), m.uniform2f(v.gridOffsetLoc, o, s), m.useProgram(w), m.uniform2f(v.p1ResLoc, f.width, f.height), m.uniform2f(v.p1GridOffsetLoc, o, s), m.useProgram(S), T.setup(m, t, n, r, i, o, s, v.scatterStateTexture), k.setup(m, t, n, r, i, o, s, v.spreadStateTexture), E === "shape") {
489
+ e = a(C, r, i);
490
+ let o = e.length, s = new Float32Array(o * 8);
491
+ for (let t = 0; t < o; t++) {
483
492
  let n = e[t].vector;
484
- s[t * 4 + 0] = n[0], s[t * 4 + 1] = n[1], s[t * 4 + 2] = n[2], s[t * 4 + 3] = n[3], s[i * 4 + t * 4 + 0] = n[4], s[i * 4 + t * 4 + 1] = n[5];
493
+ s[t * 4 + 0] = n[0], s[t * 4 + 1] = n[1], s[t * 4 + 2] = n[2], s[t * 4 + 3] = n[3], s[o * 4 + t * 4 + 0] = n[4], s[o * 4 + t * 4 + 1] = n[5];
485
494
  }
486
- C.activeTexture(C.TEXTURE2), C.bindTexture(C.TEXTURE_2D, w.charVectorsTexture), C.texImage2D(C.TEXTURE_2D, 0, C.RGBA32F, i, 2, 0, C.RGBA, C.FLOAT, s), C.activeTexture(C.TEXTURE3), C.bindTexture(C.TEXTURE_2D, w.fboTexture), C.texImage2D(C.TEXTURE_2D, 0, C.R8UI, t, n, 0, C.RED_INTEGER, C.UNSIGNED_BYTE, null), C.bindFramebuffer(C.FRAMEBUFFER, w.fbo), C.framebufferTexture2D(C.FRAMEBUFFER, C.COLOR_ATTACHMENT0, C.TEXTURE_2D, w.fboTexture, 0), C.bindFramebuffer(C.FRAMEBUFFER, null);
495
+ m.activeTexture(m.TEXTURE2), m.bindTexture(m.TEXTURE_2D, v.charVectorsTexture), m.texImage2D(m.TEXTURE_2D, 0, m.RGBA32F, o, 2, 0, m.RGBA, m.FLOAT, s), m.activeTexture(m.TEXTURE3), m.bindTexture(m.TEXTURE_2D, v.fboTexture), m.texImage2D(m.TEXTURE_2D, 0, m.R8UI, t, n, 0, m.RED_INTEGER, m.UNSIGNED_BYTE, null), m.bindFramebuffer(m.FRAMEBUFFER, v.fbo), m.framebufferTexture2D(m.FRAMEBUFFER, m.COLOR_ATTACHMENT0, m.TEXTURE_2D, v.fboTexture, 0), m.bindFramebuffer(m.FRAMEBUFFER, null);
487
496
  let c = Math.max(1, Math.round(r / 5));
488
- C.useProgram(D), C.uniform2f(w.p1CellsizeLoc, r, o), C.uniform1i(w.p1CircleNLoc, c), C.uniform1i(w.p1NumCharsLoc, i), C.uniform1f(w.p1ExponentLoc, 2), C.useProgram(E);
497
+ m.useProgram(w), m.uniform2f(v.p1CellsizeLoc, r, i), m.uniform1i(v.p1CircleNLoc, c), m.uniform1i(v.p1NumCharsLoc, o), m.uniform1f(v.p1ExponentLoc, 2), m.useProgram(S);
489
498
  }
490
- C.uniform2f(w.gridSizeLoc, t, n), H.width = S.length * r, H.height = o, U.font = `${o}px monospace`, U.fillStyle = "black", U.fillRect(0, 0, S.length * r, o), U.fillStyle = "white", U.textBaseline = "top";
491
- for (let e = 0; e < S.length; e++) U.fillText(S[e], e * r, 0);
492
- C.activeTexture(C.TEXTURE1), C.bindTexture(C.TEXTURE_2D, ee.current), C.texImage2D(C.TEXTURE_2D, 0, C.RGBA, C.RGBA, C.UNSIGNED_BYTE, H), C.uniform1f(w.numLoc, S.length), C.uniform2f(w.sizeLoc, r, o), re();
493
- }, re = () => {
494
- let e = Q.current;
495
- H.width = e.length * r, H.height = o, U.fillStyle = "black", U.fillRect(0, 0, H.width, o), U.fillStyle = "white", U.textBaseline = "top", U.font = `${o}px monospace`;
496
- for (let t = 0; t < e.length; t++) U.fillText(e[t], t * r, 0);
497
- C.activeTexture(C.TEXTURE4), C.bindTexture(C.TEXTURE_2D, te.current), C.texImage2D(C.TEXTURE_2D, 0, C.RGBA, C.RGBA, C.UNSIGNED_BYTE, H), C.uniform1f(w.scatterNumCharsLoc, e.length), O.reset(C);
499
+ m.uniform2f(v.gridSizeLoc, t, n), I.width = C.length * r, I.height = i, L.font = `${i}px monospace`, L.fillStyle = "black", L.fillRect(0, 0, C.length * r, i), L.fillStyle = "white", L.textBaseline = "top";
500
+ for (let e = 0; e < C.length; e++) L.fillText(C[e], e * r, 0);
501
+ m.activeTexture(m.TEXTURE1), m.bindTexture(m.TEXTURE_2D, ee.current), m.texImage2D(m.TEXTURE_2D, 0, m.RGBA, m.RGBA, m.UNSIGNED_BYTE, I), m.uniform1f(v.numLoc, C.length), m.uniform2f(v.sizeLoc, r, i), z();
502
+ }, z = () => {
503
+ let e = Z.current;
504
+ I.width = e.length * r, I.height = i, L.fillStyle = "black", L.fillRect(0, 0, I.width, i), L.fillStyle = "white", L.textBaseline = "top", L.font = `${i}px monospace`;
505
+ for (let t = 0; t < e.length; t++) L.fillText(e[t], t * r, 0);
506
+ m.activeTexture(m.TEXTURE4), m.bindTexture(m.TEXTURE_2D, te.current), m.texImage2D(m.TEXTURE_2D, 0, m.RGBA, m.RGBA, m.UNSIGNED_BYTE, I), m.uniform1f(v.scatterNumCharsLoc, e.length), T.reset(m);
498
507
  };
499
- Fe.current = ne, Ie.current = re;
500
- let W = (e, t) => {
501
- l = Math.round(e), u = Math.round(t), ke.current = l, Ae.current = u, d.width = l, d.height = u, ne(Ee.current);
502
- let n = v(), r = n.width / n.height, i = d.width / d.height, a = 1, o = 1, s = 0, c = 0;
503
- if (i > r) o = r / i, c = (1 - o) / 2;
508
+ We.current = R, Ge.current = z;
509
+ let ne = () => {
510
+ let e = p();
511
+ if (e.width === 0 || e.height === 0) return;
512
+ let t = e.width / e.height, n = f.width / f.height, r = 1, i = 1, a = 0, o = 0;
513
+ if (n > t) i = t / n, o = (1 - i) / 2;
504
514
  else {
505
- a = i / r;
506
- let e = Oe.current, t = e === "left" ? .25 : e === "right" ? .75 : .5;
507
- s = Math.max(0, Math.min(1 - a, t - a / 2));
515
+ r = n / t;
516
+ let e = Me.current, i = e === "left" ? .25 : e === "right" ? .75 : .5;
517
+ a = Math.max(0, Math.min(1 - r, i - r / 2));
508
518
  }
509
- C.uniform2f(w.cropOffsetLoc, s, c), C.uniform2f(w.cropScaleLoc, a, o), C.useProgram(D), C.uniform2f(w.p1CropOffsetLoc, s, c), C.uniform2f(w.p1CropScaleLoc, a, o), C.useProgram(E);
519
+ m.uniform2f(v.cropOffsetLoc, a, o), m.uniform2f(v.cropScaleLoc, r, i), m.useProgram(w), m.uniform2f(v.p1CropOffsetLoc, a, o), m.uniform2f(v.p1CropScaleLoc, r, i), m.useProgram(S);
520
+ }, B = (e, t) => {
521
+ let n = Math.round(e), r = Math.round(t);
522
+ (n !== c || r !== l) && (c = n, l = r, Ne.current = c, Pe.current = l, f.width = c, f.height = l, R(Ae.current)), ne();
510
523
  };
511
- Le.current = W;
512
- let G = (e) => {
513
- Ne.current = e;
514
- let t = Math.min(1, je.current / (window.devicePixelRatio || 1)), n = Math.max(1, Math.round(e.width * t)), r = Math.max(1, Math.round(e.height * t));
515
- Me.current = e.cssWidth > 0 ? n / e.cssWidth : 1, W(n, r);
524
+ Ke.current = B;
525
+ let V = (e) => {
526
+ Q.current = e;
527
+ let t = Math.min(1, Fe.current / (window.devicePixelRatio || 1)), n = Math.max(1, Math.round(e.width * t)), r = Math.max(1, Math.round(e.height * t));
528
+ Ie.current = e.cssWidth > 0 ? n / e.cssWidth : 1, B(n, r);
516
529
  };
517
- Pe.current = G;
518
- let K = (e) => {
519
- if (!de.current) return;
520
- let t = d.getBoundingClientRect(), n = (e.clientX - t.left) * (d.width / t.width), r = (e.clientY - t.top) * (d.height / t.height), i = performance.now();
521
- N.handleMouseMove(n, r, i), O.handleMouseMove(n, r, i);
530
+ Le.current = V;
531
+ let H = (e) => {
532
+ if (!he.current) return;
533
+ let t = f.getBoundingClientRect(), n = (e.clientX - t.left) * (f.width / t.width), r = (e.clientY - t.top) * (f.height / t.height), i = performance.now();
534
+ D.handleMouseMove(n, r, i), T.handleMouseMove(n, r, i);
522
535
  };
523
- d.addEventListener("mousemove", K);
524
- let q = () => O.handleMouseLeave();
525
- d.addEventListener("mouseleave", q);
526
- let J = (e) => {
527
- P.handleClick(e, d), F.handleClick(e, d);
536
+ f.addEventListener("mousemove", H);
537
+ let U = () => T.handleMouseLeave();
538
+ f.addEventListener("mouseleave", U);
539
+ let W = (e) => {
540
+ O.handleClick(e, f), k.handleClick(e, f);
528
541
  };
529
- d.addEventListener("click", J);
530
- let Y = () => {
531
- if (C.uniform1i(w.videoModeLoc, +!!De.current), C.uniform1f(w.brightnessLoc, ce.current), C.uniform1f(w.saturationLoc, le.current), C.uniform1f(w.bgOpacityLoc, ue.current), C.uniform1i(w.mouseEffectFlagLoc, +!!pe.current), C.uniform1i(w.scatterEffectFlagLoc, +!!me.current), C.uniform1i(w.clickEffectFlagLoc, +!!be.current), C.uniform1i(w.spreadEffectFlagLoc, +!!Ce.current), C.uniform1f(w.mouseBrightnessLoc, he.current), C.uniform1f(w.mouseRadiusLoc, Math.min(d.width, d.height) * ge.current), ie) {
532
- let e = R < 0 ? 0 : Math.min(1, (performance.now() - R) / (ae * 1e3));
533
- C.uniform1f(w.revealProgressLoc, e);
542
+ f.addEventListener("click", W);
543
+ let G = () => {
544
+ if (m.uniform1i(v.videoModeLoc, +!!je.current), m.uniform1f(v.brightnessLoc, fe.current), m.uniform1f(v.saturationLoc, pe.current), m.uniform1f(v.bgOpacityLoc, me.current), m.uniform1i(v.mouseEffectFlagLoc, +!!_e.current), m.uniform1i(v.scatterEffectFlagLoc, +!!ve.current), m.uniform1i(v.clickEffectFlagLoc, +!!we.current), m.uniform1i(v.spreadEffectFlagLoc, +!!De.current), m.uniform1f(v.mouseBrightnessLoc, ye.current), m.uniform1f(v.mouseRadiusLoc, Math.min(f.width, f.height) * be.current), se) {
545
+ let e = F < 0 ? 0 : Math.min(1, (performance.now() - F) / (ce * 1e3));
546
+ m.uniform1f(v.revealProgressLoc, e);
534
547
  }
535
- $.current && p && p.currentTime != L && p.readyState >= 2 && (C.activeTexture(C.TEXTURE0), C.bindTexture(C.TEXTURE_2D, w.texture), C.texSubImage2D(C.TEXTURE_2D, 0, 0, 0, C.RGBA, C.UNSIGNED_BYTE, p), L = p.currentTime), N.tick(C, w.mousePositionsLoc, w.mouseLifeFracsLoc), O.tick(C, d), P.tick(C, d, w.ripplePositionsLoc, w.rippleRadiiLoc, w.rippleBrightnessesLoc), F.tick(C), T === "shape" && (C.bindFramebuffer(C.FRAMEBUFFER, w.fbo), C.viewport(0, 0, t, n), C.useProgram(D), C.drawArrays(C.TRIANGLES, 0, 6), C.bindFramebuffer(C.FRAMEBUFFER, null), C.viewport(0, 0, d.width, d.height), C.useProgram(E)), C.drawArrays(C.TRIANGLES, 0, 6), I = requestAnimationFrame(Y);
536
- }, X = () => {
537
- let e = M.current, t = Ne.current;
538
- if (t && t.width > 0 && t.height > 0) G(t);
548
+ $.current && d && d.currentTime != N && d.readyState >= 2 && (m.activeTexture(m.TEXTURE0), m.bindTexture(m.TEXTURE_2D, v.texture), m.texSubImage2D(m.TEXTURE_2D, 0, 0, 0, m.RGBA, m.UNSIGNED_BYTE, d), N = d.currentTime), D.tick(m, v.mousePositionsLoc, v.mouseLifeFracsLoc), T.tick(m, f), O.tick(m, f, v.ripplePositionsLoc, v.rippleRadiiLoc, v.rippleBrightnessesLoc), k.tick(m), E === "shape" && (m.bindFramebuffer(m.FRAMEBUFFER, v.fbo), m.viewport(0, 0, t, n), m.useProgram(w), m.drawArrays(m.TRIANGLES, 0, 6), m.bindFramebuffer(m.FRAMEBUFFER, null), m.viewport(0, 0, f.width, f.height), m.useProgram(S)), m.drawArrays(m.TRIANGLES, 0, 6), A = requestAnimationFrame(G);
549
+ }, K = () => {
550
+ M || (M = !0, F < 0 && (F = performance.now()), A = requestAnimationFrame(G));
551
+ }, q = () => {
552
+ M = !1, cancelAnimationFrame(A);
553
+ };
554
+ ze.current = () => {
555
+ q(), X || d?.pause();
556
+ }, Be.current = () => {
557
+ $.current && (d?.play(), K());
558
+ };
559
+ let J = (e) => {
560
+ u = e, d = e instanceof HTMLVideoElement ? e : null, N = -1, D.reset(), O.reset();
561
+ let t = P.current, n = Q.current;
562
+ if (n && n.width > 0 && n.height > 0) V(n);
539
563
  else {
540
- let t = window.devicePixelRatio || 1, n = v(), r = e.clientWidth || n.width, i = e.clientHeight || n.height;
541
- G({
542
- width: Math.round(r * t),
543
- height: Math.round(i * t),
564
+ let e = window.devicePixelRatio || 1, n = p(), r = t.clientWidth || n.width, i = t.clientHeight || n.height;
565
+ V({
566
+ width: Math.round(r * e),
567
+ height: Math.round(i * e),
544
568
  cssWidth: r,
545
569
  cssHeight: i
546
570
  });
547
571
  }
548
- C.activeTexture(C.TEXTURE0), C.bindTexture(C.TEXTURE_2D, w.texture), C.texImage2D(C.TEXTURE_2D, 0, C.RGBA, C.RGBA, C.UNSIGNED_BYTE, f), p?.play(), R = performance.now(), $.current = !0, I = requestAnimationFrame(Y);
549
- }, Z = () => {
550
- p && (z = (z + 1) % B.length, p.src = B[z], p.load(), p.addEventListener("canplay", () => p.play(), { once: !0 }));
551
- }, fe = M.current ? x(M.current, (e) => {
552
- Ne.current = e, $.current && e.width > 0 && e.height > 0 && G(e);
572
+ m.activeTexture(m.TEXTURE0), m.bindTexture(m.TEXTURE_2D, v.texture), m.texImage2D(m.TEXTURE_2D, 0, m.RGBA, m.RGBA, m.UNSIGNED_BYTE, e), F = -1, $.current = !0, q(), Re.current ? X || d?.pause() : (d?.play(), K());
573
+ };
574
+ Ve.current = J, He.current = () => {
575
+ q(), $.current = !1, u = null, d = null;
576
+ };
577
+ let Y = P.current ? x(P.current, (e) => {
578
+ Q.current = e, $.current && e.width > 0 && e.height > 0 && V(e);
553
579
  }) : () => {};
554
- return p ? (p.addEventListener("loadeddata", X, { once: !0 }), V && p.addEventListener("ended", Z), p.readyState >= 2 && p.currentSrc.endsWith(B[0]) ? X() : p.currentSrc.endsWith(B[0]) || p.load()) : m && (m.complete && m.naturalWidth > 0 ? X() : m.addEventListener("load", X, { once: !0 })), () => {
555
- fe(), Fe.current = null, Ie.current = null, Le.current = null, Pe.current = null, $.current = !1, cancelAnimationFrame(I), p ? (p.removeEventListener("loadeddata", X), V && p.removeEventListener("ended", Z)) : m?.removeEventListener("load", X), d.removeEventListener("mousemove", K), d.removeEventListener("mouseleave", q), d.removeEventListener("click", J), C.deleteTexture(w.texture), C.deleteTexture(w.charVectorsTexture), C.deleteFramebuffer(w.fbo), C.deleteTexture(w.fboTexture), C.deleteBuffer(w.buffer), C.deleteShader(w.vertShader), C.deleteShader(w.fragShader), C.deleteShader(w.pass1FragShader), C.deleteProgram(E), C.deleteProgram(D), C.deleteTexture(ee.current), C.deleteTexture(te.current), C.deleteTexture(w.scatterStateTexture), C.deleteTexture(w.spreadStateTexture);
580
+ return Ue.current && J(Ue.current), () => {
581
+ Y(), We.current = null, Ge.current = null, Ke.current = null, Le.current = null, ze.current = null, Be.current = null, Ve.current = null, He.current = null, $.current = !1, q(), f.removeEventListener("mousemove", H), f.removeEventListener("mouseleave", U), f.removeEventListener("click", W), m.deleteTexture(v.texture), m.deleteTexture(v.charVectorsTexture), m.deleteFramebuffer(v.fbo), m.deleteTexture(v.fboTexture), m.deleteBuffer(v.buffer), m.deleteShader(v.vertShader), m.deleteShader(v.fragShader), m.deleteShader(v.pass1FragShader), m.deleteProgram(S), m.deleteProgram(w), m.deleteTexture(ee.current), m.deleteTexture(te.current), m.deleteTexture(v.scatterStateTexture), m.deleteTexture(v.spreadStateTexture);
556
582
  };
557
583
  }, [
558
- i,
559
- T,
560
- S,
561
- oe,
562
- ae,
563
- ie,
584
+ X,
585
+ E,
586
+ C,
587
+ le,
588
+ ce,
564
589
  se
590
+ ]), e(() => {
591
+ let e = X ? u : de ? N.current : M.current;
592
+ if (!e) return;
593
+ let t = e instanceof HTMLVideoElement ? e : null, n = e instanceof HTMLImageElement ? e : null, r = Array.isArray(i) ? i : i === void 0 ? [] : [i], a = r.length > 1, o = 0, s = () => {
594
+ Ue.current = e, Ve.current?.(e);
595
+ }, c = () => {
596
+ t && (o = (o + 1) % r.length, t.src = r[o], t.load(), t.addEventListener("canplay", () => t.play(), { once: !0 }));
597
+ };
598
+ return t ? (t.addEventListener("loadeddata", s, { once: !X }), a && t.addEventListener("ended", c), X ? t.readyState >= 2 && s() : t.readyState >= 2 && t.currentSrc.endsWith(r[0]) ? s() : t.currentSrc.endsWith(r[0]) || t.load()) : n && (n.complete && n.naturalWidth > 0 ? s() : n.addEventListener("load", s, { once: !0 })), () => {
599
+ t ? (t.removeEventListener("loadeddata", s), a && t.removeEventListener("ended", c)) : n?.removeEventListener("load", s), Ue.current = null, He.current?.();
600
+ };
601
+ }, [
602
+ i,
603
+ u,
604
+ X,
605
+ de
565
606
  ]);
566
- let Re = Array.isArray(i) ? i[0] : i;
607
+ let qe = Array.isArray(i) ? i[0] : i;
567
608
  return /* @__PURE__ */ r("div", {
568
- ref: M,
569
- className: E,
609
+ ref: P,
610
+ className: D,
570
611
  style: {
571
612
  height: "100%",
572
613
  width: "100%"
573
614
  },
574
- children: [se ? /* @__PURE__ */ n("img", {
575
- ref: j,
576
- src: Re,
615
+ children: [X ? null : de ? /* @__PURE__ */ n("img", {
616
+ ref: N,
617
+ src: qe,
577
618
  alt: "",
578
619
  style: { display: "none" }
579
620
  }) : /* @__PURE__ */ n("video", {
580
- ref: A,
621
+ ref: M,
581
622
  muted: !0,
582
623
  playsInline: !0,
583
624
  autoPlay: !0,
584
625
  loop: !Array.isArray(i) || i.length === 1,
585
626
  style: { display: "none" },
586
627
  children: /* @__PURE__ */ n("source", {
587
- src: Re,
628
+ src: qe,
588
629
  type: "video/mp4"
589
630
  })
590
631
  }), /* @__PURE__ */ n("canvas", {
591
- ref: k,
632
+ ref: j,
592
633
  style: {
593
634
  width: "100%",
594
635
  height: "100%",
@@ -1,4 +1,4 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`react`),require(`react/jsx-runtime`)):typeof define==`function`&&define.amd?define([`exports`,`react`,`react/jsx-runtime`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ReactVideoAscii={},e.React,e.ReactJSXRuntime))})(this,function(e,t,n){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var r=[[.25,.25],[.75,.25],[.25,.5],[.75,.5],[.25,.75],[.75,.75]];function i(e,t,n){let i=[],a=document.createElement(`canvas`);a.width=t,a.height=n;let o=a.getContext(`2d`,{willReadFrequently:!0});if(!o)return[];o.font=`${n}px monospace`,o.textBaseline=`top`;let s=t/5;for(let a of e){o.fillStyle=`black`,o.fillRect(0,0,t,n),o.fillStyle=`white`,o.fillText(a,0,0);let e=o.getImageData(0,0,t,n),c=[];for(let[i,a]of r){let r=i*t,o=a*n,l=0,u=0;for(let n=Math.floor(r-s);n<=Math.ceil(r+s);n+=1)for(let i=Math.floor(o-s);i<=Math.ceil(o+s);i+=1){let a=r-n,c=o-i;if(a*a+c*c<=s*s){let r=(i*t+n)*4,a=e.data[r];l+=a/255,u++}}let d=u>0?l/u:0;c.push(d)}i.push({char:a,vector:c})}let c=[,,,,,,].fill(0);for(let{vector:e}of i)for(let t=0;t<6;++t)e[t]>c[t]&&(c[t]=e[t]);for(let{vector:e}of i)for(let t=0;t<6;++t)e[t]/=c[t];return i}var a=` \`.',-_:!;|"~+^lr[](\\/L)>t<v=Tz?icf1{sIxY*jJno}CZyVwmSXRqM$O%#9&NW0Q@`,o=/\.(png|jpe?g|gif|webp|avif|bmp|svg)(?:[?#].*)?$/i;function s(e,t){if(t!==`auto`)return t;let n=Array.isArray(e)?e[0]:e;return o.test(n)?`image`:`video`}function c(e,t,n,r,i,a,o,s){let c=!!i,l=typeof i==`object`?i:{},u=l.style??`brighten`,d=c&&u!==`scatter`,f=c&&u===`scatter`,p=l.scatterChars??`->o`,m=l.trailLen??15,h=l.trailDecay??10,g=l.duration??1,_=l.radius??(u===`scatter`?.05:.08),v=l.brightness??2,y=!!a,b=typeof a==`object`?a:{},x=b.style??`ripple`,S=y&&x!==`spread`,C=y&&x===`spread`,w=b.brightness??1.1,T=b.speed??2,E=b.spreadExpandDuration??1.5,D=b.spreadSpeed??7.5,O=!!o,k=typeof o==`object`?o:{},A=k.type??`random`,j=k.duration??.4,ee=Math.max(20,Math.min(350,Math.round(e))),M=Math.max(0,Math.min(2,t)),N=Math.max(0,Math.min(2,n)),P=Math.max(0,Math.min(1,r));j=Math.max(.1,Math.min(4,j)),m=Math.max(0,Math.min(30,Math.round(m))),h=Math.max(1,Math.min(15,h)),g=Math.max(.1,Math.min(4,g)),_=Math.max(.03,Math.min(.2,_)),v=Math.max(.2,Math.min(5,v)),w=Math.max(1.05,Math.min(2,w)),T=Math.max(.5,Math.min(4,T)),E=Math.max(.5,Math.min(5,E)),D=Math.max(.5,Math.min(10,D));let F=s===void 0?1/0:Math.max(1,Math.min(4,s)),I;return I=O?A===`diagonal`?1:A===`radial`?2:3:0,{numCols:ee,brightness:M,saturation:N,bgOpacity:P,mouseEnabled:c,mouseStyle:u,brightenEnabled:d,scatterEnabled:f,scatterChars:p,trailLen:m,trailDecay:h,duration:g,mouseRadius:_,mouseBrightness:v,clickEnabled:S,clickBrightness:w,clickSpeed:T,spreadEnabled:C,spreadExpandDuration:E,spreadSpeed:D,revealEnabled:O,revealType:A,revealDuration:j,revealEffectFlag:I,maxDpr:F}}function l(e,t,n){let r=e.createShader(t);if(!r)throw Error(`Failed to create shader`);return e.shaderSource(r,n),e.compileShader(r),e.getShaderParameter(r,e.COMPILE_STATUS)?r:(console.log(e.getShaderInfoLog(r)),e.deleteShader(r),null)}function u(e,t,n){let r=e.createProgram();return e.attachShader(r,t),e.attachShader(r,n),e.linkProgram(r),e.getProgramParameter(r,e.LINK_STATUS)?r:(console.log(e.getProgramInfoLog(r)),e.deleteProgram(r),null)}var d=`#version 300 es
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`react`),require(`react/jsx-runtime`)):typeof define==`function`&&define.amd?define([`exports`,`react`,`react/jsx-runtime`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ReactVideoAscii={},e.React,e.ReactJSXRuntime))})(this,function(e,t,n){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var r=[[.25,.25],[.75,.25],[.25,.5],[.75,.5],[.25,.75],[.75,.75]];function i(e,t,n){let i=[],a=document.createElement(`canvas`);a.width=t,a.height=n;let o=a.getContext(`2d`,{willReadFrequently:!0});if(!o)return[];o.font=`${n}px monospace`,o.textBaseline=`top`;let s=t/5;for(let a of e){o.fillStyle=`black`,o.fillRect(0,0,t,n),o.fillStyle=`white`,o.fillText(a,0,0);let e=o.getImageData(0,0,t,n),c=[];for(let[i,a]of r){let r=i*t,o=a*n,l=0,u=0;for(let n=Math.floor(r-s);n<=Math.ceil(r+s);n+=1)for(let i=Math.floor(o-s);i<=Math.ceil(o+s);i+=1){let a=r-n,c=o-i;if(a*a+c*c<=s*s){let r=(i*t+n)*4,a=e.data[r];l+=a/255,u++}}let d=u>0?l/u:0;c.push(d)}i.push({char:a,vector:c})}let c=[,,,,,,].fill(0);for(let{vector:e}of i)for(let t=0;t<6;++t)e[t]>c[t]&&(c[t]=e[t]);for(let{vector:e}of i)for(let t=0;t<6;++t)e[t]/=c[t];return i}var a=` \`.',-_:!;|"~+^lr[](\\/L)>t<v=Tz?icf1{sIxY*jJno}CZyVwmSXRqM$O%#9&NW0Q@`,o=/\.(png|jpe?g|gif|webp|avif|bmp|svg)(?:[?#].*)?$/i;function s(e,t){if(t!==`auto`)return t;let n=Array.isArray(e)?e[0]:e;return o.test(n)?`image`:`video`}function c(e,t,n,r,i,a,o,s){let c=!!i,l=typeof i==`object`?i:{},u=l.style??`brighten`,d=c&&u!==`scatter`,f=c&&u===`scatter`,p=l.scatterChars??`->o`,m=l.trailLen??15,h=l.trailDecay??10,g=l.duration??1,_=l.radius??(u===`scatter`?.05:.08),v=l.brightness??2,y=!!a,b=typeof a==`object`?a:{},x=b.style??`ripple`,S=y&&x!==`spread`,C=y&&x===`spread`,w=b.brightness??1.1,T=b.speed??2,E=b.spreadExpandDuration??1.5,D=b.spreadSpeed??7.5,O=!!o,k=typeof o==`object`?o:{},A=k.type??`random`,j=k.duration??.4,M=Math.max(20,Math.min(350,Math.round(e))),ee=Math.max(0,Math.min(2,t)),te=Math.max(0,Math.min(2,n)),N=Math.max(0,Math.min(1,r));j=Math.max(.1,Math.min(4,j)),m=Math.max(0,Math.min(30,Math.round(m))),h=Math.max(1,Math.min(15,h)),g=Math.max(.1,Math.min(4,g)),_=Math.max(.03,Math.min(.2,_)),v=Math.max(.2,Math.min(5,v)),w=Math.max(1.05,Math.min(2,w)),T=Math.max(.5,Math.min(4,T)),E=Math.max(.5,Math.min(5,E)),D=Math.max(.5,Math.min(10,D));let P=s===void 0?1/0:Math.max(1,Math.min(4,s)),F;return F=O?A===`diagonal`?1:A===`radial`?2:3:0,{numCols:M,brightness:ee,saturation:te,bgOpacity:N,mouseEnabled:c,mouseStyle:u,brightenEnabled:d,scatterEnabled:f,scatterChars:p,trailLen:m,trailDecay:h,duration:g,mouseRadius:_,mouseBrightness:v,clickEnabled:S,clickBrightness:w,clickSpeed:T,spreadEnabled:C,spreadExpandDuration:E,spreadSpeed:D,revealEnabled:O,revealType:A,revealDuration:j,revealEffectFlag:F,maxDpr:P}}function l(e,t,n){let r=e.createShader(t);if(!r)throw Error(`Failed to create shader`);return e.shaderSource(r,n),e.compileShader(r),e.getShaderParameter(r,e.COMPILE_STATUS)?r:(console.log(e.getShaderInfoLog(r)),e.deleteShader(r),null)}function u(e,t,n){let r=e.createProgram();return e.attachShader(r,t),e.attachShader(r,n),e.linkProgram(r),e.getProgramParameter(r,e.LINK_STATUS)?r:(console.log(e.getProgramInfoLog(r)),e.deleteProgram(r),null)}var d=`#version 300 es
2
2
 
3
3
  in vec2 a_position;
4
4
 
@@ -282,4 +282,4 @@ void main() {
282
282
  }
283
283
 
284
284
  fragCharInd = uvec4(bestChar, 0u, 0u, 0u);
285
- }`;function m(e){let t=l(e,e.VERTEX_SHADER,d),n=l(e,e.FRAGMENT_SHADER,f);if(!t||!n)return null;let r=u(e,t,n);if(!r)return null;let i=new Float32Array([1,1,-1,1,1,-1,-1,-1,-1,1,1,-1]),a=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,a),e.bufferData(e.ARRAY_BUFFER,i,e.STATIC_DRAW);let o=e.getAttribLocation(r,`a_position`);e.vertexAttribPointer(o,2,e.FLOAT,!1,0,0),e.enableVertexAttribArray(o),e.useProgram(r);let s=e.createTexture();e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,s),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR);let c=e.getUniformLocation(r,`u_texture`);e.uniform1i(c,0);let m=e.createTexture();e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,m),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST);let h=e.getUniformLocation(r,`u_atlas`);e.uniform1i(h,1);let g=e.createTexture();e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,g),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST);let _=l(e,e.FRAGMENT_SHADER,p);if(!_)return null;let v=u(e,t,_);if(!v)return null;e.useProgram(v),e.uniform1i(e.getUniformLocation(v,`u_texture`),0),e.uniform1i(e.getUniformLocation(v,`u_charVectors`),2);let y=e.getUniformLocation(v,`u_resolution`),b=e.getUniformLocation(v,`u_cellsize`),x=e.getUniformLocation(v,`u_circleN`),S=e.getUniformLocation(v,`u_numCharsInt`),C=e.getUniformLocation(v,`u_shapeExponent`),w=e.getUniformLocation(v,`u_cropOffset`),T=e.getUniformLocation(v,`u_cropScale`),E=e.getUniformLocation(v,`u_gridOffset`),D=e.createTexture();e.activeTexture(e.TEXTURE3),e.bindTexture(e.TEXTURE_2D,D),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST);let O=e.createFramebuffer(),k=e.createTexture();e.activeTexture(e.TEXTURE4),e.bindTexture(e.TEXTURE_2D,k),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST);let A=e.createTexture();e.activeTexture(e.TEXTURE5),e.bindTexture(e.TEXTURE_2D,A),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST);let j=e.createTexture();return e.activeTexture(e.TEXTURE6),e.bindTexture(e.TEXTURE_2D,j),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.useProgram(r),e.uniform1i(e.getUniformLocation(r,`u_fboTexture`),3),e.uniform1i(e.getUniformLocation(r,`u_scatterAtlas`),4),e.uniform1i(e.getUniformLocation(r,`u_scatterStateTexture`),5),e.uniform1i(e.getUniformLocation(r,`u_spreadStateTexture`),6),{program:r,pass1Program:v,buffer:a,vertShader:t,fragShader:n,pass1FragShader:_,texture:s,atlasTexture:m,charVectorsTexture:g,fboTexture:D,fbo:O,scatterAtlasTexture:k,scatterStateTexture:A,spreadStateTexture:j,p1ResLoc:y,p1CellsizeLoc:b,p1CircleNLoc:x,p1NumCharsLoc:S,p1ExponentLoc:C,p1CropOffsetLoc:w,p1CropScaleLoc:T,p1GridOffsetLoc:E,revealEffectFlagLoc:e.getUniformLocation(r,`u_revealEffectFlag`),mouseEffectFlagLoc:e.getUniformLocation(r,`u_mouseEffect`),clickEffectFlagLoc:e.getUniformLocation(r,`u_clickEffect`),shapeMatchingLoc:e.getUniformLocation(r,`u_shapeMatching`),revealProgressLoc:e.getUniformLocation(r,`u_revealProgress`),brightnessLoc:e.getUniformLocation(r,`u_brightness`),saturationLoc:e.getUniformLocation(r,`u_saturation`),bgOpacityLoc:e.getUniformLocation(r,`u_bgOpacity`),mouseBrightnessLoc:e.getUniformLocation(r,`u_mouseBrightness`),mousePositionsLoc:e.getUniformLocation(r,`u_mousePositions`),mouseLifeFracsLoc:e.getUniformLocation(r,`u_mouseLifeFracs`),mouseRadiusLoc:e.getUniformLocation(r,`u_mouseRadius`),ripplePositionsLoc:e.getUniformLocation(r,`u_ripplePositions`),rippleRadiiLoc:e.getUniformLocation(r,`u_rippleRadii`),rippleBrightnessesLoc:e.getUniformLocation(r,`u_rippleBrightnesses`),scatterEffectFlagLoc:e.getUniformLocation(r,`u_scatterEffect`),scatterNumCharsLoc:e.getUniformLocation(r,`u_scatterNumChars`),spreadEffectFlagLoc:e.getUniformLocation(r,`u_spreadEffect`),videoModeLoc:e.getUniformLocation(r,`u_videoMode`),resLoc:e.getUniformLocation(r,`u_resolution`),sizeLoc:e.getUniformLocation(r,`u_cellsize`),numLoc:e.getUniformLocation(r,`u_numChars`),gridSizeLoc:e.getUniformLocation(r,`u_gridSize`),cropOffsetLoc:e.getUniformLocation(r,`u_cropOffset`),cropScaleLoc:e.getUniformLocation(r,`u_cropScale`),gridOffsetLoc:e.getUniformLocation(r,`u_gridOffset`)}}function h({scatterEnabledRef:e,mouseRadiusRef:t,durationRef:n,scatterCharsRef:r}){let i=new Uint8Array,a=new Float32Array,o=new Float32Array,s=new Uint8Array,c=null,l=null,u=0,d=0,f=-1,p=()=>Math.floor(Math.random()*r.current.length),m=0,h=0,g=1,_=1,v=0,y=0,b=null;return{setup(e,t,n,r,f,p,x,S){m=t,h=n,g=r,_=f,v=p,y=x,b=S;let C=t*n;i=new Uint8Array(C),a=new Float32Array(C),o=new Float32Array(C),s=new Uint8Array(C),c=null,l=null,u=0,d=0,e.activeTexture(e.TEXTURE5),e.bindTexture(e.TEXTURE_2D,S),e.texImage2D(e.TEXTURE_2D,0,e.R8UI,t,n,0,e.RED_INTEGER,e.UNSIGNED_BYTE,i)},handleMouseMove(t,n,r){e.current&&(l=c,c={x:t,y:n,t:r})},handleMouseLeave(){c=null,l=null,u=0,d=0},reset(e){i.fill(0),b&&m>0&&(e.activeTexture(e.TEXTURE5),e.bindTexture(e.TEXTURE_2D,b),e.texSubImage2D(e.TEXTURE_2D,0,0,0,m,h,e.RED_INTEGER,e.UNSIGNED_BYTE,i))},tick(r,x){if(!e.current||m===0||h===0)return;let S=performance.now(),C=f<0?0:Math.min(.1,(S-f)/1e3);f=S;let w=Math.min(x.width,x.height)*t.current,T=!1;if(c&&S-c.t<80){if(l){let e=(c.t-l.t)/1e3;if(e>0&&e<.2){let t=(c.x-l.x)/e,n=(c.y-l.y)/e;u=u*.7+t*.3,d=d*.7+n*.3}}else u=0,d=0;Math.hypot(u,d)>g*2&&(T=!0)}else u*=.6,d*=.6;if(s.fill(0),T&&c&&w>0){let e=c.x,t=c.y,n=Math.max(0,Math.floor((e-v-w)/g)),r=Math.min(m-1,Math.floor((e-v+w)/g)),l=Math.max(0,Math.floor((t-y-w)/_)),u=Math.min(h-1,Math.floor((t-y+w)/_));for(let c=l;c<=u;c++)for(let l=n;l<=r;l++){let n=v+(l+.5)*g,r=y+(c+.5)*_;if(Math.hypot(n-e,r-t)>w)continue;let u=c*m+l;s[u]=1,i[u]===0&&(i[u]=1+p(),o[u]=.5+Math.random()*2),a[u]=1}}let E=n.current;if(C>0)for(let e=0;e<h;e++)for(let t=0;t<m;t++){let n=e*m+t;if(i[n]===0||s[n])continue;let r=t>0?i[n-1]!==0:!1,c=t<m-1?i[n+1]!==0:!1,l=e>0?i[n-m]!==0:!1,u=e<h-1?i[n+m]!==0:!1,d=(!r||!c||!l||!u?5:1)*o[n]/E;a[n]-=d*C,a[n]<=0&&(i[n]=0)}r.activeTexture(r.TEXTURE5),r.bindTexture(r.TEXTURE_2D,b),r.texSubImage2D(r.TEXTURE_2D,0,0,0,m,h,r.RED_INTEGER,r.UNSIGNED_BYTE,i)}}}function g({brightenEnabledRef:e,trailLenRef:t,durationRef:n,trailDecayRef:r}){let i=[];return{handleMouseMove(n,r,a){e.current&&(i.push({x:n,y:r,t:a}),i.length>t.current&&i.shift())},tick(a,o,s){if(!e.current)return;let c=performance.now(),l=new Float32Array(t.current*2),u=new Float32Array(t.current);for(let e=0;e<i.length;e++){let t=c-i[e].t,a=Math.max(0,1-t/(n.current*1e3))**r.current;l[e*2]=i[e].x,l[e*2+1]=i[e].y,u[e]=a}a.uniform2fv(o,l),a.uniform1fv(s,u)}}}var _=10;function v({clickEnabledRef:e,clickSpeedRef:t,clickBrightnessRef:n,pixelScaleRef:r}){let i=[];return{handleClick(t,n){if(!e.current)return;let r=n.getBoundingClientRect(),a=(t.clientX-r.left)*(n.width/r.width),o=(t.clientY-r.top)*(n.height/r.height);i.push({x:a,y:o,t:performance.now()}),i.length>_&&i.shift()},tick(a,o,s,c,l){if(!e.current)return;let u=performance.now(),d=Math.hypot(o.width,o.height),f=t.current*r.current,p=new Float32Array(_*2),m=new Float32Array(_),h=new Float32Array(_);for(;i.length>0&&(u-i[0].t)*f>=d;)i.shift();for(let e=0;e<i.length;e++){let t=(u-i[e].t)*f,r=t/d,a=1+(n.current-1)*(1-r**2);p[e*2]=i[e].x,p[e*2+1]=i[e].y,m[e]=t,h[e]=a}a.uniform2fv(s,p),a.uniform1fv(c,m),a.uniform1fv(l,h)}}}function y({spreadEnabledRef:e,scatterCharsRef:t,spreadExpandDurationRef:n,spreadSpeedRef:r}){let i=new Uint8Array,a=new Uint8Array,o=0,s=0,c=1,l=1,u=0,d=0,f=null,p=-1,m=-1,h=()=>Math.floor(Math.random()*t.current.length),g=[[-1,0],[1,0],[0,-1],[0,1]];return{setup(e,t,n,r,h,g,_,v){o=t,s=n,c=r,l=h,u=g,d=_,f=v;let y=t*n;i=new Uint8Array(y),a=new Uint8Array(y),m=-1,p=-1,e.activeTexture(e.TEXTURE6),e.bindTexture(e.TEXTURE_2D,v),e.texImage2D(e.TEXTURE_2D,0,e.R8UI,t,n,0,e.RED_INTEGER,e.UNSIGNED_BYTE,i)},handleClick(t,r){if(!e.current||o===0)return;let f=r.getBoundingClientRect(),p=(t.clientX-f.left)*(r.width/f.width),g=(t.clientY-f.top)*(r.height/f.height),_=Math.floor((p-u)/c),v=Math.floor((g-d)/l);if(_<0||_>=o||v<0||v>=s)return;let y=v*o+_;i[y]=1+h(),a[y]=1,m=performance.now()+n.current*1e3},tick(t){if(!e.current||o===0||s===0)return;let n=performance.now(),c=p<0?0:Math.min(.1,(n-p)/1e3);p=n;let l=m>0&&n<m;if(!l&&m>0){for(let e=0;e<i.length;e++)a[e]===1&&(a[e]=2);m=-1}if(c>0)for(let e=0;e<s;e++)for(let t=0;t<o;t++){let n=e*o+t;if(a[n]!==0){if(l&&a[n]===1)for(let[n,l]of g){let u=e+n,d=t+l;if(u<0||u>=s||d<0||d>=o)continue;let f=u*o+d;a[f]===0&&Math.random()<r.current*c&&(i[f]=1+h(),a[f]=1)}else if(a[n]===2)for(let[l,u]of g){let d=e+l,f=t+u;if(d<0||d>=s||f<0||f>=o||i[d*o+f]===0){Math.random()<r.current*c&&(i[n]=0,a[n]=0);break}}}}t.activeTexture(t.TEXTURE6),t.bindTexture(t.TEXTURE_2D,f),t.texSubImage2D(t.TEXTURE_2D,0,0,0,o,s,t.RED_INTEGER,t.UNSIGNED_BYTE,i)}}}function b(e,t){let n=0,r=0,i=!1,a=null,o=()=>{let e=window.devicePixelRatio||1;t({width:Math.round(n*e),height:Math.round(r*e),cssWidth:n,cssHeight:r})},s=()=>{a?.();let e=window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`),t=()=>{i||(o(),s())};e.addEventListener(`change`,t,{once:!0}),a=()=>e.removeEventListener(`change`,t)},c=new ResizeObserver(e=>{let i=e[0],a=i.contentBoxSize?.[0];n=a?a.inlineSize:i.contentRect.width,r=a?a.blockSize:i.contentRect.height;let s=i.devicePixelContentBoxSize?.[0];s?t({width:s.inlineSize,height:s.blockSize,cssWidth:n,cssHeight:r}):o()});try{c.observe(e,{box:`device-pixel-content-box`})}catch{c.observe(e),s()}return()=>{i=!0,c.disconnect(),a?.()}}function x({src:e,mediaType:r=`auto`,videoMode:o=!1,numColsRaw:l=250,brightnessRaw:u=1,saturationRaw:d=1,bgOpacityRaw:f=.3,revealEffect:p=!1,chars:_=a,mouseEffect:x=!0,clickEffect:S=!0,charMode:C=`shape`,className:w,cropFocus:T=`center`,maxDpr:E}){let D=(0,t.useRef)(null),O=(0,t.useRef)(null),k=(0,t.useRef)(null),A=(0,t.useRef)(null),j=(0,t.useRef)(null),ee=(0,t.useRef)(null),{numCols:M,brightness:N,saturation:P,bgOpacity:F,mouseEnabled:I,mouseStyle:L,brightenEnabled:R,scatterEnabled:z,scatterChars:B,trailLen:V,trailDecay:H,duration:U,mouseRadius:W,mouseBrightness:te,clickEnabled:ne,clickBrightness:G,clickSpeed:K,spreadEnabled:q,spreadExpandDuration:J,spreadSpeed:Y,revealEnabled:re,revealDuration:ie,revealEffectFlag:ae,maxDpr:X}=c(l,u,d,f,x,S,p,E),oe=s(e,r)===`image`,se=(0,t.useRef)(N),ce=(0,t.useRef)(P),le=(0,t.useRef)(F),ue=(0,t.useRef)(I),Z=(0,t.useRef)(L),de=(0,t.useRef)(R),fe=(0,t.useRef)(z),pe=(0,t.useRef)(te),me=(0,t.useRef)(W),he=(0,t.useRef)(V),ge=(0,t.useRef)(H),_e=(0,t.useRef)(U),Q=(0,t.useRef)(B),ve=(0,t.useRef)(ne),ye=(0,t.useRef)(G),be=(0,t.useRef)(K),xe=(0,t.useRef)(q),Se=(0,t.useRef)(J),Ce=(0,t.useRef)(Y),we=(0,t.useRef)(M),Te=(0,t.useRef)(o),Ee=(0,t.useRef)(T),De=(0,t.useRef)(0),Oe=(0,t.useRef)(0),ke=(0,t.useRef)(X),Ae=(0,t.useRef)(1),je=(0,t.useRef)(null),Me=(0,t.useRef)(null);(0,t.useEffect)(()=>{se.current=N,ce.current=P,le.current=F,ue.current=I,Z.current=L,de.current=R,fe.current=z,pe.current=te,me.current=W,he.current=V,ge.current=H,_e.current=U,Q.current!==B&&$.current?(Q.current=B,Pe.current?.()):Q.current=B,ve.current=ne,ye.current=G,be.current=K,xe.current=q,Se.current=J,Ce.current=Y,we.current=M,Te.current=o},[N,P,F,I,L,R,z,te,W,V,H,U,B,ne,G,K,q,J,Y,M,o]);let Ne=(0,t.useRef)(null),Pe=(0,t.useRef)(null),Fe=(0,t.useRef)(null),$=(0,t.useRef)(!1);(0,t.useEffect)(()=>{$.current&&Ne.current?.(M)},[M]),(0,t.useEffect)(()=>{Ee.current=T,$.current&&De.current>0&&Fe.current?.(De.current,Oe.current)},[T]),(0,t.useEffect)(()=>{ke.current=X,$.current&&je.current&&Me.current?.(je.current)},[X]),(0,t.useEffect)(()=>{$.current=!1;let t=[],n=0,r=0,a=1,o=1,s=0,c=0,l=0,u=0,d=D.current;if(!d)return;let f=oe?k.current:O.current;if(!f)return;let p=f instanceof HTMLVideoElement?f:null,x=f instanceof HTMLImageElement?f:null,S=()=>f instanceof HTMLVideoElement?{width:f.videoWidth,height:f.videoHeight}:{width:f.naturalWidth,height:f.naturalHeight},w=d.getContext(`webgl2`);if(!w)return;w.pixelStorei(w.UNPACK_ALIGNMENT,1);let T=m(w);if(!T)return;let{program:E,pass1Program:M}=T;j.current=T.atlasTexture,ee.current=T.scatterAtlasTexture,w.uniform1i(T.shapeMatchingLoc,+(C===`shape`)),w.uniform1i(T.revealEffectFlagLoc,ae),w.uniform1f(T.revealProgressLoc,0);let N=h({scatterEnabledRef:fe,mouseRadiusRef:me,durationRef:_e,scatterCharsRef:Q}),P=g({brightenEnabledRef:de,trailLenRef:he,durationRef:_e,trailDecayRef:ge}),F=v({clickEnabledRef:ve,clickSpeedRef:be,clickBrightnessRef:ye,pixelScaleRef:Ae}),I=y({spreadEnabledRef:xe,scatterCharsRef:Q,spreadExpandDurationRef:Se,spreadSpeedRef:Ce}),L,R=-1,z=-1,B=0,V=Array.isArray(e)?e:[e],H=V.length>1,U=document.createElement(`canvas`),W=U.getContext(`2d`),te=e=>{let f=l>0?l:d.width,p=u>0?u:d.height;a=Math.max(1,Math.floor(f/e));let m=a*2;if(W.font=`${m}px monospace`,o=Math.max(1,Math.round(m*a/W.measureText(`M`).width)),n=Math.ceil(f/a),r=Math.ceil(p/o),s=Math.floor((f-n*a)/2),c=Math.floor((p-r*o)/2),w.viewport(0,0,d.width,d.height),w.useProgram(E),w.uniform2f(T.resLoc,d.width,d.height),w.uniform2f(T.gridOffsetLoc,s,c),w.useProgram(M),w.uniform2f(T.p1ResLoc,d.width,d.height),w.uniform2f(T.p1GridOffsetLoc,s,c),w.useProgram(E),N.setup(w,n,r,a,o,s,c,T.scatterStateTexture),I.setup(w,n,r,a,o,s,c,T.spreadStateTexture),C===`shape`){t=i(_,a,o);let e=t.length,s=new Float32Array(e*8);for(let n=0;n<e;n++){let r=t[n].vector;s[n*4+0]=r[0],s[n*4+1]=r[1],s[n*4+2]=r[2],s[n*4+3]=r[3],s[e*4+n*4+0]=r[4],s[e*4+n*4+1]=r[5]}w.activeTexture(w.TEXTURE2),w.bindTexture(w.TEXTURE_2D,T.charVectorsTexture),w.texImage2D(w.TEXTURE_2D,0,w.RGBA32F,e,2,0,w.RGBA,w.FLOAT,s),w.activeTexture(w.TEXTURE3),w.bindTexture(w.TEXTURE_2D,T.fboTexture),w.texImage2D(w.TEXTURE_2D,0,w.R8UI,n,r,0,w.RED_INTEGER,w.UNSIGNED_BYTE,null),w.bindFramebuffer(w.FRAMEBUFFER,T.fbo),w.framebufferTexture2D(w.FRAMEBUFFER,w.COLOR_ATTACHMENT0,w.TEXTURE_2D,T.fboTexture,0),w.bindFramebuffer(w.FRAMEBUFFER,null);let c=Math.max(1,Math.round(a/5));w.useProgram(M),w.uniform2f(T.p1CellsizeLoc,a,o),w.uniform1i(T.p1CircleNLoc,c),w.uniform1i(T.p1NumCharsLoc,e),w.uniform1f(T.p1ExponentLoc,2),w.useProgram(E)}w.uniform2f(T.gridSizeLoc,n,r),U.width=_.length*a,U.height=o,W.font=`${o}px monospace`,W.fillStyle=`black`,W.fillRect(0,0,_.length*a,o),W.fillStyle=`white`,W.textBaseline=`top`;for(let e=0;e<_.length;e++)W.fillText(_[e],e*a,0);w.activeTexture(w.TEXTURE1),w.bindTexture(w.TEXTURE_2D,j.current),w.texImage2D(w.TEXTURE_2D,0,w.RGBA,w.RGBA,w.UNSIGNED_BYTE,U),w.uniform1f(T.numLoc,_.length),w.uniform2f(T.sizeLoc,a,o),ne()},ne=()=>{let e=Q.current;U.width=e.length*a,U.height=o,W.fillStyle=`black`,W.fillRect(0,0,U.width,o),W.fillStyle=`white`,W.textBaseline=`top`,W.font=`${o}px monospace`;for(let t=0;t<e.length;t++)W.fillText(e[t],t*a,0);w.activeTexture(w.TEXTURE4),w.bindTexture(w.TEXTURE_2D,ee.current),w.texImage2D(w.TEXTURE_2D,0,w.RGBA,w.RGBA,w.UNSIGNED_BYTE,U),w.uniform1f(T.scatterNumCharsLoc,e.length),N.reset(w)};Ne.current=te,Pe.current=ne;let G=(e,t)=>{l=Math.round(e),u=Math.round(t),De.current=l,Oe.current=u,d.width=l,d.height=u,te(we.current);let n=S(),r=n.width/n.height,i=d.width/d.height,a=1,o=1,s=0,c=0;if(i>r)o=r/i,c=(1-o)/2;else{a=i/r;let e=Ee.current,t=e===`left`?.25:e===`right`?.75:.5;s=Math.max(0,Math.min(1-a,t-a/2))}w.uniform2f(T.cropOffsetLoc,s,c),w.uniform2f(T.cropScaleLoc,a,o),w.useProgram(M),w.uniform2f(T.p1CropOffsetLoc,s,c),w.uniform2f(T.p1CropScaleLoc,a,o),w.useProgram(E)};Fe.current=G;let K=e=>{je.current=e;let t=Math.min(1,ke.current/(window.devicePixelRatio||1)),n=Math.max(1,Math.round(e.width*t)),r=Math.max(1,Math.round(e.height*t));Ae.current=e.cssWidth>0?n/e.cssWidth:1,G(n,r)};Me.current=K;let q=e=>{if(!ue.current)return;let t=d.getBoundingClientRect(),n=(e.clientX-t.left)*(d.width/t.width),r=(e.clientY-t.top)*(d.height/t.height),i=performance.now();P.handleMouseMove(n,r,i),N.handleMouseMove(n,r,i)};d.addEventListener(`mousemove`,q);let J=()=>N.handleMouseLeave();d.addEventListener(`mouseleave`,J);let Y=e=>{F.handleClick(e,d),I.handleClick(e,d)};d.addEventListener(`click`,Y);let X=()=>{if(w.uniform1i(T.videoModeLoc,+!!Te.current),w.uniform1f(T.brightnessLoc,se.current),w.uniform1f(T.saturationLoc,ce.current),w.uniform1f(T.bgOpacityLoc,le.current),w.uniform1i(T.mouseEffectFlagLoc,+!!de.current),w.uniform1i(T.scatterEffectFlagLoc,+!!fe.current),w.uniform1i(T.clickEffectFlagLoc,+!!ve.current),w.uniform1i(T.spreadEffectFlagLoc,+!!xe.current),w.uniform1f(T.mouseBrightnessLoc,pe.current),w.uniform1f(T.mouseRadiusLoc,Math.min(d.width,d.height)*me.current),re){let e=z<0?0:Math.min(1,(performance.now()-z)/(ie*1e3));w.uniform1f(T.revealProgressLoc,e)}$.current&&p&&p.currentTime!=R&&p.readyState>=2&&(w.activeTexture(w.TEXTURE0),w.bindTexture(w.TEXTURE_2D,T.texture),w.texSubImage2D(w.TEXTURE_2D,0,0,0,w.RGBA,w.UNSIGNED_BYTE,p),R=p.currentTime),P.tick(w,T.mousePositionsLoc,T.mouseLifeFracsLoc),N.tick(w,d),F.tick(w,d,T.ripplePositionsLoc,T.rippleRadiiLoc,T.rippleBrightnessesLoc),I.tick(w),C===`shape`&&(w.bindFramebuffer(w.FRAMEBUFFER,T.fbo),w.viewport(0,0,n,r),w.useProgram(M),w.drawArrays(w.TRIANGLES,0,6),w.bindFramebuffer(w.FRAMEBUFFER,null),w.viewport(0,0,d.width,d.height),w.useProgram(E)),w.drawArrays(w.TRIANGLES,0,6),L=requestAnimationFrame(X)},Z=()=>{let e=A.current,t=je.current;if(t&&t.width>0&&t.height>0)K(t);else{let t=window.devicePixelRatio||1,n=S(),r=e.clientWidth||n.width,i=e.clientHeight||n.height;K({width:Math.round(r*t),height:Math.round(i*t),cssWidth:r,cssHeight:i})}w.activeTexture(w.TEXTURE0),w.bindTexture(w.TEXTURE_2D,T.texture),w.texImage2D(w.TEXTURE_2D,0,w.RGBA,w.RGBA,w.UNSIGNED_BYTE,f),p?.play(),z=performance.now(),$.current=!0,L=requestAnimationFrame(X)},Ie=()=>{p&&(B=(B+1)%V.length,p.src=V[B],p.load(),p.addEventListener(`canplay`,()=>p.play(),{once:!0}))},Le=A.current?b(A.current,e=>{je.current=e,$.current&&e.width>0&&e.height>0&&K(e)}):()=>{};return p?(p.addEventListener(`loadeddata`,Z,{once:!0}),H&&p.addEventListener(`ended`,Ie),p.readyState>=2&&p.currentSrc.endsWith(V[0])?Z():p.currentSrc.endsWith(V[0])||p.load()):x&&(x.complete&&x.naturalWidth>0?Z():x.addEventListener(`load`,Z,{once:!0})),()=>{Le(),Ne.current=null,Pe.current=null,Fe.current=null,Me.current=null,$.current=!1,cancelAnimationFrame(L),p?(p.removeEventListener(`loadeddata`,Z),H&&p.removeEventListener(`ended`,Ie)):x?.removeEventListener(`load`,Z),d.removeEventListener(`mousemove`,q),d.removeEventListener(`mouseleave`,J),d.removeEventListener(`click`,Y),w.deleteTexture(T.texture),w.deleteTexture(T.charVectorsTexture),w.deleteFramebuffer(T.fbo),w.deleteTexture(T.fboTexture),w.deleteBuffer(T.buffer),w.deleteShader(T.vertShader),w.deleteShader(T.fragShader),w.deleteShader(T.pass1FragShader),w.deleteProgram(E),w.deleteProgram(M),w.deleteTexture(j.current),w.deleteTexture(ee.current),w.deleteTexture(T.scatterStateTexture),w.deleteTexture(T.spreadStateTexture)}},[e,C,_,ae,ie,re,oe]);let Ie=Array.isArray(e)?e[0]:e;return(0,n.jsxs)(`div`,{ref:A,className:w,style:{height:`100%`,width:`100%`},children:[oe?(0,n.jsx)(`img`,{ref:k,src:Ie,alt:``,style:{display:`none`}}):(0,n.jsx)(`video`,{ref:O,muted:!0,playsInline:!0,autoPlay:!0,loop:!Array.isArray(e)||e.length===1,style:{display:`none`},children:(0,n.jsx)(`source`,{src:Ie,type:`video/mp4`})}),(0,n.jsx)(`canvas`,{ref:D,style:{width:`100%`,height:`100%`,display:`block`}})]})}e.VideoAscii=x});
285
+ }`;function m(e){let t=l(e,e.VERTEX_SHADER,d),n=l(e,e.FRAGMENT_SHADER,f);if(!t||!n)return null;let r=u(e,t,n);if(!r)return null;let i=new Float32Array([1,1,-1,1,1,-1,-1,-1,-1,1,1,-1]),a=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,a),e.bufferData(e.ARRAY_BUFFER,i,e.STATIC_DRAW);let o=e.getAttribLocation(r,`a_position`);e.vertexAttribPointer(o,2,e.FLOAT,!1,0,0),e.enableVertexAttribArray(o),e.useProgram(r);let s=e.createTexture();e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,s),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR);let c=e.getUniformLocation(r,`u_texture`);e.uniform1i(c,0);let m=e.createTexture();e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,m),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST);let h=e.getUniformLocation(r,`u_atlas`);e.uniform1i(h,1);let g=e.createTexture();e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,g),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST);let _=l(e,e.FRAGMENT_SHADER,p);if(!_)return null;let v=u(e,t,_);if(!v)return null;e.useProgram(v),e.uniform1i(e.getUniformLocation(v,`u_texture`),0),e.uniform1i(e.getUniformLocation(v,`u_charVectors`),2);let y=e.getUniformLocation(v,`u_resolution`),b=e.getUniformLocation(v,`u_cellsize`),x=e.getUniformLocation(v,`u_circleN`),S=e.getUniformLocation(v,`u_numCharsInt`),C=e.getUniformLocation(v,`u_shapeExponent`),w=e.getUniformLocation(v,`u_cropOffset`),T=e.getUniformLocation(v,`u_cropScale`),E=e.getUniformLocation(v,`u_gridOffset`),D=e.createTexture();e.activeTexture(e.TEXTURE3),e.bindTexture(e.TEXTURE_2D,D),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST);let O=e.createFramebuffer(),k=e.createTexture();e.activeTexture(e.TEXTURE4),e.bindTexture(e.TEXTURE_2D,k),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST);let A=e.createTexture();e.activeTexture(e.TEXTURE5),e.bindTexture(e.TEXTURE_2D,A),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST);let j=e.createTexture();return e.activeTexture(e.TEXTURE6),e.bindTexture(e.TEXTURE_2D,j),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.useProgram(r),e.uniform1i(e.getUniformLocation(r,`u_fboTexture`),3),e.uniform1i(e.getUniformLocation(r,`u_scatterAtlas`),4),e.uniform1i(e.getUniformLocation(r,`u_scatterStateTexture`),5),e.uniform1i(e.getUniformLocation(r,`u_spreadStateTexture`),6),{program:r,pass1Program:v,buffer:a,vertShader:t,fragShader:n,pass1FragShader:_,texture:s,atlasTexture:m,charVectorsTexture:g,fboTexture:D,fbo:O,scatterAtlasTexture:k,scatterStateTexture:A,spreadStateTexture:j,p1ResLoc:y,p1CellsizeLoc:b,p1CircleNLoc:x,p1NumCharsLoc:S,p1ExponentLoc:C,p1CropOffsetLoc:w,p1CropScaleLoc:T,p1GridOffsetLoc:E,revealEffectFlagLoc:e.getUniformLocation(r,`u_revealEffectFlag`),mouseEffectFlagLoc:e.getUniformLocation(r,`u_mouseEffect`),clickEffectFlagLoc:e.getUniformLocation(r,`u_clickEffect`),shapeMatchingLoc:e.getUniformLocation(r,`u_shapeMatching`),revealProgressLoc:e.getUniformLocation(r,`u_revealProgress`),brightnessLoc:e.getUniformLocation(r,`u_brightness`),saturationLoc:e.getUniformLocation(r,`u_saturation`),bgOpacityLoc:e.getUniformLocation(r,`u_bgOpacity`),mouseBrightnessLoc:e.getUniformLocation(r,`u_mouseBrightness`),mousePositionsLoc:e.getUniformLocation(r,`u_mousePositions`),mouseLifeFracsLoc:e.getUniformLocation(r,`u_mouseLifeFracs`),mouseRadiusLoc:e.getUniformLocation(r,`u_mouseRadius`),ripplePositionsLoc:e.getUniformLocation(r,`u_ripplePositions`),rippleRadiiLoc:e.getUniformLocation(r,`u_rippleRadii`),rippleBrightnessesLoc:e.getUniformLocation(r,`u_rippleBrightnesses`),scatterEffectFlagLoc:e.getUniformLocation(r,`u_scatterEffect`),scatterNumCharsLoc:e.getUniformLocation(r,`u_scatterNumChars`),spreadEffectFlagLoc:e.getUniformLocation(r,`u_spreadEffect`),videoModeLoc:e.getUniformLocation(r,`u_videoMode`),resLoc:e.getUniformLocation(r,`u_resolution`),sizeLoc:e.getUniformLocation(r,`u_cellsize`),numLoc:e.getUniformLocation(r,`u_numChars`),gridSizeLoc:e.getUniformLocation(r,`u_gridSize`),cropOffsetLoc:e.getUniformLocation(r,`u_cropOffset`),cropScaleLoc:e.getUniformLocation(r,`u_cropScale`),gridOffsetLoc:e.getUniformLocation(r,`u_gridOffset`)}}function h({scatterEnabledRef:e,mouseRadiusRef:t,durationRef:n,scatterCharsRef:r}){let i=new Uint8Array,a=new Float32Array,o=new Float32Array,s=new Uint8Array,c=null,l=null,u=0,d=0,f=-1,p=()=>Math.floor(Math.random()*r.current.length),m=0,h=0,g=1,_=1,v=0,y=0,b=null;return{setup(e,t,n,r,f,p,x,S){m=t,h=n,g=r,_=f,v=p,y=x,b=S;let C=t*n;i=new Uint8Array(C),a=new Float32Array(C),o=new Float32Array(C),s=new Uint8Array(C),c=null,l=null,u=0,d=0,e.activeTexture(e.TEXTURE5),e.bindTexture(e.TEXTURE_2D,S),e.texImage2D(e.TEXTURE_2D,0,e.R8UI,t,n,0,e.RED_INTEGER,e.UNSIGNED_BYTE,i)},handleMouseMove(t,n,r){e.current&&(l=c,c={x:t,y:n,t:r})},handleMouseLeave(){c=null,l=null,u=0,d=0},reset(e){i.fill(0),b&&m>0&&(e.activeTexture(e.TEXTURE5),e.bindTexture(e.TEXTURE_2D,b),e.texSubImage2D(e.TEXTURE_2D,0,0,0,m,h,e.RED_INTEGER,e.UNSIGNED_BYTE,i))},tick(r,x){if(!e.current||m===0||h===0)return;let S=performance.now(),C=f<0?0:Math.min(.1,(S-f)/1e3);f=S;let w=Math.min(x.width,x.height)*t.current,T=!1;if(c&&S-c.t<80){if(l){let e=(c.t-l.t)/1e3;if(e>0&&e<.2){let t=(c.x-l.x)/e,n=(c.y-l.y)/e;u=u*.7+t*.3,d=d*.7+n*.3}}else u=0,d=0;Math.hypot(u,d)>g*2&&(T=!0)}else u*=.6,d*=.6;if(s.fill(0),T&&c&&w>0){let e=c.x,t=c.y,n=Math.max(0,Math.floor((e-v-w)/g)),r=Math.min(m-1,Math.floor((e-v+w)/g)),l=Math.max(0,Math.floor((t-y-w)/_)),u=Math.min(h-1,Math.floor((t-y+w)/_));for(let c=l;c<=u;c++)for(let l=n;l<=r;l++){let n=v+(l+.5)*g,r=y+(c+.5)*_;if(Math.hypot(n-e,r-t)>w)continue;let u=c*m+l;s[u]=1,i[u]===0&&(i[u]=1+p(),o[u]=.5+Math.random()*2),a[u]=1}}let E=n.current;if(C>0)for(let e=0;e<h;e++)for(let t=0;t<m;t++){let n=e*m+t;if(i[n]===0||s[n])continue;let r=t>0?i[n-1]!==0:!1,c=t<m-1?i[n+1]!==0:!1,l=e>0?i[n-m]!==0:!1,u=e<h-1?i[n+m]!==0:!1,d=(!r||!c||!l||!u?5:1)*o[n]/E;a[n]-=d*C,a[n]<=0&&(i[n]=0)}r.activeTexture(r.TEXTURE5),r.bindTexture(r.TEXTURE_2D,b),r.texSubImage2D(r.TEXTURE_2D,0,0,0,m,h,r.RED_INTEGER,r.UNSIGNED_BYTE,i)}}}function g({brightenEnabledRef:e,trailLenRef:t,durationRef:n,trailDecayRef:r}){let i=[];return{handleMouseMove(n,r,a){e.current&&(i.push({x:n,y:r,t:a}),i.length>t.current&&i.shift())},reset(){i.length=0},tick(a,o,s){if(!e.current)return;let c=performance.now(),l=new Float32Array(t.current*2),u=new Float32Array(t.current);for(let e=0;e<i.length;e++){let t=c-i[e].t,a=Math.max(0,1-t/(n.current*1e3))**r.current;l[e*2]=i[e].x,l[e*2+1]=i[e].y,u[e]=a}a.uniform2fv(o,l),a.uniform1fv(s,u)}}}var _=10;function v({clickEnabledRef:e,clickSpeedRef:t,clickBrightnessRef:n,pixelScaleRef:r}){let i=[];return{handleClick(t,n){if(!e.current)return;let r=n.getBoundingClientRect(),a=(t.clientX-r.left)*(n.width/r.width),o=(t.clientY-r.top)*(n.height/r.height);i.push({x:a,y:o,t:performance.now()}),i.length>_&&i.shift()},reset(){i.length=0},tick(a,o,s,c,l){if(!e.current)return;let u=performance.now(),d=Math.hypot(o.width,o.height),f=t.current*r.current,p=new Float32Array(_*2),m=new Float32Array(_),h=new Float32Array(_);for(;i.length>0&&(u-i[0].t)*f>=d;)i.shift();for(let e=0;e<i.length;e++){let t=(u-i[e].t)*f,r=t/d,a=1+(n.current-1)*(1-r**2);p[e*2]=i[e].x,p[e*2+1]=i[e].y,m[e]=t,h[e]=a}a.uniform2fv(s,p),a.uniform1fv(c,m),a.uniform1fv(l,h)}}}function y({spreadEnabledRef:e,scatterCharsRef:t,spreadExpandDurationRef:n,spreadSpeedRef:r}){let i=new Uint8Array,a=new Uint8Array,o=0,s=0,c=1,l=1,u=0,d=0,f=null,p=-1,m=-1,h=()=>Math.floor(Math.random()*t.current.length),g=[[-1,0],[1,0],[0,-1],[0,1]];return{setup(e,t,n,r,h,g,_,v){o=t,s=n,c=r,l=h,u=g,d=_,f=v;let y=t*n;i=new Uint8Array(y),a=new Uint8Array(y),m=-1,p=-1,e.activeTexture(e.TEXTURE6),e.bindTexture(e.TEXTURE_2D,v),e.texImage2D(e.TEXTURE_2D,0,e.R8UI,t,n,0,e.RED_INTEGER,e.UNSIGNED_BYTE,i)},handleClick(t,r){if(!e.current||o===0)return;let f=r.getBoundingClientRect(),p=(t.clientX-f.left)*(r.width/f.width),g=(t.clientY-f.top)*(r.height/f.height),_=Math.floor((p-u)/c),v=Math.floor((g-d)/l);if(_<0||_>=o||v<0||v>=s)return;let y=v*o+_;i[y]=1+h(),a[y]=1,m=performance.now()+n.current*1e3},tick(t){if(!e.current||o===0||s===0)return;let n=performance.now(),c=p<0?0:Math.min(.1,(n-p)/1e3);p=n;let l=m>0&&n<m;if(!l&&m>0){for(let e=0;e<i.length;e++)a[e]===1&&(a[e]=2);m=-1}if(c>0)for(let e=0;e<s;e++)for(let t=0;t<o;t++){let n=e*o+t;if(a[n]!==0){if(l&&a[n]===1)for(let[n,l]of g){let u=e+n,d=t+l;if(u<0||u>=s||d<0||d>=o)continue;let f=u*o+d;a[f]===0&&Math.random()<r.current*c&&(i[f]=1+h(),a[f]=1)}else if(a[n]===2)for(let[l,u]of g){let d=e+l,f=t+u;if(d<0||d>=s||f<0||f>=o||i[d*o+f]===0){Math.random()<r.current*c&&(i[n]=0,a[n]=0);break}}}}t.activeTexture(t.TEXTURE6),t.bindTexture(t.TEXTURE_2D,f),t.texSubImage2D(t.TEXTURE_2D,0,0,0,o,s,t.RED_INTEGER,t.UNSIGNED_BYTE,i)}}}function b(e,t){let n=0,r=0,i=!1,a=null,o=()=>{let e=window.devicePixelRatio||1;t({width:Math.round(n*e),height:Math.round(r*e),cssWidth:n,cssHeight:r})},s=()=>{a?.();let e=window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`),t=()=>{i||(o(),s())};e.addEventListener(`change`,t,{once:!0}),a=()=>e.removeEventListener(`change`,t)},c=new ResizeObserver(e=>{let i=e[0],a=i.contentBoxSize?.[0];n=a?a.inlineSize:i.contentRect.width,r=a?a.blockSize:i.contentRect.height;let s=i.devicePixelContentBoxSize?.[0];s?t({width:s.inlineSize,height:s.blockSize,cssWidth:n,cssHeight:r}):o()});try{c.observe(e,{box:`device-pixel-content-box`})}catch{c.observe(e),s()}return()=>{i=!0,c.disconnect(),a?.()}}function x({src:e,mediaType:r=`auto`,media:o,videoMode:l=!1,numColsRaw:u=250,brightnessRaw:d=1,saturationRaw:f=1,bgOpacityRaw:p=.3,revealEffect:_=!1,chars:x=a,mouseEffect:S=!0,clickEffect:C=!0,charMode:w=`shape`,className:T,cropFocus:E=`center`,maxDpr:D,paused:O=!1}){let k=(0,t.useRef)(null),A=(0,t.useRef)(null),j=(0,t.useRef)(null),M=(0,t.useRef)(null),ee=(0,t.useRef)(null),te=(0,t.useRef)(null),{numCols:N,brightness:P,saturation:F,bgOpacity:I,mouseEnabled:L,mouseStyle:R,brightenEnabled:z,scatterEnabled:ne,scatterChars:B,trailLen:V,trailDecay:H,duration:U,mouseRadius:W,mouseBrightness:G,clickEnabled:K,clickBrightness:q,clickSpeed:J,spreadEnabled:Y,spreadExpandDuration:re,spreadSpeed:ie,revealEnabled:ae,revealDuration:oe,revealEffectFlag:se,maxDpr:ce}=c(u,d,f,p,S,C,_,D),X=e===void 0,le=e!==void 0&&s(e,r)===`image`,ue=(0,t.useRef)(P),de=(0,t.useRef)(F),fe=(0,t.useRef)(I),pe=(0,t.useRef)(L),me=(0,t.useRef)(R),he=(0,t.useRef)(z),ge=(0,t.useRef)(ne),_e=(0,t.useRef)(G),ve=(0,t.useRef)(W),ye=(0,t.useRef)(V),be=(0,t.useRef)(H),xe=(0,t.useRef)(U),Z=(0,t.useRef)(B),Se=(0,t.useRef)(K),Ce=(0,t.useRef)(q),we=(0,t.useRef)(J),Te=(0,t.useRef)(Y),Ee=(0,t.useRef)(re),De=(0,t.useRef)(ie),Oe=(0,t.useRef)(N),ke=(0,t.useRef)(l),Ae=(0,t.useRef)(E),je=(0,t.useRef)(0),Me=(0,t.useRef)(0),Ne=(0,t.useRef)(ce),Pe=(0,t.useRef)(1),Q=(0,t.useRef)(null),Fe=(0,t.useRef)(null),Ie=(0,t.useRef)(O),Le=(0,t.useRef)(null),Re=(0,t.useRef)(null),ze=(0,t.useRef)(null),Be=(0,t.useRef)(null),Ve=(0,t.useRef)(null);(0,t.useEffect)(()=>{ue.current=P,de.current=F,fe.current=I,pe.current=L,me.current=R,he.current=z,ge.current=ne,_e.current=G,ve.current=W,ye.current=V,be.current=H,xe.current=U,Z.current!==B&&$.current?(Z.current=B,Ue.current?.()):Z.current=B,Se.current=K,Ce.current=q,we.current=J,Te.current=Y,Ee.current=re,De.current=ie,Oe.current=N,ke.current=l},[P,F,I,L,R,z,ne,G,W,V,H,U,B,K,q,J,Y,re,ie,N,l]);let He=(0,t.useRef)(null),Ue=(0,t.useRef)(null),We=(0,t.useRef)(null),$=(0,t.useRef)(!1);(0,t.useEffect)(()=>{$.current&&He.current?.(N)},[N]),(0,t.useEffect)(()=>{Ae.current=E,$.current&&je.current>0&&We.current?.(je.current,Me.current)},[E]),(0,t.useEffect)(()=>{Ne.current=ce,$.current&&Q.current&&Fe.current?.(Q.current)},[ce]),(0,t.useEffect)(()=>{Ie.current=O,O?Le.current?.():Re.current?.()},[O]),(0,t.useEffect)(()=>{$.current=!1;let e=[],t=0,n=0,r=1,a=1,o=0,s=0,c=0,l=0,u=null,d=null,f=k.current;if(!f)return;let p=()=>u instanceof HTMLVideoElement?{width:u.videoWidth,height:u.videoHeight}:u?{width:u.naturalWidth,height:u.naturalHeight}:{width:0,height:0},_=f.getContext(`webgl2`);if(!_)return;_.pixelStorei(_.UNPACK_ALIGNMENT,1);let S=m(_);if(!S)return;let{program:C,pass1Program:T}=S;ee.current=S.atlasTexture,te.current=S.scatterAtlasTexture,_.uniform1i(S.shapeMatchingLoc,+(w===`shape`)),_.uniform1i(S.revealEffectFlagLoc,se),_.uniform1f(S.revealProgressLoc,0);let E=h({scatterEnabledRef:ge,mouseRadiusRef:ve,durationRef:xe,scatterCharsRef:Z}),D=g({brightenEnabledRef:he,trailLenRef:ye,durationRef:xe,trailDecayRef:be}),O=v({clickEnabledRef:Se,clickSpeedRef:we,clickBrightnessRef:Ce,pixelScaleRef:Pe}),A=y({spreadEnabledRef:Te,scatterCharsRef:Z,spreadExpandDurationRef:Ee,spreadSpeedRef:De}),j=0,N=!1,P=-1,F=-1,I=document.createElement(`canvas`),L=I.getContext(`2d`),R=u=>{let d=c>0?c:f.width,p=l>0?l:f.height;r=Math.max(1,Math.floor(d/u));let m=r*2;if(L.font=`${m}px monospace`,a=Math.max(1,Math.round(m*r/L.measureText(`M`).width)),t=Math.ceil(d/r),n=Math.ceil(p/a),o=Math.floor((d-t*r)/2),s=Math.floor((p-n*a)/2),_.viewport(0,0,f.width,f.height),_.useProgram(C),_.uniform2f(S.resLoc,f.width,f.height),_.uniform2f(S.gridOffsetLoc,o,s),_.useProgram(T),_.uniform2f(S.p1ResLoc,f.width,f.height),_.uniform2f(S.p1GridOffsetLoc,o,s),_.useProgram(C),E.setup(_,t,n,r,a,o,s,S.scatterStateTexture),A.setup(_,t,n,r,a,o,s,S.spreadStateTexture),w===`shape`){e=i(x,r,a);let o=e.length,s=new Float32Array(o*8);for(let t=0;t<o;t++){let n=e[t].vector;s[t*4+0]=n[0],s[t*4+1]=n[1],s[t*4+2]=n[2],s[t*4+3]=n[3],s[o*4+t*4+0]=n[4],s[o*4+t*4+1]=n[5]}_.activeTexture(_.TEXTURE2),_.bindTexture(_.TEXTURE_2D,S.charVectorsTexture),_.texImage2D(_.TEXTURE_2D,0,_.RGBA32F,o,2,0,_.RGBA,_.FLOAT,s),_.activeTexture(_.TEXTURE3),_.bindTexture(_.TEXTURE_2D,S.fboTexture),_.texImage2D(_.TEXTURE_2D,0,_.R8UI,t,n,0,_.RED_INTEGER,_.UNSIGNED_BYTE,null),_.bindFramebuffer(_.FRAMEBUFFER,S.fbo),_.framebufferTexture2D(_.FRAMEBUFFER,_.COLOR_ATTACHMENT0,_.TEXTURE_2D,S.fboTexture,0),_.bindFramebuffer(_.FRAMEBUFFER,null);let c=Math.max(1,Math.round(r/5));_.useProgram(T),_.uniform2f(S.p1CellsizeLoc,r,a),_.uniform1i(S.p1CircleNLoc,c),_.uniform1i(S.p1NumCharsLoc,o),_.uniform1f(S.p1ExponentLoc,2),_.useProgram(C)}_.uniform2f(S.gridSizeLoc,t,n),I.width=x.length*r,I.height=a,L.font=`${a}px monospace`,L.fillStyle=`black`,L.fillRect(0,0,x.length*r,a),L.fillStyle=`white`,L.textBaseline=`top`;for(let e=0;e<x.length;e++)L.fillText(x[e],e*r,0);_.activeTexture(_.TEXTURE1),_.bindTexture(_.TEXTURE_2D,ee.current),_.texImage2D(_.TEXTURE_2D,0,_.RGBA,_.RGBA,_.UNSIGNED_BYTE,I),_.uniform1f(S.numLoc,x.length),_.uniform2f(S.sizeLoc,r,a),z()},z=()=>{let e=Z.current;I.width=e.length*r,I.height=a,L.fillStyle=`black`,L.fillRect(0,0,I.width,a),L.fillStyle=`white`,L.textBaseline=`top`,L.font=`${a}px monospace`;for(let t=0;t<e.length;t++)L.fillText(e[t],t*r,0);_.activeTexture(_.TEXTURE4),_.bindTexture(_.TEXTURE_2D,te.current),_.texImage2D(_.TEXTURE_2D,0,_.RGBA,_.RGBA,_.UNSIGNED_BYTE,I),_.uniform1f(S.scatterNumCharsLoc,e.length),E.reset(_)};He.current=R,Ue.current=z;let ne=()=>{let e=p();if(e.width===0||e.height===0)return;let t=e.width/e.height,n=f.width/f.height,r=1,i=1,a=0,o=0;if(n>t)i=t/n,o=(1-i)/2;else{r=n/t;let e=Ae.current,i=e===`left`?.25:e===`right`?.75:.5;a=Math.max(0,Math.min(1-r,i-r/2))}_.uniform2f(S.cropOffsetLoc,a,o),_.uniform2f(S.cropScaleLoc,r,i),_.useProgram(T),_.uniform2f(S.p1CropOffsetLoc,a,o),_.uniform2f(S.p1CropScaleLoc,r,i),_.useProgram(C)},B=(e,t)=>{let n=Math.round(e),r=Math.round(t);(n!==c||r!==l)&&(c=n,l=r,je.current=c,Me.current=l,f.width=c,f.height=l,R(Oe.current)),ne()};We.current=B;let V=e=>{Q.current=e;let t=Math.min(1,Ne.current/(window.devicePixelRatio||1)),n=Math.max(1,Math.round(e.width*t)),r=Math.max(1,Math.round(e.height*t));Pe.current=e.cssWidth>0?n/e.cssWidth:1,B(n,r)};Fe.current=V;let H=e=>{if(!pe.current)return;let t=f.getBoundingClientRect(),n=(e.clientX-t.left)*(f.width/t.width),r=(e.clientY-t.top)*(f.height/t.height),i=performance.now();D.handleMouseMove(n,r,i),E.handleMouseMove(n,r,i)};f.addEventListener(`mousemove`,H);let U=()=>E.handleMouseLeave();f.addEventListener(`mouseleave`,U);let W=e=>{O.handleClick(e,f),A.handleClick(e,f)};f.addEventListener(`click`,W);let G=()=>{if(_.uniform1i(S.videoModeLoc,+!!ke.current),_.uniform1f(S.brightnessLoc,ue.current),_.uniform1f(S.saturationLoc,de.current),_.uniform1f(S.bgOpacityLoc,fe.current),_.uniform1i(S.mouseEffectFlagLoc,+!!he.current),_.uniform1i(S.scatterEffectFlagLoc,+!!ge.current),_.uniform1i(S.clickEffectFlagLoc,+!!Se.current),_.uniform1i(S.spreadEffectFlagLoc,+!!Te.current),_.uniform1f(S.mouseBrightnessLoc,_e.current),_.uniform1f(S.mouseRadiusLoc,Math.min(f.width,f.height)*ve.current),ae){let e=F<0?0:Math.min(1,(performance.now()-F)/(oe*1e3));_.uniform1f(S.revealProgressLoc,e)}$.current&&d&&d.currentTime!=P&&d.readyState>=2&&(_.activeTexture(_.TEXTURE0),_.bindTexture(_.TEXTURE_2D,S.texture),_.texSubImage2D(_.TEXTURE_2D,0,0,0,_.RGBA,_.UNSIGNED_BYTE,d),P=d.currentTime),D.tick(_,S.mousePositionsLoc,S.mouseLifeFracsLoc),E.tick(_,f),O.tick(_,f,S.ripplePositionsLoc,S.rippleRadiiLoc,S.rippleBrightnessesLoc),A.tick(_),w===`shape`&&(_.bindFramebuffer(_.FRAMEBUFFER,S.fbo),_.viewport(0,0,t,n),_.useProgram(T),_.drawArrays(_.TRIANGLES,0,6),_.bindFramebuffer(_.FRAMEBUFFER,null),_.viewport(0,0,f.width,f.height),_.useProgram(C)),_.drawArrays(_.TRIANGLES,0,6),j=requestAnimationFrame(G)},K=()=>{N||(N=!0,F<0&&(F=performance.now()),j=requestAnimationFrame(G))},q=()=>{N=!1,cancelAnimationFrame(j)};Le.current=()=>{q(),X||d?.pause()},Re.current=()=>{$.current&&(d?.play(),K())};let J=e=>{u=e,d=e instanceof HTMLVideoElement?e:null,P=-1,D.reset(),O.reset();let t=M.current,n=Q.current;if(n&&n.width>0&&n.height>0)V(n);else{let e=window.devicePixelRatio||1,n=p(),r=t.clientWidth||n.width,i=t.clientHeight||n.height;V({width:Math.round(r*e),height:Math.round(i*e),cssWidth:r,cssHeight:i})}_.activeTexture(_.TEXTURE0),_.bindTexture(_.TEXTURE_2D,S.texture),_.texImage2D(_.TEXTURE_2D,0,_.RGBA,_.RGBA,_.UNSIGNED_BYTE,e),F=-1,$.current=!0,q(),Ie.current?X||d?.pause():(d?.play(),K())};ze.current=J,Be.current=()=>{q(),$.current=!1,u=null,d=null};let Y=M.current?b(M.current,e=>{Q.current=e,$.current&&e.width>0&&e.height>0&&V(e)}):()=>{};return Ve.current&&J(Ve.current),()=>{Y(),He.current=null,Ue.current=null,We.current=null,Fe.current=null,Le.current=null,Re.current=null,ze.current=null,Be.current=null,$.current=!1,q(),f.removeEventListener(`mousemove`,H),f.removeEventListener(`mouseleave`,U),f.removeEventListener(`click`,W),_.deleteTexture(S.texture),_.deleteTexture(S.charVectorsTexture),_.deleteFramebuffer(S.fbo),_.deleteTexture(S.fboTexture),_.deleteBuffer(S.buffer),_.deleteShader(S.vertShader),_.deleteShader(S.fragShader),_.deleteShader(S.pass1FragShader),_.deleteProgram(C),_.deleteProgram(T),_.deleteTexture(ee.current),_.deleteTexture(te.current),_.deleteTexture(S.scatterStateTexture),_.deleteTexture(S.spreadStateTexture)}},[X,w,x,se,oe,ae]),(0,t.useEffect)(()=>{let t=X?o:le?j.current:A.current;if(!t)return;let n=t instanceof HTMLVideoElement?t:null,r=t instanceof HTMLImageElement?t:null,i=Array.isArray(e)?e:e===void 0?[]:[e],a=i.length>1,s=0,c=()=>{Ve.current=t,ze.current?.(t)},l=()=>{n&&(s=(s+1)%i.length,n.src=i[s],n.load(),n.addEventListener(`canplay`,()=>n.play(),{once:!0}))};return n?(n.addEventListener(`loadeddata`,c,{once:!X}),a&&n.addEventListener(`ended`,l),X?n.readyState>=2&&c():n.readyState>=2&&n.currentSrc.endsWith(i[0])?c():n.currentSrc.endsWith(i[0])||n.load()):r&&(r.complete&&r.naturalWidth>0?c():r.addEventListener(`load`,c,{once:!0})),()=>{n?(n.removeEventListener(`loadeddata`,c),a&&n.removeEventListener(`ended`,l)):r?.removeEventListener(`load`,c),Ve.current=null,Be.current?.()}},[e,o,X,le]);let Ge=Array.isArray(e)?e[0]:e;return(0,n.jsxs)(`div`,{ref:M,className:T,style:{height:`100%`,width:`100%`},children:[X?null:le?(0,n.jsx)(`img`,{ref:j,src:Ge,alt:``,style:{display:`none`}}):(0,n.jsx)(`video`,{ref:A,muted:!0,playsInline:!0,autoPlay:!0,loop:!Array.isArray(e)||e.length===1,style:{display:`none`},children:(0,n.jsx)(`source`,{src:Ge,type:`video/mp4`})}),(0,n.jsx)(`canvas`,{ref:k,style:{width:`100%`,height:`100%`,display:`block`}})]})}e.VideoAscii=x});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-video-ascii",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "description": "React component that renders videos and images as ASCII animations using WebGL2.",
6
6
  "author": "Lucas Jin",