@fjandin/react-shader 0.0.9 → 0.0.10
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 +0 -1
- package/dist/hooks/useWebGL.d.ts.map +1 -1
- package/dist/index.cjs +44 -38
- package/dist/index.js +45 -39
- 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
|
@@ -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,MAAM,CAAA;CACnB;AAqED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe;;;EAmQhD"}
|
package/dist/index.cjs
CHANGED
|
@@ -273,6 +273,14 @@ function useWebGL(options) {
|
|
|
273
273
|
const timeScaleRef = import_react.useRef(options.timeScale ?? 1);
|
|
274
274
|
const vertexRef = import_react.useRef(options.vertex);
|
|
275
275
|
const fragmentRef = import_react.useRef(options.fragment);
|
|
276
|
+
const dprRef = import_react.useRef(window.devicePixelRatio || 1);
|
|
277
|
+
const defaultUniformsRef = import_react.useRef({
|
|
278
|
+
iTime: 0,
|
|
279
|
+
iMouse: [0, 0],
|
|
280
|
+
iMouseNormalized: [0, 0],
|
|
281
|
+
iMouseLeftDown: 0,
|
|
282
|
+
iResolution: [0, 0]
|
|
283
|
+
});
|
|
276
284
|
uniformsRef.current = options.uniforms;
|
|
277
285
|
onErrorRef.current = options.onError;
|
|
278
286
|
onFrameRef.current = options.onFrame;
|
|
@@ -290,10 +298,9 @@ function useWebGL(options) {
|
|
|
290
298
|
return;
|
|
291
299
|
const deltaTime = lastFrameTimeRef.current === 0 ? 0 : (time - lastFrameTimeRef.current) / 1000;
|
|
292
300
|
lastFrameTimeRef.current = time;
|
|
293
|
-
elapsedTimeRef.current += deltaTime * timeScaleRef.current;
|
|
294
301
|
const { gl, program, positionAttributeLocation, uniformLocationCache } = state;
|
|
295
302
|
const elapsedTime = elapsedTimeRef.current;
|
|
296
|
-
const dpr =
|
|
303
|
+
const dpr = dprRef.current;
|
|
297
304
|
const displayWidth = canvas.clientWidth;
|
|
298
305
|
const displayHeight = canvas.clientHeight;
|
|
299
306
|
if (displayWidth === 0 || displayHeight === 0) {
|
|
@@ -313,22 +320,13 @@ function useWebGL(options) {
|
|
|
313
320
|
gl.enableVertexAttribArray(positionAttributeLocation);
|
|
314
321
|
gl.bindBuffer(gl.ARRAY_BUFFER, state.positionBuffer);
|
|
315
322
|
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
|
-
}
|
|
323
|
+
const defaultUniforms = defaultUniformsRef.current;
|
|
324
|
+
defaultUniforms.iTime = elapsedTime;
|
|
325
|
+
defaultUniforms.iMouse = mouseRef.current;
|
|
326
|
+
defaultUniforms.iMouseNormalized = mouseNormalizedRef.current;
|
|
327
|
+
defaultUniforms.iMouseLeftDown = mouseLeftDownRef.current ? 1 : 0;
|
|
328
|
+
defaultUniforms.iResolution = [canvas.width, canvas.height];
|
|
329
|
+
setUniforms(gl, program, { ...defaultUniforms, ...uniformsRef.current }, uniformLocationCache);
|
|
332
330
|
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
333
331
|
if (onFrameRef.current) {
|
|
334
332
|
onFrameRef.current({
|
|
@@ -371,10 +369,16 @@ function useWebGL(options) {
|
|
|
371
369
|
const handleContextRestored = () => {
|
|
372
370
|
initialize();
|
|
373
371
|
};
|
|
372
|
+
const dprMediaQuery = window.matchMedia(`(resolution: ${dprRef.current}dppx)`);
|
|
373
|
+
const handleDprChange = () => {
|
|
374
|
+
dprRef.current = window.devicePixelRatio || 1;
|
|
375
|
+
};
|
|
376
|
+
dprMediaQuery.addEventListener("change", handleDprChange);
|
|
374
377
|
canvas.addEventListener("webglcontextlost", handleContextLost);
|
|
375
378
|
canvas.addEventListener("webglcontextrestored", handleContextRestored);
|
|
376
379
|
initialize();
|
|
377
380
|
return () => {
|
|
381
|
+
dprMediaQuery.removeEventListener("change", handleDprChange);
|
|
378
382
|
canvas.removeEventListener("webglcontextlost", handleContextLost);
|
|
379
383
|
canvas.removeEventListener("webglcontextrestored", handleContextRestored);
|
|
380
384
|
cancelAnimationFrame(animationFrameRef.current);
|
|
@@ -399,7 +403,7 @@ function useWebGL(options) {
|
|
|
399
403
|
const rect = canvasRectRef.current;
|
|
400
404
|
if (!rect)
|
|
401
405
|
return;
|
|
402
|
-
const dpr =
|
|
406
|
+
const dpr = dprRef.current;
|
|
403
407
|
const x = (event.clientX - rect.left) * dpr;
|
|
404
408
|
const y = (rect.height - (event.clientY - rect.top)) * dpr;
|
|
405
409
|
mouseRef.current = [x, y];
|
|
@@ -464,6 +468,24 @@ void main() {
|
|
|
464
468
|
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
465
469
|
}
|
|
466
470
|
`;
|
|
471
|
+
var FULLSCREEN_CONTAINER_STYLE = {
|
|
472
|
+
position: "fixed",
|
|
473
|
+
top: 0,
|
|
474
|
+
left: 0,
|
|
475
|
+
width: "100vw",
|
|
476
|
+
height: "100vh",
|
|
477
|
+
zIndex: 9000
|
|
478
|
+
};
|
|
479
|
+
var DEFAULT_CONTAINER_STYLE = {
|
|
480
|
+
position: "relative",
|
|
481
|
+
width: "100%",
|
|
482
|
+
height: "100%"
|
|
483
|
+
};
|
|
484
|
+
var CANVAS_STYLE = {
|
|
485
|
+
display: "block",
|
|
486
|
+
width: "100%",
|
|
487
|
+
height: "100%"
|
|
488
|
+
};
|
|
467
489
|
function ReactShader({
|
|
468
490
|
className,
|
|
469
491
|
fragment,
|
|
@@ -480,11 +502,6 @@ function ReactShader({
|
|
|
480
502
|
setError(err.message);
|
|
481
503
|
console.error("ReactShader error:", err);
|
|
482
504
|
}, []);
|
|
483
|
-
const handleFrame = import_react2.useCallback((info) => {
|
|
484
|
-
if (onFrame) {
|
|
485
|
-
onFrame(info);
|
|
486
|
-
}
|
|
487
|
-
}, [onFrame]);
|
|
488
505
|
import_react2.useEffect(() => {
|
|
489
506
|
setError(null);
|
|
490
507
|
}, [fragment, vertex]);
|
|
@@ -493,23 +510,12 @@ function ReactShader({
|
|
|
493
510
|
vertex,
|
|
494
511
|
uniforms,
|
|
495
512
|
onError: handleError,
|
|
496
|
-
onFrame
|
|
513
|
+
onFrame,
|
|
497
514
|
onClick,
|
|
498
515
|
onMouseMove,
|
|
499
516
|
timeScale
|
|
500
517
|
});
|
|
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
|
-
};
|
|
518
|
+
const containerStyle = import_react2.useMemo(() => fullscreen ? FULLSCREEN_CONTAINER_STYLE : DEFAULT_CONTAINER_STYLE, [fullscreen]);
|
|
513
519
|
if (error) {
|
|
514
520
|
return /* @__PURE__ */ jsx_dev_runtime.jsxDEV("div", {
|
|
515
521
|
className,
|
|
@@ -537,7 +543,7 @@ function ReactShader({
|
|
|
537
543
|
return /* @__PURE__ */ jsx_dev_runtime.jsxDEV("canvas", {
|
|
538
544
|
ref: canvasRef,
|
|
539
545
|
className,
|
|
540
|
-
style:
|
|
546
|
+
style: CANVAS_STYLE
|
|
541
547
|
}, undefined, false, undefined, this);
|
|
542
548
|
}
|
|
543
549
|
// 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";
|
|
@@ -233,6 +233,14 @@ function useWebGL(options) {
|
|
|
233
233
|
const timeScaleRef = useRef(options.timeScale ?? 1);
|
|
234
234
|
const vertexRef = useRef(options.vertex);
|
|
235
235
|
const fragmentRef = useRef(options.fragment);
|
|
236
|
+
const dprRef = useRef(window.devicePixelRatio || 1);
|
|
237
|
+
const defaultUniformsRef = useRef({
|
|
238
|
+
iTime: 0,
|
|
239
|
+
iMouse: [0, 0],
|
|
240
|
+
iMouseNormalized: [0, 0],
|
|
241
|
+
iMouseLeftDown: 0,
|
|
242
|
+
iResolution: [0, 0]
|
|
243
|
+
});
|
|
236
244
|
uniformsRef.current = options.uniforms;
|
|
237
245
|
onErrorRef.current = options.onError;
|
|
238
246
|
onFrameRef.current = options.onFrame;
|
|
@@ -250,10 +258,9 @@ function useWebGL(options) {
|
|
|
250
258
|
return;
|
|
251
259
|
const deltaTime = lastFrameTimeRef.current === 0 ? 0 : (time - lastFrameTimeRef.current) / 1000;
|
|
252
260
|
lastFrameTimeRef.current = time;
|
|
253
|
-
elapsedTimeRef.current += deltaTime * timeScaleRef.current;
|
|
254
261
|
const { gl, program, positionAttributeLocation, uniformLocationCache } = state;
|
|
255
262
|
const elapsedTime = elapsedTimeRef.current;
|
|
256
|
-
const dpr =
|
|
263
|
+
const dpr = dprRef.current;
|
|
257
264
|
const displayWidth = canvas.clientWidth;
|
|
258
265
|
const displayHeight = canvas.clientHeight;
|
|
259
266
|
if (displayWidth === 0 || displayHeight === 0) {
|
|
@@ -273,22 +280,13 @@ function useWebGL(options) {
|
|
|
273
280
|
gl.enableVertexAttribArray(positionAttributeLocation);
|
|
274
281
|
gl.bindBuffer(gl.ARRAY_BUFFER, state.positionBuffer);
|
|
275
282
|
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
|
-
}
|
|
283
|
+
const defaultUniforms = defaultUniformsRef.current;
|
|
284
|
+
defaultUniforms.iTime = elapsedTime;
|
|
285
|
+
defaultUniforms.iMouse = mouseRef.current;
|
|
286
|
+
defaultUniforms.iMouseNormalized = mouseNormalizedRef.current;
|
|
287
|
+
defaultUniforms.iMouseLeftDown = mouseLeftDownRef.current ? 1 : 0;
|
|
288
|
+
defaultUniforms.iResolution = [canvas.width, canvas.height];
|
|
289
|
+
setUniforms(gl, program, { ...defaultUniforms, ...uniformsRef.current }, uniformLocationCache);
|
|
292
290
|
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
293
291
|
if (onFrameRef.current) {
|
|
294
292
|
onFrameRef.current({
|
|
@@ -331,10 +329,16 @@ function useWebGL(options) {
|
|
|
331
329
|
const handleContextRestored = () => {
|
|
332
330
|
initialize();
|
|
333
331
|
};
|
|
332
|
+
const dprMediaQuery = window.matchMedia(`(resolution: ${dprRef.current}dppx)`);
|
|
333
|
+
const handleDprChange = () => {
|
|
334
|
+
dprRef.current = window.devicePixelRatio || 1;
|
|
335
|
+
};
|
|
336
|
+
dprMediaQuery.addEventListener("change", handleDprChange);
|
|
334
337
|
canvas.addEventListener("webglcontextlost", handleContextLost);
|
|
335
338
|
canvas.addEventListener("webglcontextrestored", handleContextRestored);
|
|
336
339
|
initialize();
|
|
337
340
|
return () => {
|
|
341
|
+
dprMediaQuery.removeEventListener("change", handleDprChange);
|
|
338
342
|
canvas.removeEventListener("webglcontextlost", handleContextLost);
|
|
339
343
|
canvas.removeEventListener("webglcontextrestored", handleContextRestored);
|
|
340
344
|
cancelAnimationFrame(animationFrameRef.current);
|
|
@@ -359,7 +363,7 @@ function useWebGL(options) {
|
|
|
359
363
|
const rect = canvasRectRef.current;
|
|
360
364
|
if (!rect)
|
|
361
365
|
return;
|
|
362
|
-
const dpr =
|
|
366
|
+
const dpr = dprRef.current;
|
|
363
367
|
const x = (event.clientX - rect.left) * dpr;
|
|
364
368
|
const y = (rect.height - (event.clientY - rect.top)) * dpr;
|
|
365
369
|
mouseRef.current = [x, y];
|
|
@@ -424,6 +428,24 @@ void main() {
|
|
|
424
428
|
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
425
429
|
}
|
|
426
430
|
`;
|
|
431
|
+
var FULLSCREEN_CONTAINER_STYLE = {
|
|
432
|
+
position: "fixed",
|
|
433
|
+
top: 0,
|
|
434
|
+
left: 0,
|
|
435
|
+
width: "100vw",
|
|
436
|
+
height: "100vh",
|
|
437
|
+
zIndex: 9000
|
|
438
|
+
};
|
|
439
|
+
var DEFAULT_CONTAINER_STYLE = {
|
|
440
|
+
position: "relative",
|
|
441
|
+
width: "100%",
|
|
442
|
+
height: "100%"
|
|
443
|
+
};
|
|
444
|
+
var CANVAS_STYLE = {
|
|
445
|
+
display: "block",
|
|
446
|
+
width: "100%",
|
|
447
|
+
height: "100%"
|
|
448
|
+
};
|
|
427
449
|
function ReactShader({
|
|
428
450
|
className,
|
|
429
451
|
fragment,
|
|
@@ -440,11 +462,6 @@ function ReactShader({
|
|
|
440
462
|
setError(err.message);
|
|
441
463
|
console.error("ReactShader error:", err);
|
|
442
464
|
}, []);
|
|
443
|
-
const handleFrame = useCallback2((info) => {
|
|
444
|
-
if (onFrame) {
|
|
445
|
-
onFrame(info);
|
|
446
|
-
}
|
|
447
|
-
}, [onFrame]);
|
|
448
465
|
useEffect2(() => {
|
|
449
466
|
setError(null);
|
|
450
467
|
}, [fragment, vertex]);
|
|
@@ -453,23 +470,12 @@ function ReactShader({
|
|
|
453
470
|
vertex,
|
|
454
471
|
uniforms,
|
|
455
472
|
onError: handleError,
|
|
456
|
-
onFrame
|
|
473
|
+
onFrame,
|
|
457
474
|
onClick,
|
|
458
475
|
onMouseMove,
|
|
459
476
|
timeScale
|
|
460
477
|
});
|
|
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
|
-
};
|
|
478
|
+
const containerStyle = useMemo(() => fullscreen ? FULLSCREEN_CONTAINER_STYLE : DEFAULT_CONTAINER_STYLE, [fullscreen]);
|
|
473
479
|
if (error) {
|
|
474
480
|
return /* @__PURE__ */ jsxDEV("div", {
|
|
475
481
|
className,
|
|
@@ -497,7 +503,7 @@ function ReactShader({
|
|
|
497
503
|
return /* @__PURE__ */ jsxDEV("canvas", {
|
|
498
504
|
ref: canvasRef,
|
|
499
505
|
className,
|
|
500
|
-
style:
|
|
506
|
+
style: CANVAS_STYLE
|
|
501
507
|
}, undefined, false, undefined, this);
|
|
502
508
|
}
|
|
503
509
|
// src/shaders/color-palette.ts
|