@cruxgarden/plasma-ui 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +104 -0
- package/README.md +82 -7
- package/dist/Plasma.d.ts +31 -6
- package/dist/PlasmaProvider.d.ts +77 -12
- package/dist/index.d.ts +12 -3
- package/dist/index.js +325 -155
- package/dist/renderer.d.ts +30 -2
- package/package.json +7 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/PlasmaProvider.tsx
|
|
2
|
-
import { createContext, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
|
|
4
4
|
// src/shaders.ts
|
|
5
5
|
var DEFAULT_MAX_SHAPES = 16;
|
|
@@ -178,7 +178,7 @@ void main(){
|
|
|
178
178
|
const compFrag = `#version 300 es
|
|
179
179
|
${common}
|
|
180
180
|
uniform sampler2D uH, uS, uTint, uBg, uBgM, uBgH, uFrost;
|
|
181
|
-
uniform float uRefract, uDisp, uRim, uRimMode, uRimWidth, uSpec, uHair;
|
|
181
|
+
uniform float uRefract, uDisp, uRim, uRimMode, uRimWidth, uSpec, uHair, uShim, uGlow, uWash, uGrain;
|
|
182
182
|
uniform vec3 uRimColor;
|
|
183
183
|
out vec4 o;
|
|
184
184
|
|
|
@@ -235,7 +235,7 @@ void main(){
|
|
|
235
235
|
// Palette phases run on viewport position, like the grain: a frame drawn for
|
|
236
236
|
// a taller region must colour its viewport band exactly as the live frame does.
|
|
237
237
|
vec2 vp = p - uView.xy;
|
|
238
|
-
col += pal(uTime*.03 + vp.x/1400.) * .06 * smoothstep(.0, .45, hHere) * (1.+uEnergy);
|
|
238
|
+
col += pal(uTime*.03 + vp.x/1400.) * .06 * smoothstep(.0, .45, hHere) * (1.+uEnergy) * uGlow;
|
|
239
239
|
|
|
240
240
|
if(sd > -2.){
|
|
241
241
|
vec2 th = 2. / vec2(textureSize(uH, 0));
|
|
@@ -255,7 +255,12 @@ void main(){
|
|
|
255
255
|
seen(p + off, fr).g,
|
|
256
256
|
seen(p + off*(1.-disp), fr).b
|
|
257
257
|
);
|
|
258
|
+
// uWash 0 hands the background through untouched - glass with no cast of
|
|
259
|
+
// its own. 1 is the original desaturate-and-lift that gives the material
|
|
260
|
+
// its body.
|
|
261
|
+
vec3 clearRefr = refr;
|
|
258
262
|
refr = mix(refr, vec3(dot(refr, vec3(.333))), .18) * mix(1.08, .9, uLight) + .03*(1.-uLight);
|
|
263
|
+
refr = mix(clearRefr, refr, uWash);
|
|
259
264
|
// frosted: milkier and a little brighter
|
|
260
265
|
refr = mix(refr, mix(refr, vec3(dot(refr, vec3(.333))), .25) * mix(1.12, .97, uLight) + mix(.05, .03, uLight), fr);
|
|
261
266
|
float hl = 1. - .55*uLight;
|
|
@@ -280,7 +285,7 @@ void main(){
|
|
|
280
285
|
plasma += rimCol * fres * .45 * hl * uRim;
|
|
281
286
|
plasma += vec3(1.) * spec * .75 * hl * uSpec;
|
|
282
287
|
// faint shimmer across the body; fades out as the tint becomes opaque
|
|
283
|
-
plasma += pal(uTime*.04 + vp.y/900. + uEnergy*.3) * .05 * lift * (1.+uEnergy*2.) * hl * (1. - talpha);
|
|
288
|
+
plasma += pal(uTime*.04 + vp.y/900. + uEnergy*.3) * .05 * lift * (1.+uEnergy*2.) * hl * (1. - talpha) * uShim;
|
|
284
289
|
vec3 hairCol = uRimMode > .5 ? mix(vec3(1.), rimCol / 1.4, .6) : vec3(.9,.95,1.);
|
|
285
290
|
plasma += hairCol * (1.-smoothstep(0., 1.6, abs(sd - .7))) * .4 * hl * uHair;
|
|
286
291
|
|
|
@@ -290,7 +295,7 @@ void main(){
|
|
|
290
295
|
}
|
|
291
296
|
// Keyed on viewport position, so a frame drawn for a taller region has the
|
|
292
297
|
// same grain in its viewport band as the live frame that replaces it.
|
|
293
|
-
col += (hash(p - uView.xy + uTime) - .5) * .025 * grain;
|
|
298
|
+
col += (hash(p - uView.xy + uTime) - .5) * .025 * grain * uGrain;
|
|
294
299
|
o = vec4(col, 1.);
|
|
295
300
|
}`;
|
|
296
301
|
return { maskFrag, tintFrag, blurFrag, bgFrag, compFrag };
|
|
@@ -361,7 +366,11 @@ var UNIFORMS = [
|
|
|
361
366
|
"uRimColor",
|
|
362
367
|
"uRimWidth",
|
|
363
368
|
"uSpec",
|
|
364
|
-
"uHair"
|
|
369
|
+
"uHair",
|
|
370
|
+
"uShim",
|
|
371
|
+
"uGlow",
|
|
372
|
+
"uWash",
|
|
373
|
+
"uGrain"
|
|
365
374
|
];
|
|
366
375
|
var MASK_SCALE = 0.5;
|
|
367
376
|
var MAX_PIXELS = 26e5;
|
|
@@ -423,6 +432,13 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
423
432
|
this.floatOK = false;
|
|
424
433
|
/** True between webglcontextlost and webglcontextrestored: draw nothing. */
|
|
425
434
|
this.lost = false;
|
|
435
|
+
this.warnedOverflow = false;
|
|
436
|
+
/**
|
|
437
|
+
* Set by destroy(). The canvas and its context outlive this renderer, so an
|
|
438
|
+
* async callback that lands afterwards would happily allocate on a context
|
|
439
|
+
* nothing can free it from.
|
|
440
|
+
*/
|
|
441
|
+
this.destroyed = false;
|
|
426
442
|
/** Everything initGL() created, so destroy() can free it by hand. */
|
|
427
443
|
this.owned = { tex: [], fb: [], prog: [], buf: [] };
|
|
428
444
|
this.recs = /* @__PURE__ */ new Map();
|
|
@@ -471,8 +487,13 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
471
487
|
this.onContextRestored = () => {
|
|
472
488
|
this.lost = false;
|
|
473
489
|
this.initGL();
|
|
474
|
-
this.applyResize();
|
|
475
490
|
this.last = 0;
|
|
491
|
+
if (this.frozen) {
|
|
492
|
+
clearTimeout(this.scrollIdle);
|
|
493
|
+
this.thaw();
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
this.applyResize();
|
|
476
497
|
if (!document.hidden && !this.raf) this.raf = requestAnimationFrame(this.frame);
|
|
477
498
|
};
|
|
478
499
|
/**
|
|
@@ -704,6 +725,10 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
704
725
|
r.drawn = { l, t, w: rgt - l, h: btm - t };
|
|
705
726
|
});
|
|
706
727
|
this.drawnScroll = [scrollX, scrollY];
|
|
728
|
+
if (list.length > this.max && !this.warnedOverflow) {
|
|
729
|
+
this.warnedOverflow = true;
|
|
730
|
+
console.warn(`[plasma-ui] ${list.length} plasma surfaces are on screen but maxSurfaces is ${this.max}; the rest are not drawn. Raise maxSurfaces on <PlasmaProvider>.`);
|
|
731
|
+
}
|
|
707
732
|
this.lastList = list.slice(0, this.max);
|
|
708
733
|
this.draw(this.lastList);
|
|
709
734
|
};
|
|
@@ -714,13 +739,7 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
714
739
|
this.gl = gl;
|
|
715
740
|
this.settings = settings;
|
|
716
741
|
this.max = Math.max(1, Math.round(settings.maxSurfaces || DEFAULT_MAX_SHAPES));
|
|
717
|
-
this.
|
|
718
|
-
this.R = new Float32Array(this.max * 4);
|
|
719
|
-
this.F = new Float32Array(this.max);
|
|
720
|
-
this.T = new Float32Array(this.max * 4);
|
|
721
|
-
this.FR = new Float32Array(this.max);
|
|
722
|
-
this.EL = new Float32Array(this.max);
|
|
723
|
-
this.SOLO = new Float32Array(this.max);
|
|
742
|
+
this.allocUniformArrays();
|
|
724
743
|
this.initGL();
|
|
725
744
|
this.mouse.x = this.mouse.tx = innerWidth / 2;
|
|
726
745
|
this.mouse.y = this.mouse.ty = innerHeight / 2;
|
|
@@ -771,7 +790,7 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
771
790
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
772
791
|
this.imgTex = tex;
|
|
773
792
|
const up = (source, w, h) => {
|
|
774
|
-
if (!w || !h) return;
|
|
793
|
+
if (this.destroyed || !w || !h) return;
|
|
775
794
|
gl.bindTexture(gl.TEXTURE_2D, this.imgTex);
|
|
776
795
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
|
|
777
796
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, gl.RGBA, gl.UNSIGNED_BYTE, source);
|
|
@@ -786,7 +805,7 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
786
805
|
const img2 = src;
|
|
787
806
|
if (img2.complete && img2.naturalWidth) up(img2, img2.naturalWidth, img2.naturalHeight);
|
|
788
807
|
else img2.addEventListener("load", () => {
|
|
789
|
-
if (this.imgSrc === src) up(img2, img2.naturalWidth, img2.naturalHeight);
|
|
808
|
+
if (!this.destroyed && this.imgSrc === src) up(img2, img2.naturalWidth, img2.naturalHeight);
|
|
790
809
|
}, { once: true });
|
|
791
810
|
}
|
|
792
811
|
return;
|
|
@@ -800,7 +819,7 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
800
819
|
const img = new Image();
|
|
801
820
|
img.crossOrigin = "anonymous";
|
|
802
821
|
img.onload = () => {
|
|
803
|
-
if (this.imgSrc !== src) return;
|
|
822
|
+
if (this.destroyed || this.imgSrc !== src) return;
|
|
804
823
|
const tex = gl.createTexture();
|
|
805
824
|
gl.bindTexture(gl.TEXTURE_2D, tex);
|
|
806
825
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
|
|
@@ -818,7 +837,12 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
818
837
|
}
|
|
819
838
|
configure(s, immediate = false) {
|
|
820
839
|
const qualityChanged = s.quality !== this.settings.quality;
|
|
840
|
+
const max = Math.max(1, Math.round(s.maxSurfaces || DEFAULT_MAX_SHAPES));
|
|
821
841
|
this.settings = s;
|
|
842
|
+
if (max !== this.max) {
|
|
843
|
+
this.setMax(max);
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
822
846
|
this.loadBackground(s.background ?? null);
|
|
823
847
|
this.colorTarget = s.colors.map(hexToRgb);
|
|
824
848
|
if (immediate) {
|
|
@@ -872,12 +896,17 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
872
896
|
}
|
|
873
897
|
};
|
|
874
898
|
}
|
|
875
|
-
/**
|
|
876
|
-
|
|
899
|
+
/**
|
|
900
|
+
* Layout boxes of all shapes (lean removed; animating draggables report
|
|
901
|
+
* their destination). Pass `group` to see only the surfaces in that group;
|
|
902
|
+
* omit it - as any caller written before groups existed does - to see them all.
|
|
903
|
+
*/
|
|
904
|
+
layoutBoxes(excludeId, fusingOnly = false, group) {
|
|
877
905
|
const out = [];
|
|
878
906
|
this.recs.forEach((r) => {
|
|
879
907
|
if (r.id === excludeId) return;
|
|
880
908
|
if (fusingOnly && r.fuse === false) return;
|
|
909
|
+
if (group !== void 0 && (r.group ?? null) !== group) return;
|
|
881
910
|
out.push(this.layoutBoxOf(r));
|
|
882
911
|
});
|
|
883
912
|
return out;
|
|
@@ -903,6 +932,39 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
903
932
|
bump(e) {
|
|
904
933
|
this.energy = Math.max(this.energy, Math.min(e, 1));
|
|
905
934
|
}
|
|
935
|
+
/** Rebuild the shaders and uniform arrays for a new surface budget. */
|
|
936
|
+
setMax(max) {
|
|
937
|
+
this.max = max;
|
|
938
|
+
this.allocUniformArrays();
|
|
939
|
+
this.releaseGL();
|
|
940
|
+
this.initGL();
|
|
941
|
+
this.applyResize();
|
|
942
|
+
this.warnedOverflow = false;
|
|
943
|
+
}
|
|
944
|
+
allocUniformArrays() {
|
|
945
|
+
this.P = new Float32Array(this.max * 4);
|
|
946
|
+
this.R = new Float32Array(this.max * 4);
|
|
947
|
+
this.F = new Float32Array(this.max);
|
|
948
|
+
this.T = new Float32Array(this.max * 4);
|
|
949
|
+
this.FR = new Float32Array(this.max);
|
|
950
|
+
this.EL = new Float32Array(this.max);
|
|
951
|
+
this.SOLO = new Float32Array(this.max);
|
|
952
|
+
}
|
|
953
|
+
/** Delete every GL object this renderer created, leaving the canvas usable. */
|
|
954
|
+
releaseGL() {
|
|
955
|
+
const gl = this.gl;
|
|
956
|
+
if (!gl.isContextLost()) {
|
|
957
|
+
this.owned.tex.forEach((t) => gl.deleteTexture(t));
|
|
958
|
+
this.owned.fb.forEach((f) => gl.deleteFramebuffer(f));
|
|
959
|
+
this.owned.prog.forEach((pr) => gl.deleteProgram(pr));
|
|
960
|
+
this.owned.buf.forEach((b) => gl.deleteBuffer(b));
|
|
961
|
+
if (this.imgTex) gl.deleteTexture(this.imgTex);
|
|
962
|
+
}
|
|
963
|
+
this.imgTex = null;
|
|
964
|
+
this.imgSrc = null;
|
|
965
|
+
this.srcEl = null;
|
|
966
|
+
this.owned = { tex: [], fb: [], prog: [], buf: [] };
|
|
967
|
+
}
|
|
906
968
|
/**
|
|
907
969
|
* Every GL object this renderer owns. A lost context invalidates all of
|
|
908
970
|
* them, so creation lives here rather than in the constructor: the restore
|
|
@@ -911,6 +973,9 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
911
973
|
initGL() {
|
|
912
974
|
const gl = this.gl;
|
|
913
975
|
this.owned = { tex: [], fb: [], prog: [], buf: [] };
|
|
976
|
+
this.imgTex = null;
|
|
977
|
+
this.imgSrc = null;
|
|
978
|
+
this.srcEl = null;
|
|
914
979
|
this.floatOK = !!gl.getExtension("EXT_color_buffer_float");
|
|
915
980
|
const sh = makeShaders(this.max);
|
|
916
981
|
this.progs = { bg: this.program(sh.bgFrag), mask: this.program(sh.maskFrag), tint: this.program(sh.tintFrag), blur: this.program(sh.blurFrag), comp: this.program(sh.compFrag) };
|
|
@@ -934,6 +999,7 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
934
999
|
this.canvas.width = this.canvas.height = 0;
|
|
935
1000
|
}
|
|
936
1001
|
destroy() {
|
|
1002
|
+
this.destroyed = true;
|
|
937
1003
|
cancelAnimationFrame(this.raf);
|
|
938
1004
|
clearTimeout(this.resizeSettle);
|
|
939
1005
|
this.canvas.removeEventListener("webglcontextlost", this.onContextLost);
|
|
@@ -949,14 +1015,7 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
949
1015
|
r.el.style.scale = "";
|
|
950
1016
|
});
|
|
951
1017
|
this.recs.clear();
|
|
952
|
-
|
|
953
|
-
if (!gl.isContextLost()) {
|
|
954
|
-
this.owned.tex.forEach((t) => gl.deleteTexture(t));
|
|
955
|
-
this.owned.fb.forEach((f) => gl.deleteFramebuffer(f));
|
|
956
|
-
this.owned.prog.forEach((pr) => gl.deleteProgram(pr));
|
|
957
|
-
this.owned.buf.forEach((b) => gl.deleteBuffer(b));
|
|
958
|
-
}
|
|
959
|
-
this.owned = { tex: [], fb: [], prog: [], buf: [] };
|
|
1018
|
+
this.releaseGL();
|
|
960
1019
|
}
|
|
961
1020
|
freeze() {
|
|
962
1021
|
const c = this.canvas;
|
|
@@ -1074,6 +1133,18 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
1074
1133
|
gl.useProgram(bl.pr);
|
|
1075
1134
|
gl.uniform1i(bl.u.uTex, 0);
|
|
1076
1135
|
gl.activeTexture(gl.TEXTURE0);
|
|
1136
|
+
const bgBlur = Math.min(40, Math.max(0, s.backgroundBlur || 0));
|
|
1137
|
+
if (bgBlur > 0) {
|
|
1138
|
+
const step = bgBlur * this.dpr * MASK_SCALE / 4;
|
|
1139
|
+
pass(this.rtBg, this.rtBgM, 0, 0);
|
|
1140
|
+
for (let i = 0; i < 3; i++) {
|
|
1141
|
+
pass(this.rtBgM, this.rtB, step, 0);
|
|
1142
|
+
pass(this.rtB, this.rtBgM, 0, step);
|
|
1143
|
+
}
|
|
1144
|
+
gl.viewport(0, 0, this.rtBg.w, this.rtBg.h);
|
|
1145
|
+
pass(this.rtBgM, this.rtBg, 0, 0);
|
|
1146
|
+
gl.viewport(0, 0, this.rtA.w, this.rtA.h);
|
|
1147
|
+
}
|
|
1077
1148
|
const n = list.length;
|
|
1078
1149
|
let hasFrost = false, hasTint = false, hasElev = false;
|
|
1079
1150
|
for (let i = 0; i < n; i++) {
|
|
@@ -1140,6 +1211,10 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
1140
1211
|
gl.uniform1f(c.u.uRimWidth, s.rimWidth);
|
|
1141
1212
|
gl.uniform1f(c.u.uSpec, s.highlight);
|
|
1142
1213
|
gl.uniform1f(c.u.uHair, s.edgeLine);
|
|
1214
|
+
gl.uniform1f(c.u.uShim, s.shimmer);
|
|
1215
|
+
gl.uniform1f(c.u.uGlow, s.glow);
|
|
1216
|
+
gl.uniform1f(c.u.uWash, s.wash);
|
|
1217
|
+
gl.uniform1f(c.u.uGrain, s.grain);
|
|
1143
1218
|
gl.activeTexture(gl.TEXTURE0);
|
|
1144
1219
|
gl.bindTexture(gl.TEXTURE_2D, this.rtC.tex);
|
|
1145
1220
|
gl.activeTexture(gl.TEXTURE1);
|
|
@@ -1186,15 +1261,40 @@ var _PlasmaRenderer = class _PlasmaRenderer {
|
|
|
1186
1261
|
const sh = gl.createShader(type);
|
|
1187
1262
|
gl.shaderSource(sh, src);
|
|
1188
1263
|
gl.compileShader(sh);
|
|
1189
|
-
if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS))
|
|
1264
|
+
if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS)) {
|
|
1265
|
+
const log = gl.getShaderInfoLog(sh);
|
|
1266
|
+
gl.deleteShader(sh);
|
|
1267
|
+
throw new Error(log || "shader compile failed");
|
|
1268
|
+
}
|
|
1190
1269
|
return sh;
|
|
1191
1270
|
};
|
|
1192
1271
|
const pr = gl.createProgram();
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1272
|
+
const attached = [];
|
|
1273
|
+
try {
|
|
1274
|
+
const vs = compile(gl.VERTEX_SHADER, vert);
|
|
1275
|
+
let fs;
|
|
1276
|
+
try {
|
|
1277
|
+
fs = compile(gl.FRAGMENT_SHADER, fsrc);
|
|
1278
|
+
} catch (e) {
|
|
1279
|
+
gl.deleteShader(vs);
|
|
1280
|
+
throw e;
|
|
1281
|
+
}
|
|
1282
|
+
gl.attachShader(pr, vs);
|
|
1283
|
+
attached.push(vs);
|
|
1284
|
+
gl.attachShader(pr, fs);
|
|
1285
|
+
attached.push(fs);
|
|
1286
|
+
gl.bindAttribLocation(pr, 0, "p");
|
|
1287
|
+
gl.linkProgram(pr);
|
|
1288
|
+
if (!gl.getProgramParameter(pr, gl.LINK_STATUS)) throw new Error(gl.getProgramInfoLog(pr) || "program link failed");
|
|
1289
|
+
} catch (e) {
|
|
1290
|
+
gl.deleteProgram(pr);
|
|
1291
|
+
throw e;
|
|
1292
|
+
} finally {
|
|
1293
|
+
attached.forEach((sh) => {
|
|
1294
|
+
gl.detachShader(pr, sh);
|
|
1295
|
+
gl.deleteShader(sh);
|
|
1296
|
+
});
|
|
1297
|
+
}
|
|
1198
1298
|
const u = {};
|
|
1199
1299
|
UNIFORMS.forEach((n) => {
|
|
1200
1300
|
u[n] = gl.getUniformLocation(pr, n);
|
|
@@ -1223,21 +1323,35 @@ var PlasmaRenderer = _PlasmaRenderer;
|
|
|
1223
1323
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1224
1324
|
var noop = () => {
|
|
1225
1325
|
};
|
|
1226
|
-
var
|
|
1227
|
-
|
|
1326
|
+
var DEFAULT_RUNTIME = { renderer: null, supported: false, reducedMotion: false, pulse: noop, bump: noop };
|
|
1327
|
+
var DEFAULT_DEFAULTS = {
|
|
1228
1328
|
tint: "#ffffff",
|
|
1229
1329
|
opacity: 0,
|
|
1230
1330
|
frost: 0,
|
|
1231
1331
|
radius: 26,
|
|
1232
|
-
supported: false,
|
|
1233
1332
|
grid: 24,
|
|
1234
1333
|
magnet: 40,
|
|
1235
|
-
spring: { stiffness: 170, damping: 16 }
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
var
|
|
1334
|
+
spring: { stiffness: 170, damping: 16 }
|
|
1335
|
+
};
|
|
1336
|
+
var RuntimeContext = createContext(DEFAULT_RUNTIME);
|
|
1337
|
+
var DefaultsContext = createContext(DEFAULT_DEFAULTS);
|
|
1338
|
+
var AttachContext = createContext(null);
|
|
1339
|
+
var usePlasmaRuntime = () => useContext(RuntimeContext);
|
|
1340
|
+
var usePlasmaDefaults = () => useContext(DefaultsContext);
|
|
1341
|
+
function usePlasma() {
|
|
1342
|
+
const runtime = usePlasmaRuntime();
|
|
1343
|
+
const defaults = usePlasmaDefaults();
|
|
1344
|
+
return useMemo(() => ({ ...runtime, ...defaults }), [runtime, defaults]);
|
|
1345
|
+
}
|
|
1346
|
+
var DEV = typeof process !== "undefined" && true;
|
|
1347
|
+
var useIsoLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
1348
|
+
function useLatest(value) {
|
|
1349
|
+
const ref = useRef(value);
|
|
1350
|
+
useIsoLayoutEffect(() => {
|
|
1351
|
+
ref.current = value;
|
|
1352
|
+
});
|
|
1353
|
+
return ref;
|
|
1354
|
+
}
|
|
1241
1355
|
var FALLBACK_CSS = `
|
|
1242
1356
|
.plasma-panel{box-sizing:border-box}
|
|
1243
1357
|
.plasma-fallback{
|
|
@@ -1260,6 +1374,31 @@ function useReducedMotion() {
|
|
|
1260
1374
|
}, []);
|
|
1261
1375
|
return reduced;
|
|
1262
1376
|
}
|
|
1377
|
+
function PlasmaCanvas({ className, style, zIndex = -1 }) {
|
|
1378
|
+
const attach = useContext(AttachContext);
|
|
1379
|
+
const { supported } = usePlasmaRuntime();
|
|
1380
|
+
useEffect(() => {
|
|
1381
|
+
if (DEV && !attach) console.warn("[plasma-ui] <PlasmaCanvas> must be rendered inside a <PlasmaProvider>.");
|
|
1382
|
+
}, [attach]);
|
|
1383
|
+
return /* @__PURE__ */ jsx(
|
|
1384
|
+
"canvas",
|
|
1385
|
+
{
|
|
1386
|
+
ref: attach ?? void 0,
|
|
1387
|
+
"aria-hidden": "true",
|
|
1388
|
+
className,
|
|
1389
|
+
style: {
|
|
1390
|
+
position: "fixed",
|
|
1391
|
+
inset: 0,
|
|
1392
|
+
width: "100%",
|
|
1393
|
+
height: "100%",
|
|
1394
|
+
zIndex,
|
|
1395
|
+
pointerEvents: "none",
|
|
1396
|
+
display: supported ? "block" : "none",
|
|
1397
|
+
...style
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
);
|
|
1401
|
+
}
|
|
1263
1402
|
function PlasmaProvider({
|
|
1264
1403
|
children,
|
|
1265
1404
|
mood = "tidal",
|
|
@@ -1282,6 +1421,11 @@ function PlasmaProvider({
|
|
|
1282
1421
|
rimWidth = 1,
|
|
1283
1422
|
highlight = 1,
|
|
1284
1423
|
edgeLine = 1,
|
|
1424
|
+
shimmer = 1,
|
|
1425
|
+
glow = 1,
|
|
1426
|
+
wash = 1,
|
|
1427
|
+
grain = 1,
|
|
1428
|
+
backgroundBlur = 0,
|
|
1285
1429
|
pointerDrop = true,
|
|
1286
1430
|
ambientDrops = false,
|
|
1287
1431
|
grid = 24,
|
|
@@ -1289,9 +1433,10 @@ function PlasmaProvider({
|
|
|
1289
1433
|
quality = 1.25,
|
|
1290
1434
|
maxSurfaces = 16,
|
|
1291
1435
|
zIndex = -1,
|
|
1292
|
-
freezeOnScroll = false
|
|
1436
|
+
freezeOnScroll = false,
|
|
1437
|
+
canvas = true
|
|
1293
1438
|
}) {
|
|
1294
|
-
const
|
|
1439
|
+
const [canvasEl, setCanvasEl] = useState(null);
|
|
1295
1440
|
const [renderer, setRenderer] = useState(null);
|
|
1296
1441
|
const [supported, setSupported] = useState(true);
|
|
1297
1442
|
const reducedMotion = useReducedMotion();
|
|
@@ -1315,6 +1460,11 @@ function PlasmaProvider({
|
|
|
1315
1460
|
rimWidth,
|
|
1316
1461
|
highlight,
|
|
1317
1462
|
edgeLine,
|
|
1463
|
+
shimmer,
|
|
1464
|
+
glow,
|
|
1465
|
+
wash,
|
|
1466
|
+
grain,
|
|
1467
|
+
backgroundBlur,
|
|
1318
1468
|
viscosity,
|
|
1319
1469
|
stretch,
|
|
1320
1470
|
flow,
|
|
@@ -1323,91 +1473,55 @@ function PlasmaProvider({
|
|
|
1323
1473
|
maxSurfaces,
|
|
1324
1474
|
background: background ?? null
|
|
1325
1475
|
};
|
|
1326
|
-
const settingsRef =
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
const r = PlasmaRenderer.create(
|
|
1476
|
+
const settingsRef = useLatest(settings);
|
|
1477
|
+
useIsoLayoutEffect(() => {
|
|
1478
|
+
if (!canvasEl) return;
|
|
1479
|
+
const r = PlasmaRenderer.create(canvasEl, settingsRef.current);
|
|
1330
1480
|
if (!r) {
|
|
1331
1481
|
setSupported(false);
|
|
1332
1482
|
return;
|
|
1333
1483
|
}
|
|
1484
|
+
setSupported(true);
|
|
1334
1485
|
setRenderer(r);
|
|
1335
1486
|
return () => {
|
|
1336
1487
|
r.destroy();
|
|
1337
1488
|
setRenderer(null);
|
|
1338
1489
|
};
|
|
1339
|
-
}, []);
|
|
1490
|
+
}, [canvasEl]);
|
|
1491
|
+
useEffect(() => {
|
|
1492
|
+
if (!DEV || canvasEl) return;
|
|
1493
|
+
const t = setTimeout(() => console.warn("[plasma-ui] PlasmaProvider has no canvas. Either leave `canvas` on, or render a <PlasmaCanvas /> inside the provider."), 0);
|
|
1494
|
+
return () => clearTimeout(t);
|
|
1495
|
+
}, [canvasEl]);
|
|
1496
|
+
const settingsDeps = Object.values(settings).map((v) => Array.isArray(v) ? v.join() : v);
|
|
1340
1497
|
useEffect(() => {
|
|
1341
1498
|
renderer?.configure(settings);
|
|
1342
|
-
}, [
|
|
1343
|
-
renderer,
|
|
1344
|
-
m.colors.join(),
|
|
1345
|
-
settings.blend,
|
|
1346
|
-
refraction,
|
|
1347
|
-
dispersion,
|
|
1348
|
-
rim,
|
|
1349
|
-
smoothness,
|
|
1350
|
-
settings.pointerDrop,
|
|
1351
|
-
ambientDrops,
|
|
1352
|
-
theme,
|
|
1353
|
-
quality,
|
|
1354
|
-
reducedMotion,
|
|
1355
|
-
freezeOnScroll,
|
|
1356
|
-
tint,
|
|
1357
|
-
opacity,
|
|
1358
|
-
rimColor,
|
|
1359
|
-
rimWidth,
|
|
1360
|
-
highlight,
|
|
1361
|
-
edgeLine,
|
|
1362
|
-
viscosity,
|
|
1363
|
-
stretch,
|
|
1364
|
-
flow,
|
|
1365
|
-
frost,
|
|
1366
|
-
elevation,
|
|
1367
|
-
background
|
|
1368
|
-
]);
|
|
1499
|
+
}, [renderer, ...settingsDeps]);
|
|
1369
1500
|
const vis = Math.min(Math.max(viscosity, 0), 1);
|
|
1370
1501
|
const stiffK = vis < 0.5 ? 1.6 - 1.2 * vis : 1 - 1.1 * (vis - 0.5);
|
|
1371
1502
|
const dampK = vis < 0.5 ? 0.6 + 0.8 * vis : 1 + 1.6 * (vis - 0.5);
|
|
1372
|
-
const
|
|
1373
|
-
const
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
supported,
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
spring,
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
}), [renderer, tint, opacity, frost, radius, supported, grid, magnet, spring.stiffness, spring.damping, reducedMotion]);
|
|
1387
|
-
return /* @__PURE__ */ jsxs(PlasmaContext.Provider, { value, children: [
|
|
1503
|
+
const stiffness = m.spring.stiffness * stiffK;
|
|
1504
|
+
const damping = m.spring.damping * dampK * Math.sqrt(stiffK);
|
|
1505
|
+
const rendererRef = useLatest(renderer);
|
|
1506
|
+
const pulse = useCallback((x, y, s) => rendererRef.current?.pulse(x, y, s), []);
|
|
1507
|
+
const bump = useCallback((e) => rendererRef.current?.bump(e), []);
|
|
1508
|
+
const runtime = useMemo(
|
|
1509
|
+
() => ({ renderer, supported, reducedMotion, pulse, bump }),
|
|
1510
|
+
[renderer, supported, reducedMotion, pulse, bump]
|
|
1511
|
+
);
|
|
1512
|
+
const defaults = useMemo(
|
|
1513
|
+
() => ({ tint, opacity, frost, radius, grid, magnet, spring: { stiffness, damping } }),
|
|
1514
|
+
[tint, opacity, frost, radius, grid, magnet, stiffness, damping]
|
|
1515
|
+
);
|
|
1516
|
+
return /* @__PURE__ */ jsx(RuntimeContext.Provider, { value: runtime, children: /* @__PURE__ */ jsx(DefaultsContext.Provider, { value: defaults, children: /* @__PURE__ */ jsxs(AttachContext.Provider, { value: setCanvasEl, children: [
|
|
1388
1517
|
/* @__PURE__ */ jsx("style", { children: FALLBACK_CSS }),
|
|
1389
|
-
/* @__PURE__ */ jsx(
|
|
1390
|
-
"canvas",
|
|
1391
|
-
{
|
|
1392
|
-
ref: canvasRef,
|
|
1393
|
-
"aria-hidden": "true",
|
|
1394
|
-
style: {
|
|
1395
|
-
position: "fixed",
|
|
1396
|
-
inset: 0,
|
|
1397
|
-
width: "100%",
|
|
1398
|
-
height: "100%",
|
|
1399
|
-
zIndex,
|
|
1400
|
-
pointerEvents: "none",
|
|
1401
|
-
display: supported ? "block" : "none"
|
|
1402
|
-
}
|
|
1403
|
-
}
|
|
1404
|
-
),
|
|
1518
|
+
canvas && /* @__PURE__ */ jsx(PlasmaCanvas, { zIndex }),
|
|
1405
1519
|
children
|
|
1406
|
-
] });
|
|
1520
|
+
] }) }) });
|
|
1407
1521
|
}
|
|
1408
1522
|
|
|
1409
1523
|
// src/Plasma.tsx
|
|
1410
|
-
import { forwardRef, useCallback
|
|
1524
|
+
import { forwardRef, useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2, useSyncExternalStore } from "react";
|
|
1411
1525
|
|
|
1412
1526
|
// src/spring.ts
|
|
1413
1527
|
var now = () => typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
@@ -1518,6 +1632,25 @@ function boxGap(a, b) {
|
|
|
1518
1632
|
// src/Plasma.tsx
|
|
1519
1633
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
1520
1634
|
var NO_DRAG = "button,a,input,textarea,select,label,[contenteditable],[data-plasma-nodrag]";
|
|
1635
|
+
var NO_SIDES = { top: false, right: false, bottom: false, left: false };
|
|
1636
|
+
var noSides = () => NO_SIDES;
|
|
1637
|
+
function createSidesStore() {
|
|
1638
|
+
let value = NO_SIDES;
|
|
1639
|
+
const subs = /* @__PURE__ */ new Set();
|
|
1640
|
+
return {
|
|
1641
|
+
subscribe(fn) {
|
|
1642
|
+
subs.add(fn);
|
|
1643
|
+
return () => {
|
|
1644
|
+
subs.delete(fn);
|
|
1645
|
+
};
|
|
1646
|
+
},
|
|
1647
|
+
get: () => value,
|
|
1648
|
+
set(next) {
|
|
1649
|
+
value = next;
|
|
1650
|
+
subs.forEach((fn) => fn());
|
|
1651
|
+
}
|
|
1652
|
+
};
|
|
1653
|
+
}
|
|
1521
1654
|
function fallbackTint(hex, a) {
|
|
1522
1655
|
if (!(a > 0) || !/^#([0-9a-f]{6})$/i.test(hex)) return null;
|
|
1523
1656
|
const n = parseInt(hex.slice(1), 16);
|
|
@@ -1527,7 +1660,12 @@ function assignRef(ref, v) {
|
|
|
1527
1660
|
if (typeof ref === "function") ref(v);
|
|
1528
1661
|
else if (ref) ref.current = v;
|
|
1529
1662
|
}
|
|
1530
|
-
|
|
1663
|
+
function useConst(make) {
|
|
1664
|
+
const ref = useRef2(null);
|
|
1665
|
+
if (ref.current === null) ref.current = make();
|
|
1666
|
+
return ref.current;
|
|
1667
|
+
}
|
|
1668
|
+
var PlasmaInner = forwardRef(function Plasma({
|
|
1531
1669
|
as: Comp = "div",
|
|
1532
1670
|
radius,
|
|
1533
1671
|
lean = 10,
|
|
@@ -1539,6 +1677,7 @@ var Plasma = forwardRef(function Plasma2({
|
|
|
1539
1677
|
padding,
|
|
1540
1678
|
draggable = false,
|
|
1541
1679
|
snap = true,
|
|
1680
|
+
group,
|
|
1542
1681
|
bounds,
|
|
1543
1682
|
offset,
|
|
1544
1683
|
defaultOffset,
|
|
@@ -1553,29 +1692,45 @@ var Plasma = forwardRef(function Plasma2({
|
|
|
1553
1692
|
tabIndex,
|
|
1554
1693
|
...rest
|
|
1555
1694
|
}, ref) {
|
|
1556
|
-
const
|
|
1557
|
-
const
|
|
1695
|
+
const runtime = usePlasmaRuntime();
|
|
1696
|
+
const defaults = usePlasmaDefaults();
|
|
1697
|
+
const r = radius ?? defaults.radius;
|
|
1558
1698
|
const el = useRef2(null);
|
|
1559
1699
|
const handle = useRef2(null);
|
|
1560
|
-
const
|
|
1561
|
-
const
|
|
1700
|
+
const x = useConst(() => springValue(offset?.x ?? defaultOffset?.x ?? 0));
|
|
1701
|
+
const y = useConst(() => springValue(offset?.y ?? defaultOffset?.y ?? 0));
|
|
1562
1702
|
const dest = useRef2({ x: x.get(), y: y.get() });
|
|
1563
1703
|
const anims = useRef2([]);
|
|
1564
1704
|
const [dragging, setDragging] = useState2(false);
|
|
1565
1705
|
const positioned = draggable || !!offset || !!defaultOffset;
|
|
1566
|
-
const joinCb =
|
|
1567
|
-
|
|
1568
|
-
const
|
|
1569
|
-
const
|
|
1570
|
-
|
|
1571
|
-
const
|
|
1706
|
+
const joinCb = useLatest(onJoinChange);
|
|
1707
|
+
const sidesStore = useConst(createSidesStore);
|
|
1708
|
+
const sides = useSyncExternalStore(sidesStore.subscribe, sidesStore.get, noSides);
|
|
1709
|
+
const runtimeRef = useLatest(runtime);
|
|
1710
|
+
const defaultsRef = useLatest(defaults);
|
|
1711
|
+
const boundsRef = useLatest(bounds);
|
|
1712
|
+
const snapRef = useLatest(snap);
|
|
1713
|
+
const onDragEndRef = useLatest(onDragEnd);
|
|
1714
|
+
const onDragStartRef = useLatest(onDragStart);
|
|
1715
|
+
const opts = {
|
|
1716
|
+
radius: r,
|
|
1717
|
+
lean: lean || 0,
|
|
1718
|
+
tint: tint ?? null,
|
|
1719
|
+
opacity: opacity ?? null,
|
|
1720
|
+
frost: frost ?? null,
|
|
1721
|
+
elevation: elevation ?? null,
|
|
1722
|
+
fuse,
|
|
1723
|
+
group: group ?? null
|
|
1724
|
+
};
|
|
1725
|
+
const optsRef = useLatest(opts);
|
|
1726
|
+
const setRef = useCallback2((node) => {
|
|
1572
1727
|
el.current = node;
|
|
1573
1728
|
assignRef(ref, node);
|
|
1574
1729
|
}, [ref]);
|
|
1575
|
-
|
|
1576
|
-
const node = el.current, ren =
|
|
1730
|
+
useIsoLayoutEffect(() => {
|
|
1731
|
+
const node = el.current, ren = runtime.renderer;
|
|
1577
1732
|
if (!node || !ren) return;
|
|
1578
|
-
const h = ren.register(node,
|
|
1733
|
+
const h = ren.register(node, optsRef.current, (j) => joinCb.current?.(j), sidesStore.set);
|
|
1579
1734
|
if (positioned) {
|
|
1580
1735
|
h.setLayoutBox(() => {
|
|
1581
1736
|
const rect = node.getBoundingClientRect();
|
|
@@ -1594,11 +1749,11 @@ var Plasma = forwardRef(function Plasma2({
|
|
|
1594
1749
|
h.remove();
|
|
1595
1750
|
handle.current = null;
|
|
1596
1751
|
};
|
|
1597
|
-
}, [
|
|
1598
|
-
|
|
1599
|
-
handle.current?.update(
|
|
1600
|
-
}, [r, lean, tint, opacity, frost, elevation, fuse]);
|
|
1601
|
-
|
|
1752
|
+
}, [runtime.renderer, positioned]);
|
|
1753
|
+
useIsoLayoutEffect(() => {
|
|
1754
|
+
handle.current?.update(opts);
|
|
1755
|
+
}, [r, lean, tint, opacity, frost, elevation, fuse, group]);
|
|
1756
|
+
useIsoLayoutEffect(() => {
|
|
1602
1757
|
const node = el.current;
|
|
1603
1758
|
if (!node || !positioned) return;
|
|
1604
1759
|
const apply = () => {
|
|
@@ -1611,18 +1766,18 @@ var Plasma = forwardRef(function Plasma2({
|
|
|
1611
1766
|
b();
|
|
1612
1767
|
};
|
|
1613
1768
|
}, [positioned]);
|
|
1614
|
-
const springTo =
|
|
1769
|
+
const springTo = useCallback2((tx, ty, vx = 0, vy = 0) => {
|
|
1615
1770
|
dest.current = { x: tx, y: ty };
|
|
1616
1771
|
anims.current.forEach((a) => a.stop());
|
|
1617
|
-
const { spring
|
|
1618
|
-
if (reducedMotion) {
|
|
1772
|
+
const { spring } = defaultsRef.current;
|
|
1773
|
+
if (runtimeRef.current.reducedMotion) {
|
|
1619
1774
|
x.set(tx);
|
|
1620
1775
|
y.set(ty);
|
|
1621
1776
|
anims.current = [];
|
|
1622
1777
|
return;
|
|
1623
1778
|
}
|
|
1624
|
-
const
|
|
1625
|
-
anims.current = [animateSpring(x, tx, { ...
|
|
1779
|
+
const o = { stiffness: spring.stiffness, damping: spring.damping };
|
|
1780
|
+
anims.current = [animateSpring(x, tx, { ...o, velocity: vx }), animateSpring(y, ty, { ...o, velocity: vy })];
|
|
1626
1781
|
}, []);
|
|
1627
1782
|
useEffect2(() => {
|
|
1628
1783
|
if (!offset) return;
|
|
@@ -1630,15 +1785,26 @@ var Plasma = forwardRef(function Plasma2({
|
|
|
1630
1785
|
springTo(offset.x, offset.y);
|
|
1631
1786
|
}, [offset?.x, offset?.y]);
|
|
1632
1787
|
useEffect2(() => () => anims.current.forEach((a) => a.stop()), []);
|
|
1633
|
-
|
|
1634
|
-
|
|
1788
|
+
useEffect2(() => {
|
|
1789
|
+
if (!DEV) return;
|
|
1790
|
+
if (!runtime.renderer && runtime.supported) {
|
|
1791
|
+
console.warn("[plasma-ui] <Plasma> rendered outside a <PlasmaProvider>: it will draw as the plain CSS fallback.");
|
|
1792
|
+
}
|
|
1793
|
+
const s = style;
|
|
1794
|
+
if (positioned && s && ("transform" in s || "translate" in s || "scale" in s)) {
|
|
1795
|
+
console.warn("[plasma-ui] <Plasma> owns transform, translate and scale on its element. A `style` that sets any of them will fight the drag and lean animations.");
|
|
1796
|
+
}
|
|
1797
|
+
}, [runtime.renderer, runtime.supported, positioned, style]);
|
|
1798
|
+
const boundsBox = useCallback2(() => {
|
|
1799
|
+
const b = boundsRef.current?.current?.getBoundingClientRect();
|
|
1635
1800
|
return b ? { l: b.left, t: b.top, w: b.width, h: b.height } : { l: 0, t: 0, w: innerWidth, h: innerHeight };
|
|
1636
|
-
};
|
|
1637
|
-
const settle = (proposed, vx = 0, vy = 0) => {
|
|
1801
|
+
}, []);
|
|
1802
|
+
const settle = useCallback2((proposed, vx = 0, vy = 0) => {
|
|
1638
1803
|
const node = el.current, h = handle.current;
|
|
1639
|
-
const { grid, magnet
|
|
1804
|
+
const { grid, magnet } = defaultsRef.current;
|
|
1805
|
+
const { renderer } = runtimeRef.current;
|
|
1640
1806
|
let target = proposed;
|
|
1641
|
-
if (
|
|
1807
|
+
if (snapRef.current && h && renderer) {
|
|
1642
1808
|
const rect = node.getBoundingClientRect();
|
|
1643
1809
|
const w = node.offsetWidth, hh = node.offsetHeight;
|
|
1644
1810
|
const lo = h.leanOffset();
|
|
@@ -1646,15 +1812,15 @@ var Plasma = forwardRef(function Plasma2({
|
|
|
1646
1812
|
const baseT = rect.top + (rect.height - hh) / 2 - lo.y - y.get();
|
|
1647
1813
|
const s = snapBox(
|
|
1648
1814
|
{ l: baseL + proposed.x, t: baseT + proposed.y, w, h: hh },
|
|
1649
|
-
renderer.layoutBoxes(h.id, true),
|
|
1650
|
-
{ grid, magnet, bounds: boundsBox(), inset:
|
|
1815
|
+
renderer.layoutBoxes(h.id, true, optsRef.current.group ?? null),
|
|
1816
|
+
{ grid, magnet, bounds: boundsBox(), inset: boundsRef.current ? 0 : 8 }
|
|
1651
1817
|
);
|
|
1652
1818
|
target = { x: s.l - baseL, y: s.t - baseT };
|
|
1653
1819
|
}
|
|
1654
1820
|
springTo(target.x, target.y, vx, vy);
|
|
1655
|
-
|
|
1656
|
-
};
|
|
1657
|
-
const handlePointerDown = (e) => {
|
|
1821
|
+
onDragEndRef.current?.(target);
|
|
1822
|
+
}, []);
|
|
1823
|
+
const handlePointerDown = useCallback2((e) => {
|
|
1658
1824
|
onPointerDown?.(e);
|
|
1659
1825
|
if (!draggable || e.defaultPrevented || e.button !== 0) return;
|
|
1660
1826
|
if (e.target.closest(NO_DRAG)) return;
|
|
@@ -1672,12 +1838,12 @@ var Plasma = forwardRef(function Plasma2({
|
|
|
1672
1838
|
const clamp = (v, a, b) => Math.min(Math.max(v, a), Math.max(a, b));
|
|
1673
1839
|
handle.current?.setDragging(true);
|
|
1674
1840
|
setDragging(true);
|
|
1675
|
-
|
|
1841
|
+
onDragStartRef.current?.();
|
|
1676
1842
|
const move = (ev) => {
|
|
1677
1843
|
x.set(clamp(start.x + ev.clientX - start.px, minX - 40, maxX + 40));
|
|
1678
1844
|
y.set(clamp(start.y + ev.clientY - start.py, minY - 40, maxY + 40));
|
|
1679
1845
|
dest.current = { x: x.get(), y: y.get() };
|
|
1680
|
-
|
|
1846
|
+
runtimeRef.current.bump(Math.hypot(x.getVelocity(), y.getVelocity()) / 1800);
|
|
1681
1847
|
};
|
|
1682
1848
|
const up = () => {
|
|
1683
1849
|
node.removeEventListener("pointermove", move);
|
|
@@ -1691,17 +1857,17 @@ var Plasma = forwardRef(function Plasma2({
|
|
|
1691
1857
|
node.addEventListener("pointermove", move);
|
|
1692
1858
|
node.addEventListener("pointerup", up);
|
|
1693
1859
|
node.addEventListener("pointercancel", up);
|
|
1694
|
-
};
|
|
1695
|
-
const handleKeyDown = (e) => {
|
|
1860
|
+
}, [draggable, onPointerDown]);
|
|
1861
|
+
const handleKeyDown = useCallback2((e) => {
|
|
1696
1862
|
onKeyDown?.(e);
|
|
1697
1863
|
if (!draggable || e.defaultPrevented || e.target !== el.current) return;
|
|
1698
|
-
const step =
|
|
1864
|
+
const step = defaultsRef.current.grid || 24;
|
|
1699
1865
|
const d = { ArrowLeft: [-step, 0], ArrowRight: [step, 0], ArrowUp: [0, -step], ArrowDown: [0, step] }[e.key];
|
|
1700
1866
|
if (!d) return;
|
|
1701
1867
|
e.preventDefault();
|
|
1702
1868
|
settle({ x: dest.current.x + d[0], y: dest.current.y + d[1] });
|
|
1703
|
-
};
|
|
1704
|
-
const classes = ["plasma-panel",
|
|
1869
|
+
}, [draggable, onKeyDown]);
|
|
1870
|
+
const classes = ["plasma-panel", runtime.supported ? "" : "plasma-fallback", className].filter(Boolean).join(" ");
|
|
1705
1871
|
return /* @__PURE__ */ jsx2(
|
|
1706
1872
|
Comp,
|
|
1707
1873
|
{
|
|
@@ -1713,7 +1879,7 @@ var Plasma = forwardRef(function Plasma2({
|
|
|
1713
1879
|
padding: `${sides.top ? padding / 2 : padding}px ${sides.right ? padding / 2 : padding}px ${sides.bottom ? padding / 2 : padding}px ${sides.left ? padding / 2 : padding}px`,
|
|
1714
1880
|
transition: "padding 250ms ease"
|
|
1715
1881
|
},
|
|
1716
|
-
...
|
|
1882
|
+
...runtime.supported ? null : fallbackTint(tint ?? defaults.tint, opacity ?? defaults.opacity),
|
|
1717
1883
|
...style
|
|
1718
1884
|
},
|
|
1719
1885
|
"data-plasma-draggable": draggable || void 0,
|
|
@@ -1726,9 +1892,11 @@ var Plasma = forwardRef(function Plasma2({
|
|
|
1726
1892
|
}
|
|
1727
1893
|
);
|
|
1728
1894
|
});
|
|
1895
|
+
var Plasma2 = PlasmaInner;
|
|
1729
1896
|
export {
|
|
1730
1897
|
DEFAULT_MAX_SHAPES,
|
|
1731
|
-
Plasma,
|
|
1898
|
+
Plasma2 as Plasma,
|
|
1899
|
+
PlasmaCanvas,
|
|
1732
1900
|
PlasmaProvider,
|
|
1733
1901
|
PlasmaRenderer,
|
|
1734
1902
|
boxGap,
|
|
@@ -1736,5 +1904,7 @@ export {
|
|
|
1736
1904
|
moods,
|
|
1737
1905
|
resolveMood,
|
|
1738
1906
|
snapBox,
|
|
1739
|
-
usePlasma
|
|
1907
|
+
usePlasma,
|
|
1908
|
+
usePlasmaDefaults,
|
|
1909
|
+
usePlasmaRuntime
|
|
1740
1910
|
};
|