@fjandin/react-shader 0.0.14 → 0.0.16

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.
@@ -1,3 +1,3 @@
1
1
  import type { ReactShaderProps } from "./types";
2
- export declare function ReactShader({ className, fragment, vertex, uniforms, fullscreen, timeScale, onFrame, onClick, onMouseMove, onMouseDown, onMouseUp, }: ReactShaderProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function ReactShader({ className, fragment, vertex, uniforms, fullscreen, timeScale, onFrame, onClick, onMouseMove, onMouseDown, onMouseUp, onMouseWheel, }: ReactShaderProps): import("react/jsx-runtime").JSX.Element;
3
3
  //# sourceMappingURL=ReactShader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReactShader.d.ts","sourceRoot":"","sources":["../src/ReactShader.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAgC/C,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,QAAQ,EACR,MAAuB,EACvB,QAAQ,EACR,UAAkB,EAClB,SAAa,EACb,OAAO,EACP,OAAO,EACP,WAAW,EACX,WAAW,EACX,SAAS,GACV,EAAE,gBAAgB,2CAyDlB"}
1
+ {"version":3,"file":"ReactShader.d.ts","sourceRoot":"","sources":["../src/ReactShader.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAiC/C,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,QAAQ,EACR,MAAuB,EACvB,QAAQ,EACR,UAAkB,EAClB,SAAa,EACb,OAAO,EACP,OAAO,EACP,WAAW,EACX,WAAW,EACX,SAAS,EACT,YAAY,GACb,EAAE,gBAAgB,2CA0DlB"}
@@ -1 +1 @@
1
- {"version":3,"file":"frontend.d.ts","sourceRoot":"","sources":["../../src/example/frontend.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,aAAa,CAAA;AAiHpB,wBAAgB,GAAG,4CAgGlB"}
1
+ {"version":3,"file":"frontend.d.ts","sourceRoot":"","sources":["../../src/example/frontend.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,aAAa,CAAA;AAkHpB,wBAAgB,GAAG,4CAiJlB"}
@@ -0,0 +1,3 @@
1
+ import type { UseAudioOptions, UseAudioReturn } from "../types";
2
+ export declare function useAudio(options?: UseAudioOptions): UseAudioReturn;
3
+ //# sourceMappingURL=useAudio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAudio.d.ts","sourceRoot":"","sources":["../../src/hooks/useAudio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAqC,eAAe,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AA6DlG,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,cAAc,CAsMtE"}
@@ -9,6 +9,7 @@ interface UseWebGLOptions {
9
9
  onMouseDown?: (info: FrameInfo) => void;
10
10
  onMouseUp?: (info: FrameInfo) => void;
11
11
  onMouseMove?: (info: FrameInfo) => void;
12
+ onMouseWheel?: (info: FrameInfo, wheelDelta: number) => void;
12
13
  timeScale?: number;
13
14
  }
14
15
  export declare function useWebGL(options: UseWebGLOptions): {
@@ -1 +1 @@
1
- {"version":3,"file":"useWebGL.d.ts","sourceRoot":"","sources":["../../src/hooks/useWebGL.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAKvD,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACvC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAChC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACrC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAwED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe;;;EAyRhD"}
1
+ {"version":3,"file":"useWebGL.d.ts","sourceRoot":"","sources":["../../src/hooks/useWebGL.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAKvD,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACvC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAChC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACrC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAwED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe;;;EA0ShD"}
package/dist/index.cjs CHANGED
@@ -29,6 +29,7 @@ var __export = (target, all) => {
29
29
  // src/index.ts
30
30
  var exports_src = {};
31
31
  __export(exports_src, {
32
+ useAudio: () => useAudio,
32
33
  generateUtilsFunction: () => generateUtilsFunction,
33
34
  generateSimplexNoiseFunction: () => generateSimplexNoiseFunction,
34
35
  generateSceneCirclesFunction: () => generateSceneCirclesFunction,
@@ -38,11 +39,219 @@ __export(exports_src, {
38
39
  });
39
40
  module.exports = __toCommonJS(exports_src);
40
41
 
42
+ // src/hooks/useAudio.ts
43
+ var import_react = require("react");
44
+ var DEFAULT_FFT_SIZE = 2048;
45
+ var DEFAULT_SMOOTHING_TIME_CONSTANT = 0.8;
46
+ var DEFAULT_SMOOTHING = 0.9;
47
+ var NUM_BANDS = 16;
48
+ var MIN_FREQ = 20;
49
+ var MAX_FREQ = 20000;
50
+ var DEFAULT_BANDS = {
51
+ low: [20, 250],
52
+ mid: [250, 4000],
53
+ high: [4000, 20000]
54
+ };
55
+ var EMPTY_BANDS = Array(NUM_BANDS).fill(0);
56
+ function hzToBin(hz, sampleRate, fftSize) {
57
+ const binFrequency = sampleRate / fftSize;
58
+ return Math.round(hz / binFrequency);
59
+ }
60
+ function calculateBandLevel(data, startBin, endBin) {
61
+ if (startBin >= endBin || startBin >= data.length)
62
+ return 0;
63
+ const clampedStart = Math.max(0, startBin);
64
+ const clampedEnd = Math.min(data.length, endBin);
65
+ let sum = 0;
66
+ for (let i = clampedStart;i < clampedEnd; i++) {
67
+ sum += data[i];
68
+ }
69
+ const count = clampedEnd - clampedStart;
70
+ return count > 0 ? sum / count / 255 : 0;
71
+ }
72
+ function lerp(a, b, t) {
73
+ return a + (b - a) * t;
74
+ }
75
+ function getLogFrequencyBands() {
76
+ const logMin = Math.log10(MIN_FREQ);
77
+ const logMax = Math.log10(MAX_FREQ);
78
+ const step = (logMax - logMin) / NUM_BANDS;
79
+ const frequencies = [];
80
+ for (let i = 0;i <= NUM_BANDS; i++) {
81
+ frequencies.push(10 ** (logMin + step * i));
82
+ }
83
+ return frequencies;
84
+ }
85
+ var LOG_FREQ_BANDS = getLogFrequencyBands();
86
+ function useAudio(options = {}) {
87
+ const {
88
+ source = "microphone",
89
+ mediaElement = null,
90
+ fftSize = DEFAULT_FFT_SIZE,
91
+ smoothingTimeConstant = DEFAULT_SMOOTHING_TIME_CONSTANT,
92
+ smoothing = DEFAULT_SMOOTHING,
93
+ frequencyBands = {}
94
+ } = options;
95
+ const bands = {
96
+ low: frequencyBands.low ?? DEFAULT_BANDS.low,
97
+ mid: frequencyBands.mid ?? DEFAULT_BANDS.mid,
98
+ high: frequencyBands.high ?? DEFAULT_BANDS.high
99
+ };
100
+ const [state, setState] = import_react.useState("disconnected");
101
+ const [error, setError] = import_react.useState(null);
102
+ const [isRunning, setIsRunning] = import_react.useState(false);
103
+ const [levels, setLevels] = import_react.useState({ low: 0, mid: 0, high: 0, bands: [...EMPTY_BANDS] });
104
+ const [frequencyData, setFrequencyData] = import_react.useState(null);
105
+ const audioStateRef = import_react.useRef(null);
106
+ const animationFrameRef = import_react.useRef(0);
107
+ const dataArrayRef = import_react.useRef(null);
108
+ const smoothedLevelsRef = import_react.useRef({ low: 0, mid: 0, high: 0, bands: [...EMPTY_BANDS] });
109
+ const analyze = import_react.useCallback(() => {
110
+ const audioState = audioStateRef.current;
111
+ if (!audioState)
112
+ return;
113
+ const { analyser } = audioState;
114
+ const dataArray = dataArrayRef.current;
115
+ if (!dataArray)
116
+ return;
117
+ analyser.getByteFrequencyData(dataArray);
118
+ const sampleRate = audioState.context.sampleRate;
119
+ const fftBins = analyser.fftSize;
120
+ const lowBins = [
121
+ hzToBin(bands.low[0], sampleRate, fftBins),
122
+ hzToBin(bands.low[1], sampleRate, fftBins)
123
+ ];
124
+ const midBins = [
125
+ hzToBin(bands.mid[0], sampleRate, fftBins),
126
+ hzToBin(bands.mid[1], sampleRate, fftBins)
127
+ ];
128
+ const highBins = [
129
+ hzToBin(bands.high[0], sampleRate, fftBins),
130
+ hzToBin(bands.high[1], sampleRate, fftBins)
131
+ ];
132
+ const rawBands = [];
133
+ for (let i = 0;i < NUM_BANDS; i++) {
134
+ const startBin = hzToBin(LOG_FREQ_BANDS[i], sampleRate, fftBins);
135
+ const endBin = hzToBin(LOG_FREQ_BANDS[i + 1], sampleRate, fftBins);
136
+ rawBands.push(calculateBandLevel(dataArray, startBin, endBin));
137
+ }
138
+ const rawLevels = {
139
+ low: calculateBandLevel(dataArray, lowBins[0], lowBins[1]),
140
+ mid: calculateBandLevel(dataArray, midBins[0], midBins[1]),
141
+ high: calculateBandLevel(dataArray, highBins[0], highBins[1]),
142
+ bands: rawBands
143
+ };
144
+ const t = 1 - smoothing;
145
+ const prev = smoothedLevelsRef.current;
146
+ const smoothedBands = rawBands.map((raw, i) => lerp(prev.bands[i] ?? 0, raw, t));
147
+ const smoothedLevels = {
148
+ low: lerp(prev.low, rawLevels.low, t),
149
+ mid: lerp(prev.mid, rawLevels.mid, t),
150
+ high: lerp(prev.high, rawLevels.high, t),
151
+ bands: smoothedBands
152
+ };
153
+ smoothedLevelsRef.current = smoothedLevels;
154
+ setLevels(smoothedLevels);
155
+ const dataCopy = new Uint8Array(dataArray.length);
156
+ dataCopy.set(dataArray);
157
+ setFrequencyData(dataCopy);
158
+ animationFrameRef.current = requestAnimationFrame(analyze);
159
+ }, [bands.low, bands.mid, bands.high, smoothing]);
160
+ const start = import_react.useCallback(async () => {
161
+ if (audioStateRef.current)
162
+ return;
163
+ setState("connecting");
164
+ setError(null);
165
+ try {
166
+ const AudioContextClass = window.AudioContext || window.webkitAudioContext;
167
+ if (!AudioContextClass) {
168
+ throw new Error("AudioContext not supported");
169
+ }
170
+ const context = new AudioContextClass;
171
+ if (context.state === "suspended") {
172
+ await context.resume();
173
+ }
174
+ const analyser = context.createAnalyser();
175
+ analyser.fftSize = fftSize;
176
+ analyser.smoothingTimeConstant = smoothingTimeConstant;
177
+ let audioSource;
178
+ let stream;
179
+ if (source === "microphone") {
180
+ stream = await navigator.mediaDevices.getUserMedia({ audio: true });
181
+ audioSource = context.createMediaStreamSource(stream);
182
+ } else if (source === "display") {
183
+ stream = await navigator.mediaDevices.getDisplayMedia({
184
+ video: true,
185
+ audio: true
186
+ });
187
+ const audioTracks = stream.getAudioTracks();
188
+ if (audioTracks.length === 0) {
189
+ for (const track of stream.getTracks()) {
190
+ track.stop();
191
+ }
192
+ throw new Error("No audio track available. Make sure to share a tab with audio enabled.");
193
+ }
194
+ audioSource = context.createMediaStreamSource(stream);
195
+ } else if (source === "element" && mediaElement) {
196
+ audioSource = context.createMediaElementSource(mediaElement);
197
+ audioSource.connect(context.destination);
198
+ } else {
199
+ throw new Error("Invalid audio source configuration");
200
+ }
201
+ audioSource.connect(analyser);
202
+ audioStateRef.current = {
203
+ context,
204
+ analyser,
205
+ source: audioSource,
206
+ stream
207
+ };
208
+ dataArrayRef.current = new Uint8Array(analyser.frequencyBinCount);
209
+ setState("connected");
210
+ setIsRunning(true);
211
+ animationFrameRef.current = requestAnimationFrame(analyze);
212
+ } catch (err) {
213
+ const audioError = err instanceof Error ? err : new Error(String(err));
214
+ setError(audioError);
215
+ setState("error");
216
+ setIsRunning(false);
217
+ }
218
+ }, [source, mediaElement, fftSize, smoothingTimeConstant, analyze]);
219
+ const stop = import_react.useCallback(() => {
220
+ cancelAnimationFrame(animationFrameRef.current);
221
+ const audioState = audioStateRef.current;
222
+ if (audioState) {
223
+ audioState.source.disconnect();
224
+ if (audioState.stream) {
225
+ for (const track of audioState.stream.getTracks()) {
226
+ track.stop();
227
+ }
228
+ }
229
+ audioState.analyser.disconnect();
230
+ audioState.context.close();
231
+ audioStateRef.current = null;
232
+ }
233
+ dataArrayRef.current = null;
234
+ smoothedLevelsRef.current = { low: 0, mid: 0, high: 0, bands: [...EMPTY_BANDS] };
235
+ setState("disconnected");
236
+ setIsRunning(false);
237
+ setLevels({ low: 0, mid: 0, high: 0, bands: [...EMPTY_BANDS] });
238
+ setFrequencyData(null);
239
+ }, []);
240
+ return {
241
+ levels,
242
+ frequencyData,
243
+ state,
244
+ error,
245
+ start,
246
+ stop,
247
+ isRunning
248
+ };
249
+ }
41
250
  // src/ReactShader.tsx
42
- var import_react2 = require("react");
251
+ var import_react3 = require("react");
43
252
 
44
253
  // src/hooks/useWebGL.ts
45
- var import_react = require("react");
254
+ var import_react2 = require("react");
46
255
 
47
256
  // src/utils/shader.ts
48
257
  function compileShader(gl, type, source) {
@@ -407,28 +616,29 @@ function cleanupWebGL(gl, state) {
407
616
  gl.deleteProgram(state.program);
408
617
  }
409
618
  function useWebGL(options) {
410
- const canvasRef = import_react.useRef(null);
411
- const stateRef = import_react.useRef(null);
412
- const animationFrameRef = import_react.useRef(0);
413
- const elapsedTimeRef = import_react.useRef(0);
414
- const lastFrameTimeRef = import_react.useRef(0);
415
- const mouseRef = import_react.useRef([0, 0]);
416
- const mouseNormalizedRef = import_react.useRef([0, 0]);
417
- const mouseLeftDownRef = import_react.useRef(false);
418
- const canvasRectRef = import_react.useRef(null);
419
- const contextLostRef = import_react.useRef(false);
420
- const uniformsRef = import_react.useRef(options.uniforms);
421
- const onErrorRef = import_react.useRef(options.onError);
422
- const onFrameRef = import_react.useRef(options.onFrame);
423
- const onClickRef = import_react.useRef(options.onClick);
424
- const onMouseDownRef = import_react.useRef(options.onMouseDown);
425
- const onMouseUpRef = import_react.useRef(options.onMouseUp);
426
- const onMouseMoveRef = import_react.useRef(options.onMouseMove);
427
- const timeScaleRef = import_react.useRef(options.timeScale ?? 1);
428
- const vertexRef = import_react.useRef(options.vertex);
429
- const fragmentRef = import_react.useRef(options.fragment);
430
- const dprRef = import_react.useRef(window.devicePixelRatio || 1);
431
- const defaultUniformsRef = import_react.useRef({
619
+ const canvasRef = import_react2.useRef(null);
620
+ const stateRef = import_react2.useRef(null);
621
+ const animationFrameRef = import_react2.useRef(0);
622
+ const elapsedTimeRef = import_react2.useRef(0);
623
+ const lastFrameTimeRef = import_react2.useRef(0);
624
+ const mouseRef = import_react2.useRef([0, 0]);
625
+ const mouseNormalizedRef = import_react2.useRef([0, 0]);
626
+ const mouseLeftDownRef = import_react2.useRef(false);
627
+ const canvasRectRef = import_react2.useRef(null);
628
+ const contextLostRef = import_react2.useRef(false);
629
+ const uniformsRef = import_react2.useRef(options.uniforms);
630
+ const onErrorRef = import_react2.useRef(options.onError);
631
+ const onFrameRef = import_react2.useRef(options.onFrame);
632
+ const onClickRef = import_react2.useRef(options.onClick);
633
+ const onMouseDownRef = import_react2.useRef(options.onMouseDown);
634
+ const onMouseUpRef = import_react2.useRef(options.onMouseUp);
635
+ const onMouseMoveRef = import_react2.useRef(options.onMouseMove);
636
+ const onMouseWheelRef = import_react2.useRef(options.onMouseWheel);
637
+ const timeScaleRef = import_react2.useRef(options.timeScale ?? 1);
638
+ const vertexRef = import_react2.useRef(options.vertex);
639
+ const fragmentRef = import_react2.useRef(options.fragment);
640
+ const dprRef = import_react2.useRef(window.devicePixelRatio || 1);
641
+ const defaultUniformsRef = import_react2.useRef({
432
642
  iTime: 0,
433
643
  iMouse: [0, 0],
434
644
  iMouseNormalized: [0, 0],
@@ -442,10 +652,11 @@ function useWebGL(options) {
442
652
  onMouseDownRef.current = options.onMouseDown;
443
653
  onMouseUpRef.current = options.onMouseUp;
444
654
  onMouseMoveRef.current = options.onMouseMove;
655
+ onMouseWheelRef.current = options.onMouseWheel;
445
656
  timeScaleRef.current = options.timeScale ?? 1;
446
657
  vertexRef.current = options.vertex;
447
658
  fragmentRef.current = options.fragment;
448
- const render = import_react.useCallback((time) => {
659
+ const render = import_react2.useCallback((time) => {
449
660
  if (contextLostRef.current)
450
661
  return;
451
662
  const state = stateRef.current;
@@ -497,7 +708,7 @@ function useWebGL(options) {
497
708
  }
498
709
  animationFrameRef.current = requestAnimationFrame(render);
499
710
  }, []);
500
- import_react.useEffect(() => {
711
+ import_react2.useEffect(() => {
501
712
  const canvas = canvasRef.current;
502
713
  if (!canvas)
503
714
  return;
@@ -545,7 +756,7 @@ function useWebGL(options) {
545
756
  }
546
757
  };
547
758
  }, [render]);
548
- import_react.useEffect(() => {
759
+ import_react2.useEffect(() => {
549
760
  const canvas = canvasRef.current;
550
761
  if (!canvas)
551
762
  return;
@@ -616,10 +827,21 @@ function useWebGL(options) {
616
827
  mouseLeftDown: mouseLeftDownRef.current
617
828
  });
618
829
  };
830
+ const handleMouseWheel = (event) => {
831
+ onMouseWheelRef.current?.({
832
+ deltaTime: 0,
833
+ time: elapsedTimeRef.current,
834
+ resolution: [canvas.width, canvas.height],
835
+ mouse: mouseRef.current,
836
+ mouseNormalized: mouseNormalizedRef.current,
837
+ mouseLeftDown: mouseLeftDownRef.current
838
+ }, event.deltaY);
839
+ };
619
840
  window.addEventListener("mousemove", handleMouseMove);
620
841
  window.addEventListener("mousedown", handleMouseDown);
621
842
  window.addEventListener("mouseup", handleMouseUp);
622
843
  canvas.addEventListener("click", handleClick);
844
+ window.addEventListener("wheel", handleMouseWheel);
623
845
  return () => {
624
846
  resizeObserver.disconnect();
625
847
  window.removeEventListener("scroll", updateRect);
@@ -627,6 +849,7 @@ function useWebGL(options) {
627
849
  window.removeEventListener("mousedown", handleMouseDown);
628
850
  window.removeEventListener("mouseup", handleMouseUp);
629
851
  canvas.removeEventListener("click", handleClick);
852
+ window.removeEventListener("wheel", handleMouseWheel);
630
853
  };
631
854
  }, []);
632
855
  return { canvasRef, mouseRef };
@@ -635,6 +858,7 @@ function useWebGL(options) {
635
858
  // src/ReactShader.tsx
636
859
  var jsx_dev_runtime = require("react/jsx-dev-runtime");
637
860
  var DEFAULT_VERTEX = `#version 300 es
861
+ precision highp float;
638
862
  in vec2 a_position;
639
863
 
640
864
  void main() {
@@ -670,14 +894,15 @@ function ReactShader({
670
894
  onClick,
671
895
  onMouseMove,
672
896
  onMouseDown,
673
- onMouseUp
897
+ onMouseUp,
898
+ onMouseWheel
674
899
  }) {
675
- const [error, setError] = import_react2.useState(null);
676
- const handleError = import_react2.useCallback((err) => {
900
+ const [error, setError] = import_react3.useState(null);
901
+ const handleError = import_react3.useCallback((err) => {
677
902
  setError(err.message);
678
903
  console.error("ReactShader error:", err);
679
904
  }, []);
680
- import_react2.useEffect(() => {
905
+ import_react3.useEffect(() => {
681
906
  setError(null);
682
907
  }, [fragment, vertex]);
683
908
  const { canvasRef } = useWebGL({
@@ -690,9 +915,10 @@ function ReactShader({
690
915
  onMouseMove,
691
916
  onMouseDown,
692
917
  onMouseUp,
918
+ onMouseWheel,
693
919
  timeScale
694
920
  });
695
- const containerStyle = import_react2.useMemo(() => fullscreen ? FULLSCREEN_CONTAINER_STYLE : DEFAULT_CONTAINER_STYLE, [fullscreen]);
921
+ const containerStyle = import_react3.useMemo(() => fullscreen ? FULLSCREEN_CONTAINER_STYLE : DEFAULT_CONTAINER_STYLE, [fullscreen]);
696
922
  if (error) {
697
923
  return /* @__PURE__ */ jsx_dev_runtime.jsxDEV("div", {
698
924
  className,
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
+ export { useAudio } from "./hooks/useAudio";
1
2
  export { ReactShader } from "./ReactShader";
2
3
  export { generateColorPaletteFunction } from "./shaders/color-palette";
3
4
  export { generateDistortionRippleFunction } from "./shaders/distortion-ripple";
4
5
  export { generateSceneCirclesFunction } from "./shaders/scene-circles";
5
6
  export { generateSimplexNoiseFunction } from "./shaders/simplex-noise";
6
7
  export { generateUtilsFunction } from "./shaders/utils";
7
- export type { DefaultUniforms, FloatArray, FrameInfo, ReactShaderProps, TextureMagFilter, TextureMinFilter, TextureOptions, TextureSource, TextureWrap, UniformValue, Vec2, Vec2Array, Vec3, Vec3Array, Vec4, Vec4Array, } from "./types";
8
+ export type { AudioConnectionState, AudioLevels, AudioSourceType, DefaultUniforms, FloatArray, FrameInfo, ReactShaderProps, TextureMagFilter, TextureMinFilter, TextureOptions, TextureSource, TextureWrap, UniformValue, UseAudioOptions, UseAudioReturn, Vec2, Vec2Array, Vec3, Vec3Array, Vec4, Vec4Array, } from "./types";
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAA;AAC9E,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AACvD,YAAY,EACV,eAAe,EACf,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,WAAW,EACX,YAAY,EACZ,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,SAAS,GACV,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAA;AAC9E,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AACvD,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,eAAe,EACf,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,WAAW,EACX,YAAY,EACZ,eAAe,EACf,cAAc,EACd,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,SAAS,GACV,MAAM,SAAS,CAAA"}
package/dist/index.js CHANGED
@@ -1,8 +1,216 @@
1
+ // src/hooks/useAudio.ts
2
+ import { useCallback, useRef, useState } from "react";
3
+ var DEFAULT_FFT_SIZE = 2048;
4
+ var DEFAULT_SMOOTHING_TIME_CONSTANT = 0.8;
5
+ var DEFAULT_SMOOTHING = 0.9;
6
+ var NUM_BANDS = 16;
7
+ var MIN_FREQ = 20;
8
+ var MAX_FREQ = 20000;
9
+ var DEFAULT_BANDS = {
10
+ low: [20, 250],
11
+ mid: [250, 4000],
12
+ high: [4000, 20000]
13
+ };
14
+ var EMPTY_BANDS = Array(NUM_BANDS).fill(0);
15
+ function hzToBin(hz, sampleRate, fftSize) {
16
+ const binFrequency = sampleRate / fftSize;
17
+ return Math.round(hz / binFrequency);
18
+ }
19
+ function calculateBandLevel(data, startBin, endBin) {
20
+ if (startBin >= endBin || startBin >= data.length)
21
+ return 0;
22
+ const clampedStart = Math.max(0, startBin);
23
+ const clampedEnd = Math.min(data.length, endBin);
24
+ let sum = 0;
25
+ for (let i = clampedStart;i < clampedEnd; i++) {
26
+ sum += data[i];
27
+ }
28
+ const count = clampedEnd - clampedStart;
29
+ return count > 0 ? sum / count / 255 : 0;
30
+ }
31
+ function lerp(a, b, t) {
32
+ return a + (b - a) * t;
33
+ }
34
+ function getLogFrequencyBands() {
35
+ const logMin = Math.log10(MIN_FREQ);
36
+ const logMax = Math.log10(MAX_FREQ);
37
+ const step = (logMax - logMin) / NUM_BANDS;
38
+ const frequencies = [];
39
+ for (let i = 0;i <= NUM_BANDS; i++) {
40
+ frequencies.push(10 ** (logMin + step * i));
41
+ }
42
+ return frequencies;
43
+ }
44
+ var LOG_FREQ_BANDS = getLogFrequencyBands();
45
+ function useAudio(options = {}) {
46
+ const {
47
+ source = "microphone",
48
+ mediaElement = null,
49
+ fftSize = DEFAULT_FFT_SIZE,
50
+ smoothingTimeConstant = DEFAULT_SMOOTHING_TIME_CONSTANT,
51
+ smoothing = DEFAULT_SMOOTHING,
52
+ frequencyBands = {}
53
+ } = options;
54
+ const bands = {
55
+ low: frequencyBands.low ?? DEFAULT_BANDS.low,
56
+ mid: frequencyBands.mid ?? DEFAULT_BANDS.mid,
57
+ high: frequencyBands.high ?? DEFAULT_BANDS.high
58
+ };
59
+ const [state, setState] = useState("disconnected");
60
+ const [error, setError] = useState(null);
61
+ const [isRunning, setIsRunning] = useState(false);
62
+ const [levels, setLevels] = useState({ low: 0, mid: 0, high: 0, bands: [...EMPTY_BANDS] });
63
+ const [frequencyData, setFrequencyData] = useState(null);
64
+ const audioStateRef = useRef(null);
65
+ const animationFrameRef = useRef(0);
66
+ const dataArrayRef = useRef(null);
67
+ const smoothedLevelsRef = useRef({ low: 0, mid: 0, high: 0, bands: [...EMPTY_BANDS] });
68
+ const analyze = useCallback(() => {
69
+ const audioState = audioStateRef.current;
70
+ if (!audioState)
71
+ return;
72
+ const { analyser } = audioState;
73
+ const dataArray = dataArrayRef.current;
74
+ if (!dataArray)
75
+ return;
76
+ analyser.getByteFrequencyData(dataArray);
77
+ const sampleRate = audioState.context.sampleRate;
78
+ const fftBins = analyser.fftSize;
79
+ const lowBins = [
80
+ hzToBin(bands.low[0], sampleRate, fftBins),
81
+ hzToBin(bands.low[1], sampleRate, fftBins)
82
+ ];
83
+ const midBins = [
84
+ hzToBin(bands.mid[0], sampleRate, fftBins),
85
+ hzToBin(bands.mid[1], sampleRate, fftBins)
86
+ ];
87
+ const highBins = [
88
+ hzToBin(bands.high[0], sampleRate, fftBins),
89
+ hzToBin(bands.high[1], sampleRate, fftBins)
90
+ ];
91
+ const rawBands = [];
92
+ for (let i = 0;i < NUM_BANDS; i++) {
93
+ const startBin = hzToBin(LOG_FREQ_BANDS[i], sampleRate, fftBins);
94
+ const endBin = hzToBin(LOG_FREQ_BANDS[i + 1], sampleRate, fftBins);
95
+ rawBands.push(calculateBandLevel(dataArray, startBin, endBin));
96
+ }
97
+ const rawLevels = {
98
+ low: calculateBandLevel(dataArray, lowBins[0], lowBins[1]),
99
+ mid: calculateBandLevel(dataArray, midBins[0], midBins[1]),
100
+ high: calculateBandLevel(dataArray, highBins[0], highBins[1]),
101
+ bands: rawBands
102
+ };
103
+ const t = 1 - smoothing;
104
+ const prev = smoothedLevelsRef.current;
105
+ const smoothedBands = rawBands.map((raw, i) => lerp(prev.bands[i] ?? 0, raw, t));
106
+ const smoothedLevels = {
107
+ low: lerp(prev.low, rawLevels.low, t),
108
+ mid: lerp(prev.mid, rawLevels.mid, t),
109
+ high: lerp(prev.high, rawLevels.high, t),
110
+ bands: smoothedBands
111
+ };
112
+ smoothedLevelsRef.current = smoothedLevels;
113
+ setLevels(smoothedLevels);
114
+ const dataCopy = new Uint8Array(dataArray.length);
115
+ dataCopy.set(dataArray);
116
+ setFrequencyData(dataCopy);
117
+ animationFrameRef.current = requestAnimationFrame(analyze);
118
+ }, [bands.low, bands.mid, bands.high, smoothing]);
119
+ const start = useCallback(async () => {
120
+ if (audioStateRef.current)
121
+ return;
122
+ setState("connecting");
123
+ setError(null);
124
+ try {
125
+ const AudioContextClass = window.AudioContext || window.webkitAudioContext;
126
+ if (!AudioContextClass) {
127
+ throw new Error("AudioContext not supported");
128
+ }
129
+ const context = new AudioContextClass;
130
+ if (context.state === "suspended") {
131
+ await context.resume();
132
+ }
133
+ const analyser = context.createAnalyser();
134
+ analyser.fftSize = fftSize;
135
+ analyser.smoothingTimeConstant = smoothingTimeConstant;
136
+ let audioSource;
137
+ let stream;
138
+ if (source === "microphone") {
139
+ stream = await navigator.mediaDevices.getUserMedia({ audio: true });
140
+ audioSource = context.createMediaStreamSource(stream);
141
+ } else if (source === "display") {
142
+ stream = await navigator.mediaDevices.getDisplayMedia({
143
+ video: true,
144
+ audio: true
145
+ });
146
+ const audioTracks = stream.getAudioTracks();
147
+ if (audioTracks.length === 0) {
148
+ for (const track of stream.getTracks()) {
149
+ track.stop();
150
+ }
151
+ throw new Error("No audio track available. Make sure to share a tab with audio enabled.");
152
+ }
153
+ audioSource = context.createMediaStreamSource(stream);
154
+ } else if (source === "element" && mediaElement) {
155
+ audioSource = context.createMediaElementSource(mediaElement);
156
+ audioSource.connect(context.destination);
157
+ } else {
158
+ throw new Error("Invalid audio source configuration");
159
+ }
160
+ audioSource.connect(analyser);
161
+ audioStateRef.current = {
162
+ context,
163
+ analyser,
164
+ source: audioSource,
165
+ stream
166
+ };
167
+ dataArrayRef.current = new Uint8Array(analyser.frequencyBinCount);
168
+ setState("connected");
169
+ setIsRunning(true);
170
+ animationFrameRef.current = requestAnimationFrame(analyze);
171
+ } catch (err) {
172
+ const audioError = err instanceof Error ? err : new Error(String(err));
173
+ setError(audioError);
174
+ setState("error");
175
+ setIsRunning(false);
176
+ }
177
+ }, [source, mediaElement, fftSize, smoothingTimeConstant, analyze]);
178
+ const stop = useCallback(() => {
179
+ cancelAnimationFrame(animationFrameRef.current);
180
+ const audioState = audioStateRef.current;
181
+ if (audioState) {
182
+ audioState.source.disconnect();
183
+ if (audioState.stream) {
184
+ for (const track of audioState.stream.getTracks()) {
185
+ track.stop();
186
+ }
187
+ }
188
+ audioState.analyser.disconnect();
189
+ audioState.context.close();
190
+ audioStateRef.current = null;
191
+ }
192
+ dataArrayRef.current = null;
193
+ smoothedLevelsRef.current = { low: 0, mid: 0, high: 0, bands: [...EMPTY_BANDS] };
194
+ setState("disconnected");
195
+ setIsRunning(false);
196
+ setLevels({ low: 0, mid: 0, high: 0, bands: [...EMPTY_BANDS] });
197
+ setFrequencyData(null);
198
+ }, []);
199
+ return {
200
+ levels,
201
+ frequencyData,
202
+ state,
203
+ error,
204
+ start,
205
+ stop,
206
+ isRunning
207
+ };
208
+ }
1
209
  // src/ReactShader.tsx
2
- import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useState } from "react";
210
+ import { useCallback as useCallback3, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
3
211
 
4
212
  // src/hooks/useWebGL.ts
5
- import { useCallback, useEffect, useRef } from "react";
213
+ import { useCallback as useCallback2, useEffect, useRef as useRef2 } from "react";
6
214
 
7
215
  // src/utils/shader.ts
8
216
  function compileShader(gl, type, source) {
@@ -367,28 +575,29 @@ function cleanupWebGL(gl, state) {
367
575
  gl.deleteProgram(state.program);
368
576
  }
369
577
  function useWebGL(options) {
370
- const canvasRef = useRef(null);
371
- const stateRef = useRef(null);
372
- const animationFrameRef = useRef(0);
373
- const elapsedTimeRef = useRef(0);
374
- const lastFrameTimeRef = useRef(0);
375
- const mouseRef = useRef([0, 0]);
376
- const mouseNormalizedRef = useRef([0, 0]);
377
- const mouseLeftDownRef = useRef(false);
378
- const canvasRectRef = useRef(null);
379
- const contextLostRef = useRef(false);
380
- const uniformsRef = useRef(options.uniforms);
381
- const onErrorRef = useRef(options.onError);
382
- const onFrameRef = useRef(options.onFrame);
383
- const onClickRef = useRef(options.onClick);
384
- const onMouseDownRef = useRef(options.onMouseDown);
385
- const onMouseUpRef = useRef(options.onMouseUp);
386
- const onMouseMoveRef = useRef(options.onMouseMove);
387
- const timeScaleRef = useRef(options.timeScale ?? 1);
388
- const vertexRef = useRef(options.vertex);
389
- const fragmentRef = useRef(options.fragment);
390
- const dprRef = useRef(window.devicePixelRatio || 1);
391
- const defaultUniformsRef = useRef({
578
+ const canvasRef = useRef2(null);
579
+ const stateRef = useRef2(null);
580
+ const animationFrameRef = useRef2(0);
581
+ const elapsedTimeRef = useRef2(0);
582
+ const lastFrameTimeRef = useRef2(0);
583
+ const mouseRef = useRef2([0, 0]);
584
+ const mouseNormalizedRef = useRef2([0, 0]);
585
+ const mouseLeftDownRef = useRef2(false);
586
+ const canvasRectRef = useRef2(null);
587
+ const contextLostRef = useRef2(false);
588
+ const uniformsRef = useRef2(options.uniforms);
589
+ const onErrorRef = useRef2(options.onError);
590
+ const onFrameRef = useRef2(options.onFrame);
591
+ const onClickRef = useRef2(options.onClick);
592
+ const onMouseDownRef = useRef2(options.onMouseDown);
593
+ const onMouseUpRef = useRef2(options.onMouseUp);
594
+ const onMouseMoveRef = useRef2(options.onMouseMove);
595
+ const onMouseWheelRef = useRef2(options.onMouseWheel);
596
+ const timeScaleRef = useRef2(options.timeScale ?? 1);
597
+ const vertexRef = useRef2(options.vertex);
598
+ const fragmentRef = useRef2(options.fragment);
599
+ const dprRef = useRef2(window.devicePixelRatio || 1);
600
+ const defaultUniformsRef = useRef2({
392
601
  iTime: 0,
393
602
  iMouse: [0, 0],
394
603
  iMouseNormalized: [0, 0],
@@ -402,10 +611,11 @@ function useWebGL(options) {
402
611
  onMouseDownRef.current = options.onMouseDown;
403
612
  onMouseUpRef.current = options.onMouseUp;
404
613
  onMouseMoveRef.current = options.onMouseMove;
614
+ onMouseWheelRef.current = options.onMouseWheel;
405
615
  timeScaleRef.current = options.timeScale ?? 1;
406
616
  vertexRef.current = options.vertex;
407
617
  fragmentRef.current = options.fragment;
408
- const render = useCallback((time) => {
618
+ const render = useCallback2((time) => {
409
619
  if (contextLostRef.current)
410
620
  return;
411
621
  const state = stateRef.current;
@@ -576,10 +786,21 @@ function useWebGL(options) {
576
786
  mouseLeftDown: mouseLeftDownRef.current
577
787
  });
578
788
  };
789
+ const handleMouseWheel = (event) => {
790
+ onMouseWheelRef.current?.({
791
+ deltaTime: 0,
792
+ time: elapsedTimeRef.current,
793
+ resolution: [canvas.width, canvas.height],
794
+ mouse: mouseRef.current,
795
+ mouseNormalized: mouseNormalizedRef.current,
796
+ mouseLeftDown: mouseLeftDownRef.current
797
+ }, event.deltaY);
798
+ };
579
799
  window.addEventListener("mousemove", handleMouseMove);
580
800
  window.addEventListener("mousedown", handleMouseDown);
581
801
  window.addEventListener("mouseup", handleMouseUp);
582
802
  canvas.addEventListener("click", handleClick);
803
+ window.addEventListener("wheel", handleMouseWheel);
583
804
  return () => {
584
805
  resizeObserver.disconnect();
585
806
  window.removeEventListener("scroll", updateRect);
@@ -587,6 +808,7 @@ function useWebGL(options) {
587
808
  window.removeEventListener("mousedown", handleMouseDown);
588
809
  window.removeEventListener("mouseup", handleMouseUp);
589
810
  canvas.removeEventListener("click", handleClick);
811
+ window.removeEventListener("wheel", handleMouseWheel);
590
812
  };
591
813
  }, []);
592
814
  return { canvasRef, mouseRef };
@@ -595,6 +817,7 @@ function useWebGL(options) {
595
817
  // src/ReactShader.tsx
596
818
  import { jsxDEV } from "react/jsx-dev-runtime";
597
819
  var DEFAULT_VERTEX = `#version 300 es
820
+ precision highp float;
598
821
  in vec2 a_position;
599
822
 
600
823
  void main() {
@@ -630,10 +853,11 @@ function ReactShader({
630
853
  onClick,
631
854
  onMouseMove,
632
855
  onMouseDown,
633
- onMouseUp
856
+ onMouseUp,
857
+ onMouseWheel
634
858
  }) {
635
- const [error, setError] = useState(null);
636
- const handleError = useCallback2((err) => {
859
+ const [error, setError] = useState2(null);
860
+ const handleError = useCallback3((err) => {
637
861
  setError(err.message);
638
862
  console.error("ReactShader error:", err);
639
863
  }, []);
@@ -650,6 +874,7 @@ function ReactShader({
650
874
  onMouseMove,
651
875
  onMouseDown,
652
876
  onMouseUp,
877
+ onMouseWheel,
653
878
  timeScale
654
879
  });
655
880
  const containerStyle = useMemo(() => fullscreen ? FULLSCREEN_CONTAINER_STYLE : DEFAULT_CONTAINER_STYLE, [fullscreen]);
@@ -950,6 +1175,7 @@ function generateUtilsFunction() {
950
1175
  `;
951
1176
  }
952
1177
  export {
1178
+ useAudio,
953
1179
  generateUtilsFunction,
954
1180
  generateSimplexNoiseFunction,
955
1181
  generateSceneCirclesFunction,
package/dist/types.d.ts CHANGED
@@ -38,6 +38,7 @@ export interface ReactShaderProps {
38
38
  onMouseMove?: (info: FrameInfo) => void;
39
39
  onMouseDown?: (info: FrameInfo) => void;
40
40
  onMouseUp?: (info: FrameInfo) => void;
41
+ onMouseWheel?: (info: FrameInfo, wheelDelta: number) => void;
41
42
  }
42
43
  export interface DefaultUniforms {
43
44
  iTime: number;
@@ -46,4 +47,33 @@ export interface DefaultUniforms {
46
47
  iMouseLeftDown: number;
47
48
  iResolution: Vec2;
48
49
  }
50
+ export interface AudioLevels {
51
+ low: number;
52
+ mid: number;
53
+ high: number;
54
+ bands: number[];
55
+ }
56
+ export type AudioSourceType = "microphone" | "element" | "display";
57
+ export type AudioConnectionState = "disconnected" | "connecting" | "connected" | "error";
58
+ export interface UseAudioOptions {
59
+ source?: AudioSourceType;
60
+ mediaElement?: HTMLAudioElement | HTMLVideoElement | null;
61
+ fftSize?: number;
62
+ smoothingTimeConstant?: number;
63
+ smoothing?: number;
64
+ frequencyBands?: Partial<{
65
+ low: [number, number];
66
+ mid: [number, number];
67
+ high: [number, number];
68
+ }>;
69
+ }
70
+ export interface UseAudioReturn {
71
+ levels: AudioLevels;
72
+ frequencyData: Uint8Array<ArrayBuffer> | null;
73
+ state: AudioConnectionState;
74
+ error: Error | null;
75
+ start: () => Promise<void>;
76
+ stop: () => void;
77
+ isRunning: boolean;
78
+ }
49
79
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AACnC,MAAM,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAC3C,MAAM,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAEnD,MAAM,MAAM,UAAU,GAAG,MAAM,EAAE,CAAA;AACjC,MAAM,MAAM,SAAS,GAAG,IAAI,EAAE,CAAA;AAC9B,MAAM,MAAM,SAAS,GAAG,IAAI,EAAE,CAAA;AAC9B,MAAM,MAAM,SAAS,GAAG,IAAI,EAAE,CAAA;AAE9B,MAAM,MAAM,aAAa,GACrB,gBAAgB,GAChB,iBAAiB,GACjB,gBAAgB,GAChB,WAAW,GACX,SAAS,GACT,eAAe,CAAA;AAEnB,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAA;AACvD,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAC9D,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,QAAQ,CAAA;AAEnD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,aAAa,CAAA;IACrB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,SAAS,CAAC,EAAE,gBAAgB,CAAA;IAC5B,SAAS,CAAC,EAAE,gBAAgB,CAAA;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,UAAU,GACV,SAAS,GACT,SAAS,GACT,SAAS,GACT,aAAa,GACb,cAAc,CAAA;AAElB,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACvB,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,aAAa,EAAE,OAAO,CAAA;CACvB;AACD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACvC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;CACtC;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,IAAI,CAAA;IACZ,gBAAgB,EAAE,IAAI,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,IAAI,CAAA;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjandin/react-shader",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "React component for rendering WebGL shaders",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",