@fjandin/react-shader 0.0.9 → 0.0.11
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 +4 -3
- package/dist/ReactShader.d.ts.map +1 -1
- package/dist/hooks/useWebGL.d.ts +2 -1
- package/dist/hooks/useWebGL.d.ts.map +1 -1
- package/dist/index.cjs +64 -37
- package/dist/index.js +65 -38
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,8 +48,7 @@ function App() {
|
|
|
48
48
|
| `fragment` | `string` | Yes | - | GLSL fragment shader source code |
|
|
49
49
|
| `vertex` | `string` | No | Default quad shader | GLSL vertex shader source code |
|
|
50
50
|
| `uniforms` | `Record<string, UniformValue>` | No | `{}` | Custom uniform values |
|
|
51
|
-
| `className` | `string` | No | - | CSS class name for the
|
|
52
|
-
| `debug` | `boolean` | No | `false` | Show debug overlay with resolution and mouse info |
|
|
51
|
+
| `className` | `string` | No | - | CSS class name for the canvas |
|
|
53
52
|
| `fullscreen` | `boolean` | No | `false` | Render as fixed fullscreen overlay |
|
|
54
53
|
| `timeScale` | `number` | No | `1` | Scale factor for elapsed time |
|
|
55
54
|
| `onFrame` | `(info: FrameInfo) => void` | No | - | Callback invoked on each frame |
|
|
@@ -175,6 +174,7 @@ The `FrameInfo` object contains:
|
|
|
175
174
|
- `time` - Total elapsed time in seconds
|
|
176
175
|
- `resolution` - Canvas resolution as `[width, height]`
|
|
177
176
|
- `mouse` - Mouse position as `[x, y]`
|
|
177
|
+
- `mouseNormalized` - Aspect-corrected mouse position as `[x, y]`
|
|
178
178
|
- `mouseLeftDown` - Whether left mouse button is pressed
|
|
179
179
|
|
|
180
180
|
## TypeScript
|
|
@@ -215,11 +215,12 @@ const declarations = generateUniformDeclarations({
|
|
|
215
215
|
## Features
|
|
216
216
|
|
|
217
217
|
- WebGL2 with WebGL1 fallback
|
|
218
|
-
- High-DPI display support
|
|
218
|
+
- High-DPI display support with automatic DPR change detection
|
|
219
219
|
- Automatic canvas resizing
|
|
220
220
|
- Shader compilation error display
|
|
221
221
|
- Context loss/restoration handling
|
|
222
222
|
- Mouse tracking with WebGL coordinate convention
|
|
223
|
+
- Optimized render loop with minimal per-frame allocations
|
|
223
224
|
|
|
224
225
|
## Requirements
|
|
225
226
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactShader.d.ts","sourceRoot":"","sources":["../src/ReactShader.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,
|
|
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,GACZ,EAAE,gBAAgB,2CAuDlB"}
|
package/dist/hooks/useWebGL.d.ts
CHANGED
|
@@ -6,8 +6,9 @@ interface UseWebGLOptions {
|
|
|
6
6
|
onError?: (error: Error) => void;
|
|
7
7
|
onFrame?: (info: FrameInfo) => void;
|
|
8
8
|
onClick?: (info: FrameInfo) => void;
|
|
9
|
+
onMouseDown?: (info: FrameInfo) => void;
|
|
10
|
+
onMouseUp?: (info: FrameInfo) => void;
|
|
9
11
|
onMouseMove?: (info: FrameInfo) => void;
|
|
10
|
-
running?: boolean;
|
|
11
12
|
timeScale?: number;
|
|
12
13
|
}
|
|
13
14
|
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;AAIvD,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,
|
|
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;AAIvD,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;AAqED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe;;;EAyRhD"}
|
package/dist/index.cjs
CHANGED
|
@@ -269,14 +269,26 @@ function useWebGL(options) {
|
|
|
269
269
|
const onErrorRef = import_react.useRef(options.onError);
|
|
270
270
|
const onFrameRef = import_react.useRef(options.onFrame);
|
|
271
271
|
const onClickRef = import_react.useRef(options.onClick);
|
|
272
|
+
const onMouseDownRef = import_react.useRef(options.onMouseDown);
|
|
273
|
+
const onMouseUpRef = import_react.useRef(options.onMouseUp);
|
|
272
274
|
const onMouseMoveRef = import_react.useRef(options.onMouseMove);
|
|
273
275
|
const timeScaleRef = import_react.useRef(options.timeScale ?? 1);
|
|
274
276
|
const vertexRef = import_react.useRef(options.vertex);
|
|
275
277
|
const fragmentRef = import_react.useRef(options.fragment);
|
|
278
|
+
const dprRef = import_react.useRef(window.devicePixelRatio || 1);
|
|
279
|
+
const defaultUniformsRef = import_react.useRef({
|
|
280
|
+
iTime: 0,
|
|
281
|
+
iMouse: [0, 0],
|
|
282
|
+
iMouseNormalized: [0, 0],
|
|
283
|
+
iMouseLeftDown: 0,
|
|
284
|
+
iResolution: [0, 0]
|
|
285
|
+
});
|
|
276
286
|
uniformsRef.current = options.uniforms;
|
|
277
287
|
onErrorRef.current = options.onError;
|
|
278
288
|
onFrameRef.current = options.onFrame;
|
|
279
289
|
onClickRef.current = options.onClick;
|
|
290
|
+
onMouseDownRef.current = options.onMouseDown;
|
|
291
|
+
onMouseUpRef.current = options.onMouseUp;
|
|
280
292
|
onMouseMoveRef.current = options.onMouseMove;
|
|
281
293
|
timeScaleRef.current = options.timeScale ?? 1;
|
|
282
294
|
vertexRef.current = options.vertex;
|
|
@@ -293,7 +305,7 @@ function useWebGL(options) {
|
|
|
293
305
|
elapsedTimeRef.current += deltaTime * timeScaleRef.current;
|
|
294
306
|
const { gl, program, positionAttributeLocation, uniformLocationCache } = state;
|
|
295
307
|
const elapsedTime = elapsedTimeRef.current;
|
|
296
|
-
const dpr =
|
|
308
|
+
const dpr = dprRef.current;
|
|
297
309
|
const displayWidth = canvas.clientWidth;
|
|
298
310
|
const displayHeight = canvas.clientHeight;
|
|
299
311
|
if (displayWidth === 0 || displayHeight === 0) {
|
|
@@ -313,22 +325,13 @@ function useWebGL(options) {
|
|
|
313
325
|
gl.enableVertexAttribArray(positionAttributeLocation);
|
|
314
326
|
gl.bindBuffer(gl.ARRAY_BUFFER, state.positionBuffer);
|
|
315
327
|
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
iMouse: mouseRef.current,
|
|
324
|
-
iMouseNormalized: mouseNormalizedRef.current,
|
|
325
|
-
iMouseLeftDown: mouseLeftDownRef.current ? 1 : 0,
|
|
326
|
-
iResolution: [canvas.width, canvas.height]
|
|
327
|
-
};
|
|
328
|
-
setUniforms(gl, program, defaultUniforms, uniformLocationCache);
|
|
329
|
-
if (uniformsRef.current) {
|
|
330
|
-
setUniforms(gl, program, uniformsRef.current, uniformLocationCache);
|
|
331
|
-
}
|
|
328
|
+
const defaultUniforms = defaultUniformsRef.current;
|
|
329
|
+
defaultUniforms.iTime = elapsedTime;
|
|
330
|
+
defaultUniforms.iMouse = mouseRef.current;
|
|
331
|
+
defaultUniforms.iMouseNormalized = mouseNormalizedRef.current;
|
|
332
|
+
defaultUniforms.iMouseLeftDown = mouseLeftDownRef.current ? 1 : 0;
|
|
333
|
+
defaultUniforms.iResolution = [canvas.width, canvas.height];
|
|
334
|
+
setUniforms(gl, program, { ...defaultUniforms, ...uniformsRef.current }, uniformLocationCache);
|
|
332
335
|
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
333
336
|
if (onFrameRef.current) {
|
|
334
337
|
onFrameRef.current({
|
|
@@ -371,10 +374,16 @@ function useWebGL(options) {
|
|
|
371
374
|
const handleContextRestored = () => {
|
|
372
375
|
initialize();
|
|
373
376
|
};
|
|
377
|
+
const dprMediaQuery = window.matchMedia(`(resolution: ${dprRef.current}dppx)`);
|
|
378
|
+
const handleDprChange = () => {
|
|
379
|
+
dprRef.current = window.devicePixelRatio || 1;
|
|
380
|
+
};
|
|
381
|
+
dprMediaQuery.addEventListener("change", handleDprChange);
|
|
374
382
|
canvas.addEventListener("webglcontextlost", handleContextLost);
|
|
375
383
|
canvas.addEventListener("webglcontextrestored", handleContextRestored);
|
|
376
384
|
initialize();
|
|
377
385
|
return () => {
|
|
386
|
+
dprMediaQuery.removeEventListener("change", handleDprChange);
|
|
378
387
|
canvas.removeEventListener("webglcontextlost", handleContextLost);
|
|
379
388
|
canvas.removeEventListener("webglcontextrestored", handleContextRestored);
|
|
380
389
|
cancelAnimationFrame(animationFrameRef.current);
|
|
@@ -399,7 +408,7 @@ function useWebGL(options) {
|
|
|
399
408
|
const rect = canvasRectRef.current;
|
|
400
409
|
if (!rect)
|
|
401
410
|
return;
|
|
402
|
-
const dpr =
|
|
411
|
+
const dpr = dprRef.current;
|
|
403
412
|
const x = (event.clientX - rect.left) * dpr;
|
|
404
413
|
const y = (rect.height - (event.clientY - rect.top)) * dpr;
|
|
405
414
|
mouseRef.current = [x, y];
|
|
@@ -421,11 +430,27 @@ function useWebGL(options) {
|
|
|
421
430
|
if (event.button === 0) {
|
|
422
431
|
mouseLeftDownRef.current = true;
|
|
423
432
|
}
|
|
433
|
+
onMouseDownRef.current?.({
|
|
434
|
+
deltaTime: 0,
|
|
435
|
+
time: elapsedTimeRef.current,
|
|
436
|
+
resolution: [canvas.width, canvas.height],
|
|
437
|
+
mouse: mouseRef.current,
|
|
438
|
+
mouseNormalized: mouseNormalizedRef.current,
|
|
439
|
+
mouseLeftDown: mouseLeftDownRef.current
|
|
440
|
+
});
|
|
424
441
|
};
|
|
425
442
|
const handleMouseUp = (event) => {
|
|
426
443
|
if (event.button === 0) {
|
|
427
444
|
mouseLeftDownRef.current = false;
|
|
428
445
|
}
|
|
446
|
+
onMouseUpRef.current?.({
|
|
447
|
+
deltaTime: 0,
|
|
448
|
+
time: elapsedTimeRef.current,
|
|
449
|
+
resolution: [canvas.width, canvas.height],
|
|
450
|
+
mouse: mouseRef.current,
|
|
451
|
+
mouseNormalized: mouseNormalizedRef.current,
|
|
452
|
+
mouseLeftDown: mouseLeftDownRef.current
|
|
453
|
+
});
|
|
429
454
|
};
|
|
430
455
|
const handleClick = () => {
|
|
431
456
|
if (!onClickRef.current)
|
|
@@ -464,6 +489,24 @@ void main() {
|
|
|
464
489
|
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
465
490
|
}
|
|
466
491
|
`;
|
|
492
|
+
var FULLSCREEN_CONTAINER_STYLE = {
|
|
493
|
+
position: "fixed",
|
|
494
|
+
top: 0,
|
|
495
|
+
left: 0,
|
|
496
|
+
width: "100vw",
|
|
497
|
+
height: "100vh",
|
|
498
|
+
zIndex: 9000
|
|
499
|
+
};
|
|
500
|
+
var DEFAULT_CONTAINER_STYLE = {
|
|
501
|
+
position: "relative",
|
|
502
|
+
width: "100%",
|
|
503
|
+
height: "100%"
|
|
504
|
+
};
|
|
505
|
+
var CANVAS_STYLE = {
|
|
506
|
+
display: "block",
|
|
507
|
+
width: "100%",
|
|
508
|
+
height: "100%"
|
|
509
|
+
};
|
|
467
510
|
function ReactShader({
|
|
468
511
|
className,
|
|
469
512
|
fragment,
|
|
@@ -480,11 +523,6 @@ function ReactShader({
|
|
|
480
523
|
setError(err.message);
|
|
481
524
|
console.error("ReactShader error:", err);
|
|
482
525
|
}, []);
|
|
483
|
-
const handleFrame = import_react2.useCallback((info) => {
|
|
484
|
-
if (onFrame) {
|
|
485
|
-
onFrame(info);
|
|
486
|
-
}
|
|
487
|
-
}, [onFrame]);
|
|
488
526
|
import_react2.useEffect(() => {
|
|
489
527
|
setError(null);
|
|
490
528
|
}, [fragment, vertex]);
|
|
@@ -493,23 +531,12 @@ function ReactShader({
|
|
|
493
531
|
vertex,
|
|
494
532
|
uniforms,
|
|
495
533
|
onError: handleError,
|
|
496
|
-
onFrame
|
|
534
|
+
onFrame,
|
|
497
535
|
onClick,
|
|
498
536
|
onMouseMove,
|
|
499
537
|
timeScale
|
|
500
538
|
});
|
|
501
|
-
const containerStyle = fullscreen ?
|
|
502
|
-
position: "fixed",
|
|
503
|
-
top: 0,
|
|
504
|
-
left: 0,
|
|
505
|
-
width: "100vw",
|
|
506
|
-
height: "100vh",
|
|
507
|
-
zIndex: 9000
|
|
508
|
-
} : {
|
|
509
|
-
position: "relative",
|
|
510
|
-
width: "100%",
|
|
511
|
-
height: "100%"
|
|
512
|
-
};
|
|
539
|
+
const containerStyle = import_react2.useMemo(() => fullscreen ? FULLSCREEN_CONTAINER_STYLE : DEFAULT_CONTAINER_STYLE, [fullscreen]);
|
|
513
540
|
if (error) {
|
|
514
541
|
return /* @__PURE__ */ jsx_dev_runtime.jsxDEV("div", {
|
|
515
542
|
className,
|
|
@@ -537,7 +564,7 @@ function ReactShader({
|
|
|
537
564
|
return /* @__PURE__ */ jsx_dev_runtime.jsxDEV("canvas", {
|
|
538
565
|
ref: canvasRef,
|
|
539
566
|
className,
|
|
540
|
-
style:
|
|
567
|
+
style: CANVAS_STYLE
|
|
541
568
|
}, undefined, false, undefined, this);
|
|
542
569
|
}
|
|
543
570
|
// src/shaders/color-palette.ts
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/ReactShader.tsx
|
|
2
|
-
import { useCallback as useCallback2, useEffect as useEffect2, useState } from "react";
|
|
2
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useState } from "react";
|
|
3
3
|
|
|
4
4
|
// src/hooks/useWebGL.ts
|
|
5
5
|
import { useCallback, useEffect, useRef } from "react";
|
|
@@ -229,14 +229,26 @@ function useWebGL(options) {
|
|
|
229
229
|
const onErrorRef = useRef(options.onError);
|
|
230
230
|
const onFrameRef = useRef(options.onFrame);
|
|
231
231
|
const onClickRef = useRef(options.onClick);
|
|
232
|
+
const onMouseDownRef = useRef(options.onMouseDown);
|
|
233
|
+
const onMouseUpRef = useRef(options.onMouseUp);
|
|
232
234
|
const onMouseMoveRef = useRef(options.onMouseMove);
|
|
233
235
|
const timeScaleRef = useRef(options.timeScale ?? 1);
|
|
234
236
|
const vertexRef = useRef(options.vertex);
|
|
235
237
|
const fragmentRef = useRef(options.fragment);
|
|
238
|
+
const dprRef = useRef(window.devicePixelRatio || 1);
|
|
239
|
+
const defaultUniformsRef = useRef({
|
|
240
|
+
iTime: 0,
|
|
241
|
+
iMouse: [0, 0],
|
|
242
|
+
iMouseNormalized: [0, 0],
|
|
243
|
+
iMouseLeftDown: 0,
|
|
244
|
+
iResolution: [0, 0]
|
|
245
|
+
});
|
|
236
246
|
uniformsRef.current = options.uniforms;
|
|
237
247
|
onErrorRef.current = options.onError;
|
|
238
248
|
onFrameRef.current = options.onFrame;
|
|
239
249
|
onClickRef.current = options.onClick;
|
|
250
|
+
onMouseDownRef.current = options.onMouseDown;
|
|
251
|
+
onMouseUpRef.current = options.onMouseUp;
|
|
240
252
|
onMouseMoveRef.current = options.onMouseMove;
|
|
241
253
|
timeScaleRef.current = options.timeScale ?? 1;
|
|
242
254
|
vertexRef.current = options.vertex;
|
|
@@ -253,7 +265,7 @@ function useWebGL(options) {
|
|
|
253
265
|
elapsedTimeRef.current += deltaTime * timeScaleRef.current;
|
|
254
266
|
const { gl, program, positionAttributeLocation, uniformLocationCache } = state;
|
|
255
267
|
const elapsedTime = elapsedTimeRef.current;
|
|
256
|
-
const dpr =
|
|
268
|
+
const dpr = dprRef.current;
|
|
257
269
|
const displayWidth = canvas.clientWidth;
|
|
258
270
|
const displayHeight = canvas.clientHeight;
|
|
259
271
|
if (displayWidth === 0 || displayHeight === 0) {
|
|
@@ -273,22 +285,13 @@ function useWebGL(options) {
|
|
|
273
285
|
gl.enableVertexAttribArray(positionAttributeLocation);
|
|
274
286
|
gl.bindBuffer(gl.ARRAY_BUFFER, state.positionBuffer);
|
|
275
287
|
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
iMouse: mouseRef.current,
|
|
284
|
-
iMouseNormalized: mouseNormalizedRef.current,
|
|
285
|
-
iMouseLeftDown: mouseLeftDownRef.current ? 1 : 0,
|
|
286
|
-
iResolution: [canvas.width, canvas.height]
|
|
287
|
-
};
|
|
288
|
-
setUniforms(gl, program, defaultUniforms, uniformLocationCache);
|
|
289
|
-
if (uniformsRef.current) {
|
|
290
|
-
setUniforms(gl, program, uniformsRef.current, uniformLocationCache);
|
|
291
|
-
}
|
|
288
|
+
const defaultUniforms = defaultUniformsRef.current;
|
|
289
|
+
defaultUniforms.iTime = elapsedTime;
|
|
290
|
+
defaultUniforms.iMouse = mouseRef.current;
|
|
291
|
+
defaultUniforms.iMouseNormalized = mouseNormalizedRef.current;
|
|
292
|
+
defaultUniforms.iMouseLeftDown = mouseLeftDownRef.current ? 1 : 0;
|
|
293
|
+
defaultUniforms.iResolution = [canvas.width, canvas.height];
|
|
294
|
+
setUniforms(gl, program, { ...defaultUniforms, ...uniformsRef.current }, uniformLocationCache);
|
|
292
295
|
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
293
296
|
if (onFrameRef.current) {
|
|
294
297
|
onFrameRef.current({
|
|
@@ -331,10 +334,16 @@ function useWebGL(options) {
|
|
|
331
334
|
const handleContextRestored = () => {
|
|
332
335
|
initialize();
|
|
333
336
|
};
|
|
337
|
+
const dprMediaQuery = window.matchMedia(`(resolution: ${dprRef.current}dppx)`);
|
|
338
|
+
const handleDprChange = () => {
|
|
339
|
+
dprRef.current = window.devicePixelRatio || 1;
|
|
340
|
+
};
|
|
341
|
+
dprMediaQuery.addEventListener("change", handleDprChange);
|
|
334
342
|
canvas.addEventListener("webglcontextlost", handleContextLost);
|
|
335
343
|
canvas.addEventListener("webglcontextrestored", handleContextRestored);
|
|
336
344
|
initialize();
|
|
337
345
|
return () => {
|
|
346
|
+
dprMediaQuery.removeEventListener("change", handleDprChange);
|
|
338
347
|
canvas.removeEventListener("webglcontextlost", handleContextLost);
|
|
339
348
|
canvas.removeEventListener("webglcontextrestored", handleContextRestored);
|
|
340
349
|
cancelAnimationFrame(animationFrameRef.current);
|
|
@@ -359,7 +368,7 @@ function useWebGL(options) {
|
|
|
359
368
|
const rect = canvasRectRef.current;
|
|
360
369
|
if (!rect)
|
|
361
370
|
return;
|
|
362
|
-
const dpr =
|
|
371
|
+
const dpr = dprRef.current;
|
|
363
372
|
const x = (event.clientX - rect.left) * dpr;
|
|
364
373
|
const y = (rect.height - (event.clientY - rect.top)) * dpr;
|
|
365
374
|
mouseRef.current = [x, y];
|
|
@@ -381,11 +390,27 @@ function useWebGL(options) {
|
|
|
381
390
|
if (event.button === 0) {
|
|
382
391
|
mouseLeftDownRef.current = true;
|
|
383
392
|
}
|
|
393
|
+
onMouseDownRef.current?.({
|
|
394
|
+
deltaTime: 0,
|
|
395
|
+
time: elapsedTimeRef.current,
|
|
396
|
+
resolution: [canvas.width, canvas.height],
|
|
397
|
+
mouse: mouseRef.current,
|
|
398
|
+
mouseNormalized: mouseNormalizedRef.current,
|
|
399
|
+
mouseLeftDown: mouseLeftDownRef.current
|
|
400
|
+
});
|
|
384
401
|
};
|
|
385
402
|
const handleMouseUp = (event) => {
|
|
386
403
|
if (event.button === 0) {
|
|
387
404
|
mouseLeftDownRef.current = false;
|
|
388
405
|
}
|
|
406
|
+
onMouseUpRef.current?.({
|
|
407
|
+
deltaTime: 0,
|
|
408
|
+
time: elapsedTimeRef.current,
|
|
409
|
+
resolution: [canvas.width, canvas.height],
|
|
410
|
+
mouse: mouseRef.current,
|
|
411
|
+
mouseNormalized: mouseNormalizedRef.current,
|
|
412
|
+
mouseLeftDown: mouseLeftDownRef.current
|
|
413
|
+
});
|
|
389
414
|
};
|
|
390
415
|
const handleClick = () => {
|
|
391
416
|
if (!onClickRef.current)
|
|
@@ -424,6 +449,24 @@ void main() {
|
|
|
424
449
|
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
425
450
|
}
|
|
426
451
|
`;
|
|
452
|
+
var FULLSCREEN_CONTAINER_STYLE = {
|
|
453
|
+
position: "fixed",
|
|
454
|
+
top: 0,
|
|
455
|
+
left: 0,
|
|
456
|
+
width: "100vw",
|
|
457
|
+
height: "100vh",
|
|
458
|
+
zIndex: 9000
|
|
459
|
+
};
|
|
460
|
+
var DEFAULT_CONTAINER_STYLE = {
|
|
461
|
+
position: "relative",
|
|
462
|
+
width: "100%",
|
|
463
|
+
height: "100%"
|
|
464
|
+
};
|
|
465
|
+
var CANVAS_STYLE = {
|
|
466
|
+
display: "block",
|
|
467
|
+
width: "100%",
|
|
468
|
+
height: "100%"
|
|
469
|
+
};
|
|
427
470
|
function ReactShader({
|
|
428
471
|
className,
|
|
429
472
|
fragment,
|
|
@@ -440,11 +483,6 @@ function ReactShader({
|
|
|
440
483
|
setError(err.message);
|
|
441
484
|
console.error("ReactShader error:", err);
|
|
442
485
|
}, []);
|
|
443
|
-
const handleFrame = useCallback2((info) => {
|
|
444
|
-
if (onFrame) {
|
|
445
|
-
onFrame(info);
|
|
446
|
-
}
|
|
447
|
-
}, [onFrame]);
|
|
448
486
|
useEffect2(() => {
|
|
449
487
|
setError(null);
|
|
450
488
|
}, [fragment, vertex]);
|
|
@@ -453,23 +491,12 @@ function ReactShader({
|
|
|
453
491
|
vertex,
|
|
454
492
|
uniforms,
|
|
455
493
|
onError: handleError,
|
|
456
|
-
onFrame
|
|
494
|
+
onFrame,
|
|
457
495
|
onClick,
|
|
458
496
|
onMouseMove,
|
|
459
497
|
timeScale
|
|
460
498
|
});
|
|
461
|
-
const containerStyle = fullscreen ?
|
|
462
|
-
position: "fixed",
|
|
463
|
-
top: 0,
|
|
464
|
-
left: 0,
|
|
465
|
-
width: "100vw",
|
|
466
|
-
height: "100vh",
|
|
467
|
-
zIndex: 9000
|
|
468
|
-
} : {
|
|
469
|
-
position: "relative",
|
|
470
|
-
width: "100%",
|
|
471
|
-
height: "100%"
|
|
472
|
-
};
|
|
499
|
+
const containerStyle = useMemo(() => fullscreen ? FULLSCREEN_CONTAINER_STYLE : DEFAULT_CONTAINER_STYLE, [fullscreen]);
|
|
473
500
|
if (error) {
|
|
474
501
|
return /* @__PURE__ */ jsxDEV("div", {
|
|
475
502
|
className,
|
|
@@ -497,7 +524,7 @@ function ReactShader({
|
|
|
497
524
|
return /* @__PURE__ */ jsxDEV("canvas", {
|
|
498
525
|
ref: canvasRef,
|
|
499
526
|
className,
|
|
500
|
-
style:
|
|
527
|
+
style: CANVAS_STYLE
|
|
501
528
|
}, undefined, false, undefined, this);
|
|
502
529
|
}
|
|
503
530
|
// src/shaders/color-palette.ts
|