@fjandin/react-shader 0.0.17 → 0.0.19
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/dist/ReactGpuShader.d.ts +9 -2
- package/dist/ReactGpuShader.d.ts.map +1 -1
- package/dist/example/examples/mandelbrot.d.ts +2 -0
- package/dist/example/examples/mandelbrot.d.ts.map +1 -0
- package/dist/example/examples/mandelbrot2.d.ts +2 -0
- package/dist/example/examples/mandelbrot2.d.ts.map +1 -0
- package/dist/example/examples/webgpu.d.ts.map +1 -1
- package/dist/example/frontend.d.ts.map +1 -1
- package/dist/hooks/useWebGPU.d.ts +8 -1
- package/dist/hooks/useWebGPU.d.ts.map +1 -1
- package/dist/index.cjs +73 -5
- package/dist/index.js +73 -5
- package/package.json +1 -1
package/dist/ReactGpuShader.d.ts
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import type { Vec2, Vec3, Vec4, Vec4Array } from "./types";
|
|
1
|
+
import type { FrameInfo, Vec2, Vec3, Vec4, Vec4Array } from "./types";
|
|
2
2
|
type GpuUniformValue = number | Vec2 | Vec3 | Vec4 | Vec4Array;
|
|
3
3
|
export interface ReactGpuShaderProps {
|
|
4
4
|
className?: string;
|
|
5
5
|
fragment: string;
|
|
6
6
|
uniforms?: Record<string, GpuUniformValue>;
|
|
7
7
|
fullscreen?: boolean;
|
|
8
|
+
timeScale?: number;
|
|
9
|
+
onFrame?: (info: FrameInfo) => void;
|
|
10
|
+
onClick?: (info: FrameInfo) => void;
|
|
11
|
+
onMouseMove?: (info: FrameInfo) => void;
|
|
12
|
+
onMouseDown?: (info: FrameInfo) => void;
|
|
13
|
+
onMouseUp?: (info: FrameInfo) => void;
|
|
14
|
+
onMouseWheel?: (info: FrameInfo, wheelDelta: number) => void;
|
|
8
15
|
}
|
|
9
|
-
export declare function ReactGpuShader({ className, fragment, uniforms, fullscreen }: ReactGpuShaderProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export declare function ReactGpuShader({ className, fragment, uniforms, fullscreen, timeScale, onFrame, onClick, onMouseMove, onMouseDown, onMouseUp, onMouseWheel, }: ReactGpuShaderProps): import("react/jsx-runtime").JSX.Element;
|
|
10
17
|
export {};
|
|
11
18
|
//# sourceMappingURL=ReactGpuShader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactGpuShader.d.ts","sourceRoot":"","sources":["../src/ReactGpuShader.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"ReactGpuShader.d.ts","sourceRoot":"","sources":["../src/ReactGpuShader.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAGrE,KAAK,eAAe,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAA;AAE9D,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IAC1C,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;IACrC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;CAC7D;AAuBD,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,UAAkB,EAClB,SAAS,EACT,OAAO,EACP,OAAO,EACP,WAAW,EACX,WAAW,EACX,SAAS,EACT,YAAY,GACb,EAAE,mBAAmB,2CAyDrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mandelbrot.d.ts","sourceRoot":"","sources":["../../../src/example/examples/mandelbrot.tsx"],"names":[],"mappings":"AA8BA,wBAAgB,oBAAoB,4CAiFnC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mandelbrot2.d.ts","sourceRoot":"","sources":["../../../src/example/examples/mandelbrot2.tsx"],"names":[],"mappings":"AA4HA,wBAAgB,qBAAqB,4CAiGpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webgpu.d.ts","sourceRoot":"","sources":["../../../src/example/examples/webgpu.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"webgpu.d.ts","sourceRoot":"","sources":["../../../src/example/examples/webgpu.tsx"],"names":[],"mappings":"AAmDA,wBAAgB,UAAU,4CAgHzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frontend.d.ts","sourceRoot":"","sources":["../../src/example/frontend.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"frontend.d.ts","sourceRoot":"","sources":["../../src/example/frontend.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,aAAa,CAAA;AA0BpB,wBAAgB,GAAG,4CAyClB"}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import type { Vec2, Vec3, Vec4, Vec4Array } from "../types";
|
|
1
|
+
import type { FrameInfo, Vec2, Vec3, Vec4, Vec4Array } from "../types";
|
|
2
2
|
type GpuUniformValue = number | Vec2 | Vec3 | Vec4 | Vec4Array;
|
|
3
3
|
interface UseWebGPUOptions {
|
|
4
4
|
fragment: string;
|
|
5
5
|
uniforms?: Record<string, GpuUniformValue>;
|
|
6
6
|
onError?: (error: Error) => void;
|
|
7
|
+
timeScale?: number;
|
|
8
|
+
onFrame?: (info: FrameInfo) => void;
|
|
9
|
+
onClick?: (info: FrameInfo) => void;
|
|
10
|
+
onMouseMove?: (info: FrameInfo) => void;
|
|
11
|
+
onMouseDown?: (info: FrameInfo) => void;
|
|
12
|
+
onMouseUp?: (info: FrameInfo) => void;
|
|
13
|
+
onMouseWheel?: (info: FrameInfo, wheelDelta: number) => void;
|
|
7
14
|
}
|
|
8
15
|
export declare function useWebGPU(options: UseWebGPUOptions): {
|
|
9
16
|
canvasRef: import("react").RefObject<HTMLCanvasElement>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useWebGPU.d.ts","sourceRoot":"","sources":["../../src/hooks/useWebGPU.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"useWebGPU.d.ts","sourceRoot":"","sources":["../../src/hooks/useWebGPU.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAGtE,KAAK,eAAe,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAA;AAE9D,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IAC1C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAChC,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;IACrC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;CAC7D;AAmXD,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB;;;EAgRlD"}
|
package/dist/index.cjs
CHANGED
|
@@ -275,10 +275,10 @@ function inferWgslType(value) {
|
|
|
275
275
|
}
|
|
276
276
|
if (isVec4Array(value)) {
|
|
277
277
|
return {
|
|
278
|
-
wgslType: `array<vec4f,
|
|
278
|
+
wgslType: `array<vec4f, 100>`,
|
|
279
279
|
baseType: "vec4f",
|
|
280
280
|
isArray: true,
|
|
281
|
-
arrayLength:
|
|
281
|
+
arrayLength: 100
|
|
282
282
|
};
|
|
283
283
|
}
|
|
284
284
|
if (isVec4(value)) {
|
|
@@ -455,6 +455,9 @@ async function initializeWebGPU(canvas, fragmentSource, customUniforms) {
|
|
|
455
455
|
throw new Error("Failed to get WebGPU adapter");
|
|
456
456
|
}
|
|
457
457
|
const device = await adapter.requestDevice();
|
|
458
|
+
device.lost.then((info) => {
|
|
459
|
+
console.error(`WebGPU device lost: ${info.message}`);
|
|
460
|
+
});
|
|
458
461
|
const context = canvas.getContext("webgpu");
|
|
459
462
|
if (!context) {
|
|
460
463
|
throw new Error("Failed to get WebGPU context");
|
|
@@ -537,10 +540,32 @@ function useWebGPU(options) {
|
|
|
537
540
|
const mouseLeftDownRef = import_react2.useRef(false);
|
|
538
541
|
const canvasRectRef = import_react2.useRef(null);
|
|
539
542
|
const onErrorRef = import_react2.useRef(options.onError);
|
|
543
|
+
const onFrameRef = import_react2.useRef(options.onFrame);
|
|
544
|
+
const onClickRef = import_react2.useRef(options.onClick);
|
|
545
|
+
const onMouseDownRef = import_react2.useRef(options.onMouseDown);
|
|
546
|
+
const onMouseUpRef = import_react2.useRef(options.onMouseUp);
|
|
547
|
+
const onMouseMoveRef = import_react2.useRef(options.onMouseMove);
|
|
548
|
+
const onMouseWheelRef = import_react2.useRef(options.onMouseWheel);
|
|
549
|
+
const timeScaleRef = import_react2.useRef(options.timeScale ?? 1);
|
|
540
550
|
const fragmentRef = import_react2.useRef(options.fragment);
|
|
541
551
|
const uniformsRef = import_react2.useRef(options.uniforms);
|
|
542
552
|
const dprRef = import_react2.useRef(window.devicePixelRatio || 1);
|
|
553
|
+
const frameInfoRef = import_react2.useRef({
|
|
554
|
+
deltaTime: 0,
|
|
555
|
+
time: 0,
|
|
556
|
+
resolution: [0, 0],
|
|
557
|
+
mouse: [0, 0],
|
|
558
|
+
mouseNormalized: [0, 0],
|
|
559
|
+
mouseLeftDown: false
|
|
560
|
+
});
|
|
543
561
|
onErrorRef.current = options.onError;
|
|
562
|
+
onFrameRef.current = options.onFrame;
|
|
563
|
+
onClickRef.current = options.onClick;
|
|
564
|
+
onMouseDownRef.current = options.onMouseDown;
|
|
565
|
+
onMouseUpRef.current = options.onMouseUp;
|
|
566
|
+
onMouseMoveRef.current = options.onMouseMove;
|
|
567
|
+
onMouseWheelRef.current = options.onMouseWheel;
|
|
568
|
+
timeScaleRef.current = options.timeScale ?? 1;
|
|
544
569
|
fragmentRef.current = options.fragment;
|
|
545
570
|
uniformsRef.current = options.uniforms;
|
|
546
571
|
const render = import_react2.useCallback((time) => {
|
|
@@ -551,7 +576,18 @@ function useWebGPU(options) {
|
|
|
551
576
|
}
|
|
552
577
|
const deltaTime = lastFrameTimeRef.current === 0 ? 0 : (time - lastFrameTimeRef.current) / 1000;
|
|
553
578
|
lastFrameTimeRef.current = time;
|
|
554
|
-
elapsedTimeRef.current += deltaTime;
|
|
579
|
+
elapsedTimeRef.current += deltaTime * timeScaleRef.current;
|
|
580
|
+
frameInfoRef.current = {
|
|
581
|
+
deltaTime,
|
|
582
|
+
time: elapsedTimeRef.current,
|
|
583
|
+
resolution: [canvas.width, canvas.height],
|
|
584
|
+
mouse: mouseRef.current,
|
|
585
|
+
mouseNormalized: mouseNormalizedRef.current,
|
|
586
|
+
mouseLeftDown: mouseLeftDownRef.current
|
|
587
|
+
};
|
|
588
|
+
if (onFrameRef.current) {
|
|
589
|
+
onFrameRef.current(frameInfoRef.current);
|
|
590
|
+
}
|
|
555
591
|
const { device, context, pipeline, uniformBuffer, uniformBindGroup, uniformLayout } = state;
|
|
556
592
|
const dpr = dprRef.current;
|
|
557
593
|
const displayWidth = canvas.clientWidth;
|
|
@@ -676,26 +712,39 @@ function useWebGPU(options) {
|
|
|
676
712
|
(mouseRef.current[0] - canvas.width / 2) / minDimension,
|
|
677
713
|
(mouseRef.current[1] - canvas.height / 2) / minDimension
|
|
678
714
|
];
|
|
715
|
+
onMouseMoveRef.current?.(frameInfoRef.current);
|
|
679
716
|
};
|
|
680
717
|
const handleMouseDown = (event) => {
|
|
681
718
|
if (event.button === 0) {
|
|
682
719
|
mouseLeftDownRef.current = true;
|
|
683
720
|
}
|
|
721
|
+
onMouseDownRef.current?.(frameInfoRef.current);
|
|
684
722
|
};
|
|
685
723
|
const handleMouseUp = (event) => {
|
|
686
724
|
if (event.button === 0) {
|
|
687
725
|
mouseLeftDownRef.current = false;
|
|
688
726
|
}
|
|
727
|
+
onMouseUpRef.current?.(frameInfoRef.current);
|
|
728
|
+
};
|
|
729
|
+
const handleClick = () => {
|
|
730
|
+
onClickRef.current?.(frameInfoRef.current);
|
|
731
|
+
};
|
|
732
|
+
const handleMouseWheel = (event) => {
|
|
733
|
+
onMouseWheelRef.current?.(frameInfoRef.current, event.deltaY);
|
|
689
734
|
};
|
|
690
735
|
window.addEventListener("mousemove", handleMouseMove);
|
|
691
736
|
window.addEventListener("mousedown", handleMouseDown);
|
|
692
737
|
window.addEventListener("mouseup", handleMouseUp);
|
|
738
|
+
canvas.addEventListener("click", handleClick);
|
|
739
|
+
window.addEventListener("wheel", handleMouseWheel);
|
|
693
740
|
return () => {
|
|
694
741
|
resizeObserver.disconnect();
|
|
695
742
|
window.removeEventListener("scroll", updateRect);
|
|
696
743
|
window.removeEventListener("mousemove", handleMouseMove);
|
|
697
744
|
window.removeEventListener("mousedown", handleMouseDown);
|
|
698
745
|
window.removeEventListener("mouseup", handleMouseUp);
|
|
746
|
+
canvas.removeEventListener("click", handleClick);
|
|
747
|
+
window.removeEventListener("wheel", handleMouseWheel);
|
|
699
748
|
};
|
|
700
749
|
}, []);
|
|
701
750
|
return { canvasRef, mouseRef };
|
|
@@ -721,7 +770,19 @@ var CANVAS_STYLE = {
|
|
|
721
770
|
width: "100%",
|
|
722
771
|
height: "100%"
|
|
723
772
|
};
|
|
724
|
-
function ReactGpuShader({
|
|
773
|
+
function ReactGpuShader({
|
|
774
|
+
className,
|
|
775
|
+
fragment,
|
|
776
|
+
uniforms,
|
|
777
|
+
fullscreen = false,
|
|
778
|
+
timeScale,
|
|
779
|
+
onFrame,
|
|
780
|
+
onClick,
|
|
781
|
+
onMouseMove,
|
|
782
|
+
onMouseDown,
|
|
783
|
+
onMouseUp,
|
|
784
|
+
onMouseWheel
|
|
785
|
+
}) {
|
|
725
786
|
const [error, setError] = import_react3.useState(null);
|
|
726
787
|
const handleError = import_react3.useCallback((err) => {
|
|
727
788
|
setError(err.message);
|
|
@@ -733,7 +794,14 @@ function ReactGpuShader({ className, fragment, uniforms, fullscreen = false }) {
|
|
|
733
794
|
const { canvasRef } = useWebGPU({
|
|
734
795
|
fragment,
|
|
735
796
|
uniforms,
|
|
736
|
-
onError: handleError
|
|
797
|
+
onError: handleError,
|
|
798
|
+
timeScale,
|
|
799
|
+
onFrame,
|
|
800
|
+
onClick,
|
|
801
|
+
onMouseMove,
|
|
802
|
+
onMouseDown,
|
|
803
|
+
onMouseUp,
|
|
804
|
+
onMouseWheel
|
|
737
805
|
});
|
|
738
806
|
const containerStyle = import_react3.useMemo(() => fullscreen ? FULLSCREEN_CONTAINER_STYLE : DEFAULT_CONTAINER_STYLE, [fullscreen]);
|
|
739
807
|
if (error) {
|
package/dist/index.js
CHANGED
|
@@ -229,10 +229,10 @@ function inferWgslType(value) {
|
|
|
229
229
|
}
|
|
230
230
|
if (isVec4Array(value)) {
|
|
231
231
|
return {
|
|
232
|
-
wgslType: `array<vec4f,
|
|
232
|
+
wgslType: `array<vec4f, 100>`,
|
|
233
233
|
baseType: "vec4f",
|
|
234
234
|
isArray: true,
|
|
235
|
-
arrayLength:
|
|
235
|
+
arrayLength: 100
|
|
236
236
|
};
|
|
237
237
|
}
|
|
238
238
|
if (isVec4(value)) {
|
|
@@ -409,6 +409,9 @@ async function initializeWebGPU(canvas, fragmentSource, customUniforms) {
|
|
|
409
409
|
throw new Error("Failed to get WebGPU adapter");
|
|
410
410
|
}
|
|
411
411
|
const device = await adapter.requestDevice();
|
|
412
|
+
device.lost.then((info) => {
|
|
413
|
+
console.error(`WebGPU device lost: ${info.message}`);
|
|
414
|
+
});
|
|
412
415
|
const context = canvas.getContext("webgpu");
|
|
413
416
|
if (!context) {
|
|
414
417
|
throw new Error("Failed to get WebGPU context");
|
|
@@ -491,10 +494,32 @@ function useWebGPU(options) {
|
|
|
491
494
|
const mouseLeftDownRef = useRef2(false);
|
|
492
495
|
const canvasRectRef = useRef2(null);
|
|
493
496
|
const onErrorRef = useRef2(options.onError);
|
|
497
|
+
const onFrameRef = useRef2(options.onFrame);
|
|
498
|
+
const onClickRef = useRef2(options.onClick);
|
|
499
|
+
const onMouseDownRef = useRef2(options.onMouseDown);
|
|
500
|
+
const onMouseUpRef = useRef2(options.onMouseUp);
|
|
501
|
+
const onMouseMoveRef = useRef2(options.onMouseMove);
|
|
502
|
+
const onMouseWheelRef = useRef2(options.onMouseWheel);
|
|
503
|
+
const timeScaleRef = useRef2(options.timeScale ?? 1);
|
|
494
504
|
const fragmentRef = useRef2(options.fragment);
|
|
495
505
|
const uniformsRef = useRef2(options.uniforms);
|
|
496
506
|
const dprRef = useRef2(window.devicePixelRatio || 1);
|
|
507
|
+
const frameInfoRef = useRef2({
|
|
508
|
+
deltaTime: 0,
|
|
509
|
+
time: 0,
|
|
510
|
+
resolution: [0, 0],
|
|
511
|
+
mouse: [0, 0],
|
|
512
|
+
mouseNormalized: [0, 0],
|
|
513
|
+
mouseLeftDown: false
|
|
514
|
+
});
|
|
497
515
|
onErrorRef.current = options.onError;
|
|
516
|
+
onFrameRef.current = options.onFrame;
|
|
517
|
+
onClickRef.current = options.onClick;
|
|
518
|
+
onMouseDownRef.current = options.onMouseDown;
|
|
519
|
+
onMouseUpRef.current = options.onMouseUp;
|
|
520
|
+
onMouseMoveRef.current = options.onMouseMove;
|
|
521
|
+
onMouseWheelRef.current = options.onMouseWheel;
|
|
522
|
+
timeScaleRef.current = options.timeScale ?? 1;
|
|
498
523
|
fragmentRef.current = options.fragment;
|
|
499
524
|
uniformsRef.current = options.uniforms;
|
|
500
525
|
const render = useCallback2((time) => {
|
|
@@ -505,7 +530,18 @@ function useWebGPU(options) {
|
|
|
505
530
|
}
|
|
506
531
|
const deltaTime = lastFrameTimeRef.current === 0 ? 0 : (time - lastFrameTimeRef.current) / 1000;
|
|
507
532
|
lastFrameTimeRef.current = time;
|
|
508
|
-
elapsedTimeRef.current += deltaTime;
|
|
533
|
+
elapsedTimeRef.current += deltaTime * timeScaleRef.current;
|
|
534
|
+
frameInfoRef.current = {
|
|
535
|
+
deltaTime,
|
|
536
|
+
time: elapsedTimeRef.current,
|
|
537
|
+
resolution: [canvas.width, canvas.height],
|
|
538
|
+
mouse: mouseRef.current,
|
|
539
|
+
mouseNormalized: mouseNormalizedRef.current,
|
|
540
|
+
mouseLeftDown: mouseLeftDownRef.current
|
|
541
|
+
};
|
|
542
|
+
if (onFrameRef.current) {
|
|
543
|
+
onFrameRef.current(frameInfoRef.current);
|
|
544
|
+
}
|
|
509
545
|
const { device, context, pipeline, uniformBuffer, uniformBindGroup, uniformLayout } = state;
|
|
510
546
|
const dpr = dprRef.current;
|
|
511
547
|
const displayWidth = canvas.clientWidth;
|
|
@@ -630,26 +666,39 @@ function useWebGPU(options) {
|
|
|
630
666
|
(mouseRef.current[0] - canvas.width / 2) / minDimension,
|
|
631
667
|
(mouseRef.current[1] - canvas.height / 2) / minDimension
|
|
632
668
|
];
|
|
669
|
+
onMouseMoveRef.current?.(frameInfoRef.current);
|
|
633
670
|
};
|
|
634
671
|
const handleMouseDown = (event) => {
|
|
635
672
|
if (event.button === 0) {
|
|
636
673
|
mouseLeftDownRef.current = true;
|
|
637
674
|
}
|
|
675
|
+
onMouseDownRef.current?.(frameInfoRef.current);
|
|
638
676
|
};
|
|
639
677
|
const handleMouseUp = (event) => {
|
|
640
678
|
if (event.button === 0) {
|
|
641
679
|
mouseLeftDownRef.current = false;
|
|
642
680
|
}
|
|
681
|
+
onMouseUpRef.current?.(frameInfoRef.current);
|
|
682
|
+
};
|
|
683
|
+
const handleClick = () => {
|
|
684
|
+
onClickRef.current?.(frameInfoRef.current);
|
|
685
|
+
};
|
|
686
|
+
const handleMouseWheel = (event) => {
|
|
687
|
+
onMouseWheelRef.current?.(frameInfoRef.current, event.deltaY);
|
|
643
688
|
};
|
|
644
689
|
window.addEventListener("mousemove", handleMouseMove);
|
|
645
690
|
window.addEventListener("mousedown", handleMouseDown);
|
|
646
691
|
window.addEventListener("mouseup", handleMouseUp);
|
|
692
|
+
canvas.addEventListener("click", handleClick);
|
|
693
|
+
window.addEventListener("wheel", handleMouseWheel);
|
|
647
694
|
return () => {
|
|
648
695
|
resizeObserver.disconnect();
|
|
649
696
|
window.removeEventListener("scroll", updateRect);
|
|
650
697
|
window.removeEventListener("mousemove", handleMouseMove);
|
|
651
698
|
window.removeEventListener("mousedown", handleMouseDown);
|
|
652
699
|
window.removeEventListener("mouseup", handleMouseUp);
|
|
700
|
+
canvas.removeEventListener("click", handleClick);
|
|
701
|
+
window.removeEventListener("wheel", handleMouseWheel);
|
|
653
702
|
};
|
|
654
703
|
}, []);
|
|
655
704
|
return { canvasRef, mouseRef };
|
|
@@ -675,7 +724,19 @@ var CANVAS_STYLE = {
|
|
|
675
724
|
width: "100%",
|
|
676
725
|
height: "100%"
|
|
677
726
|
};
|
|
678
|
-
function ReactGpuShader({
|
|
727
|
+
function ReactGpuShader({
|
|
728
|
+
className,
|
|
729
|
+
fragment,
|
|
730
|
+
uniforms,
|
|
731
|
+
fullscreen = false,
|
|
732
|
+
timeScale,
|
|
733
|
+
onFrame,
|
|
734
|
+
onClick,
|
|
735
|
+
onMouseMove,
|
|
736
|
+
onMouseDown,
|
|
737
|
+
onMouseUp,
|
|
738
|
+
onMouseWheel
|
|
739
|
+
}) {
|
|
679
740
|
const [error, setError] = useState2(null);
|
|
680
741
|
const handleError = useCallback3((err) => {
|
|
681
742
|
setError(err.message);
|
|
@@ -687,7 +748,14 @@ function ReactGpuShader({ className, fragment, uniforms, fullscreen = false }) {
|
|
|
687
748
|
const { canvasRef } = useWebGPU({
|
|
688
749
|
fragment,
|
|
689
750
|
uniforms,
|
|
690
|
-
onError: handleError
|
|
751
|
+
onError: handleError,
|
|
752
|
+
timeScale,
|
|
753
|
+
onFrame,
|
|
754
|
+
onClick,
|
|
755
|
+
onMouseMove,
|
|
756
|
+
onMouseDown,
|
|
757
|
+
onMouseUp,
|
|
758
|
+
onMouseWheel
|
|
691
759
|
});
|
|
692
760
|
const containerStyle = useMemo(() => fullscreen ? FULLSCREEN_CONTAINER_STYLE : DEFAULT_CONTAINER_STYLE, [fullscreen]);
|
|
693
761
|
if (error) {
|