liquid-gl 2.0.3 → 2.1.1
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 -1
- package/liquidGL.js +364 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<a href="https://liquidgl.naughtyduk.com"><img src="https://raw.githubusercontent.com/naughtyduk/liquidGL/main/assets/liquidGL-npm-preview.gif" alt="liquidGL" width="100%" height="auto"/></a>
|
|
4
4
|
|
|
5
|
-
### v2.
|
|
5
|
+
### v2.1.1
|
|
6
6
|
|
|
7
7
|
> [!NOTE]
|
|
8
8
|
> `liquidGL` is free to use for both non-commercial and commercial purposes.
|
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
|
|
32
32
|
**Features**
|
|
33
33
|
|
|
34
|
+
- **2.1.0 - Helper GUI** — A helper GUI is now available to adjust the liquidGL options in real-time during development, helping you to achieve the perfect aesthetic. To enable it, set `helper: true` in the options object when calling `liquidGL()`.
|
|
35
|
+
|
|
34
36
|
- **Sticky positioning support** — `position: sticky` elements can now be glassified. Sticky lenses are measured every animation frame, so the glass pane tracks the element through its flowing and stuck phases, then releases with it at the end of its containing block — inside nested scroll containers as well as the main document.
|
|
35
37
|
|
|
36
38
|
- **Built-in DOM snapshotter** — the `html2canvas` dependency has been replaced with an integrated rasteriser. Capture no longer depends on a third-party library.
|
|
@@ -227,6 +229,7 @@ Passing `gsap` lets `liquidGL` drive its render loop from the GSAP ticker and ke
|
|
|
227
229
|
| `tiltFactor` | number | `5` | Depth of the tilt in degrees (0–25 recommended). |
|
|
228
230
|
| `tiltEase` | number | `400` | Duration in ms for the tilt to settle, applied symmetrically on hover-in and hover-out. `0` applies the tilt instantly. |
|
|
229
231
|
| `magnify` | number | `1` | Magnification factor of the lens (clamped 0.001–3.0). `1` is no magnification. |
|
|
232
|
+
| `helper` | boolean | `false` | Loads the helper GUI for live tweaking of the liquidGL options. |
|
|
230
233
|
| `on.init` | function | `—` | Callback that runs once the first render completes. Receives the lens instance. |
|
|
231
234
|
|
|
232
235
|
> The `target` parameter is required; all others are optional.
|
package/liquidGL.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Author: NaughtyDuk© – https://liquidgl.naughtyduk.com
|
|
6
6
|
* Licence: MIT
|
|
7
|
-
* Version: v2.0
|
|
7
|
+
* Version: v2.1.0
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
const liquidGL = (() => {
|
|
@@ -2064,6 +2064,8 @@ const liquidGL = (() => {
|
|
|
2064
2064
|
vec2 texel = 1.0 / u_textureResolution;
|
|
2065
2065
|
vec4 refrCol;
|
|
2066
2066
|
|
|
2067
|
+
vec2 chroma = offset * u_aberration;
|
|
2068
|
+
|
|
2067
2069
|
if (u_frost > 0.0) {
|
|
2068
2070
|
float radius = u_frost * 4.0;
|
|
2069
2071
|
vec4 sum = vec4(0.0);
|
|
@@ -2072,8 +2074,15 @@ const liquidGL = (() => {
|
|
|
2072
2074
|
for (int i = 0; i < SAMPLES; i++) {
|
|
2073
2075
|
float angle = random(v_uv + float(i)) * 6.283185;
|
|
2074
2076
|
float dist = sqrt(random(v_uv - float(i))) * radius;
|
|
2075
|
-
vec2
|
|
2076
|
-
|
|
2077
|
+
vec2 foff = vec2(cos(angle), sin(angle)) * texel * dist;
|
|
2078
|
+
if (u_aberration > 0.0) {
|
|
2079
|
+
sum.r += texture2D(u_tex, sampleUV + foff - chroma).r;
|
|
2080
|
+
sum.g += texture2D(u_tex, sampleUV + foff).g;
|
|
2081
|
+
sum.b += texture2D(u_tex, sampleUV + foff + chroma).b;
|
|
2082
|
+
sum.a += texture2D(u_tex, sampleUV + foff).a;
|
|
2083
|
+
} else {
|
|
2084
|
+
sum += texture2D(u_tex, sampleUV + foff);
|
|
2085
|
+
}
|
|
2077
2086
|
}
|
|
2078
2087
|
refrCol = sum / float(SAMPLES);
|
|
2079
2088
|
} else {
|
|
@@ -2083,12 +2092,11 @@ const liquidGL = (() => {
|
|
|
2083
2092
|
refrCol += texture2D(u_tex, sampleUV + vec2(0.0, texel.y));
|
|
2084
2093
|
refrCol += texture2D(u_tex, sampleUV + vec2(0.0, -texel.y));
|
|
2085
2094
|
refrCol /= 5.0;
|
|
2086
|
-
}
|
|
2087
2095
|
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2096
|
+
if (u_aberration > 0.0) {
|
|
2097
|
+
refrCol.r = texture2D(u_tex, sampleUV - chroma).r;
|
|
2098
|
+
refrCol.b = texture2D(u_tex, sampleUV + chroma).b;
|
|
2099
|
+
}
|
|
2092
2100
|
}
|
|
2093
2101
|
|
|
2094
2102
|
if (refrCol.a < 0.1) {
|
|
@@ -4062,6 +4070,342 @@ const liquidGL = (() => {
|
|
|
4062
4070
|
}
|
|
4063
4071
|
}
|
|
4064
4072
|
|
|
4073
|
+
/* --------------------------------------------------
|
|
4074
|
+
* Helper GUI System
|
|
4075
|
+
* ------------------------------------------------*/
|
|
4076
|
+
let helperGUIs = [];
|
|
4077
|
+
let lilGuiLoaded = false;
|
|
4078
|
+
let lilGuiLoadPromise = null;
|
|
4079
|
+
|
|
4080
|
+
function loadLilGui() {
|
|
4081
|
+
if (lilGuiLoaded) {
|
|
4082
|
+
return Promise.resolve();
|
|
4083
|
+
}
|
|
4084
|
+
if (lilGuiLoadPromise) {
|
|
4085
|
+
return lilGuiLoadPromise;
|
|
4086
|
+
}
|
|
4087
|
+
|
|
4088
|
+
lilGuiLoadPromise = new Promise((resolve, reject) => {
|
|
4089
|
+
if (typeof lil !== "undefined") {
|
|
4090
|
+
lilGuiLoaded = true;
|
|
4091
|
+
injectHelperStyles();
|
|
4092
|
+
resolve();
|
|
4093
|
+
return;
|
|
4094
|
+
}
|
|
4095
|
+
|
|
4096
|
+
const script = document.createElement("script");
|
|
4097
|
+
script.src =
|
|
4098
|
+
"https://cdn.jsdelivr.net/npm/lil-gui@0.19.1/dist/lil-gui.umd.min.js";
|
|
4099
|
+
script.integrity =
|
|
4100
|
+
"sha384-2eNPNc7Cms+nVcpmQPotBpthLWCwjAGbkp0Y+3MUQqwPbmTpMFmbh2a230Gkns0x";
|
|
4101
|
+
script.crossOrigin = "anonymous";
|
|
4102
|
+
script.onload = () => {
|
|
4103
|
+
lilGuiLoaded = true;
|
|
4104
|
+
injectHelperStyles();
|
|
4105
|
+
resolve();
|
|
4106
|
+
};
|
|
4107
|
+
script.onerror = () => {
|
|
4108
|
+
reject(new Error("Failed to load lil-gui"));
|
|
4109
|
+
};
|
|
4110
|
+
document.head.appendChild(script);
|
|
4111
|
+
});
|
|
4112
|
+
|
|
4113
|
+
return lilGuiLoadPromise;
|
|
4114
|
+
}
|
|
4115
|
+
|
|
4116
|
+
function injectHelperStyles() {
|
|
4117
|
+
if (document.getElementById("liquidgl-helper-styles")) return;
|
|
4118
|
+
|
|
4119
|
+
const style = document.createElement("style");
|
|
4120
|
+
style.id = "liquidgl-helper-styles";
|
|
4121
|
+
style.textContent = `
|
|
4122
|
+
@media screen and (max-width: 768px) {
|
|
4123
|
+
.lil-gui.root.liquidgl-helper {
|
|
4124
|
+
width: 61vw;
|
|
4125
|
+
}
|
|
4126
|
+
}
|
|
4127
|
+
|
|
4128
|
+
.lil-gui.root.liquidgl-helper,
|
|
4129
|
+
.lil-gui.liquidgl-helper .lil-gui {
|
|
4130
|
+
--background-color: rgb(9 9 11 / 85%);
|
|
4131
|
+
--widget-color: rgb(39 39 42 / 50%);
|
|
4132
|
+
--hover-color: rgb(39 39 42 / 70%);
|
|
4133
|
+
--focus-color: rgb(39 39 42 / 90%);
|
|
4134
|
+
--number-color: #fafafa;
|
|
4135
|
+
--string-color: #fafafa;
|
|
4136
|
+
--font-size: 13px;
|
|
4137
|
+
--input-font-size: 13px;
|
|
4138
|
+
--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
4139
|
+
--font-family-mono: monospace;
|
|
4140
|
+
--padding: 10px;
|
|
4141
|
+
--spacing: 10px;
|
|
4142
|
+
--widget-height: 28px;
|
|
4143
|
+
--title-height: 28px;
|
|
4144
|
+
--name-width: 45%;
|
|
4145
|
+
--slider-knob-width: 4px;
|
|
4146
|
+
--slider-input-width: 27%;
|
|
4147
|
+
--color-input-width: 27%;
|
|
4148
|
+
--slider-input-min-width: 45px;
|
|
4149
|
+
--color-input-min-width: 45px;
|
|
4150
|
+
--folder-indent: 8px;
|
|
4151
|
+
--widget-padding: 0 10px;
|
|
4152
|
+
--widget-border-radius: 4px;
|
|
4153
|
+
--checkbox-size: 16px;
|
|
4154
|
+
--scrollbar-width: 6px;
|
|
4155
|
+
}
|
|
4156
|
+
|
|
4157
|
+
.lil-gui.root.liquidgl-helper {
|
|
4158
|
+
border-radius: 12px !important;
|
|
4159
|
+
border: 0.5px solid #1e1e20 !important;
|
|
4160
|
+
backdrop-filter: blur(16px);
|
|
4161
|
+
box-shadow: 0 4px 16px rgb(0 0 0 / 20%) !important;
|
|
4162
|
+
position: fixed !important;
|
|
4163
|
+
top: 1rem !important;
|
|
4164
|
+
right: 1rem !important;
|
|
4165
|
+
left: auto !important;
|
|
4166
|
+
z-index: 999999999 !important;
|
|
4167
|
+
}
|
|
4168
|
+
|
|
4169
|
+
.lil-gui.liquidgl-helper .title {
|
|
4170
|
+
background: transparent;
|
|
4171
|
+
border-bottom: 0.5px solid #1e1e20;
|
|
4172
|
+
border-radius: 12px 12px 0 0 !important;
|
|
4173
|
+
}
|
|
4174
|
+
|
|
4175
|
+
.lil-gui.liquidgl-helper .title button {
|
|
4176
|
+
padding: 12px 16px !important;
|
|
4177
|
+
}
|
|
4178
|
+
|
|
4179
|
+
.lil-gui.liquidgl-helper.closed .title {
|
|
4180
|
+
border-radius: 12px !important;
|
|
4181
|
+
border-bottom: none;
|
|
4182
|
+
}
|
|
4183
|
+
|
|
4184
|
+
.lil-gui.liquidgl-helper .children {
|
|
4185
|
+
border-top: 0.5px solid #1e1e20;
|
|
4186
|
+
}
|
|
4187
|
+
|
|
4188
|
+
@media (max-width: 768px) {
|
|
4189
|
+
.lil-gui.root.liquidgl-helper {
|
|
4190
|
+
top: 1rem !important;
|
|
4191
|
+
right: 1rem !important;
|
|
4192
|
+
}
|
|
4193
|
+
}
|
|
4194
|
+
`;
|
|
4195
|
+
document.head.appendChild(style);
|
|
4196
|
+
}
|
|
4197
|
+
|
|
4198
|
+
function createHelperGUI(lenses, options, instanceIndex) {
|
|
4199
|
+
if (typeof lil === "undefined") return;
|
|
4200
|
+
|
|
4201
|
+
const lensList = (Array.isArray(lenses) ? lenses : [lenses]).filter(
|
|
4202
|
+
Boolean,
|
|
4203
|
+
);
|
|
4204
|
+
if (!lensList.length) return;
|
|
4205
|
+
|
|
4206
|
+
const gui = new lil.GUI({
|
|
4207
|
+
title: `liquidGL Helper ${instanceIndex + 1}`,
|
|
4208
|
+
closeFolders: true,
|
|
4209
|
+
});
|
|
4210
|
+
gui.domElement.classList.add("liquidgl-helper");
|
|
4211
|
+
gui.$title.style.cursor = "default";
|
|
4212
|
+
|
|
4213
|
+
const topOffset = 1 + instanceIndex * 3;
|
|
4214
|
+
gui.domElement.style.top = `${topOffset}rem`;
|
|
4215
|
+
|
|
4216
|
+
const state = lensList[0].options;
|
|
4217
|
+
|
|
4218
|
+
const applyToLenses = (key, value) => {
|
|
4219
|
+
lensList.forEach((ln) => {
|
|
4220
|
+
if (!ln) return;
|
|
4221
|
+
ln.options[key] = value;
|
|
4222
|
+
if (key === "shadow") ln.setShadow(value);
|
|
4223
|
+
if (key === "tilt") ln.setTilt(value);
|
|
4224
|
+
});
|
|
4225
|
+
};
|
|
4226
|
+
|
|
4227
|
+
const refractionFolder = gui.addFolder("Refraction");
|
|
4228
|
+
refractionFolder
|
|
4229
|
+
.add(state, "refraction", 0, 0.1, 0.001)
|
|
4230
|
+
.name("Refraction")
|
|
4231
|
+
.onChange((v) => applyToLenses("refraction", v));
|
|
4232
|
+
refractionFolder
|
|
4233
|
+
.add(state, "aberration", 0, 1, 0.01)
|
|
4234
|
+
.name("Aberration")
|
|
4235
|
+
.onChange((v) => applyToLenses("aberration", v));
|
|
4236
|
+
refractionFolder
|
|
4237
|
+
.add(state, "bevelDepth", 0, 0.2, 0.001)
|
|
4238
|
+
.name("Bevel Depth")
|
|
4239
|
+
.onChange((v) => applyToLenses("bevelDepth", v));
|
|
4240
|
+
refractionFolder
|
|
4241
|
+
.add(state, "bevelWidth", 0, 0.5, 0.001)
|
|
4242
|
+
.name("Bevel Width")
|
|
4243
|
+
.onChange((v) => applyToLenses("bevelWidth", v));
|
|
4244
|
+
refractionFolder
|
|
4245
|
+
.add(state, "magnify", 1, 5, 0.1)
|
|
4246
|
+
.name("Magnify")
|
|
4247
|
+
.onChange((v) => applyToLenses("magnify", v));
|
|
4248
|
+
|
|
4249
|
+
const surfaceFolder = gui.addFolder("Surface");
|
|
4250
|
+
surfaceFolder
|
|
4251
|
+
.add(state, "frost", 0, 10, 0.1)
|
|
4252
|
+
.name("Frost")
|
|
4253
|
+
.onChange((v) => applyToLenses("frost", v));
|
|
4254
|
+
surfaceFolder
|
|
4255
|
+
.add(state, "specular")
|
|
4256
|
+
.name("Specular")
|
|
4257
|
+
.onChange((v) => applyToLenses("specular", v));
|
|
4258
|
+
surfaceFolder
|
|
4259
|
+
.add(state, "shadow")
|
|
4260
|
+
.name("Shadow")
|
|
4261
|
+
.onChange((v) => applyToLenses("shadow", v));
|
|
4262
|
+
|
|
4263
|
+
const tiltFolder = gui.addFolder("Tilt");
|
|
4264
|
+
tiltFolder
|
|
4265
|
+
.add(state, "tilt")
|
|
4266
|
+
.name("Tilt")
|
|
4267
|
+
.onChange((v) => applyToLenses("tilt", v));
|
|
4268
|
+
tiltFolder
|
|
4269
|
+
.add(state, "tiltFactor", 0, 25, 0.1)
|
|
4270
|
+
.name("Tilt Factor")
|
|
4271
|
+
.onChange((v) => applyToLenses("tiltFactor", v));
|
|
4272
|
+
tiltFolder
|
|
4273
|
+
.add(state, "tiltEase", 0, 1000, 10)
|
|
4274
|
+
.name("Tilt Ease")
|
|
4275
|
+
.onChange((v) => applyToLenses("tiltEase", v));
|
|
4276
|
+
|
|
4277
|
+
const initFolder = gui.addFolder("Initialisation");
|
|
4278
|
+
const reinitState = {
|
|
4279
|
+
reveal: options.reveal,
|
|
4280
|
+
resolution: options.resolution,
|
|
4281
|
+
};
|
|
4282
|
+
|
|
4283
|
+
initFolder
|
|
4284
|
+
.add(reinitState, "reveal", ["none", "fade"])
|
|
4285
|
+
.name("Reveal")
|
|
4286
|
+
.onFinishChange((value) => {
|
|
4287
|
+
if (
|
|
4288
|
+
confirm(
|
|
4289
|
+
"Changing reveal applies on the next initialisation. Continue?",
|
|
4290
|
+
)
|
|
4291
|
+
) {
|
|
4292
|
+
applyToLenses("reveal", value);
|
|
4293
|
+
} else {
|
|
4294
|
+
reinitState.reveal = options.reveal;
|
|
4295
|
+
gui.controllersRecursive().forEach((c) => c.updateDisplay());
|
|
4296
|
+
}
|
|
4297
|
+
});
|
|
4298
|
+
|
|
4299
|
+
initFolder
|
|
4300
|
+
.add(reinitState, "resolution", 0.5, 3, 0.25)
|
|
4301
|
+
.name("Resolution")
|
|
4302
|
+
.onFinishChange((value) => {
|
|
4303
|
+
if (
|
|
4304
|
+
confirm(
|
|
4305
|
+
"Changing resolution re-captures the page snapshot. Continue?",
|
|
4306
|
+
)
|
|
4307
|
+
) {
|
|
4308
|
+
applyToLenses("resolution", value);
|
|
4309
|
+
const renderer = window.__liquidGLRenderer__;
|
|
4310
|
+
if (renderer) {
|
|
4311
|
+
renderer._snapshotResolution = Math.max(0.1, Math.min(3.0, value));
|
|
4312
|
+
renderer.captureSnapshot();
|
|
4313
|
+
}
|
|
4314
|
+
} else {
|
|
4315
|
+
reinitState.resolution = options.resolution;
|
|
4316
|
+
gui.controllersRecursive().forEach((c) => c.updateDisplay());
|
|
4317
|
+
}
|
|
4318
|
+
});
|
|
4319
|
+
|
|
4320
|
+
const copyButton = {
|
|
4321
|
+
copySettings: () => {
|
|
4322
|
+
const code = generateInitCode(options);
|
|
4323
|
+
const controller = gui.controllers.find(
|
|
4324
|
+
(c) => c.property === "copySettings",
|
|
4325
|
+
);
|
|
4326
|
+
|
|
4327
|
+
if (!controller) return;
|
|
4328
|
+
|
|
4329
|
+
const originalName = controller._name;
|
|
4330
|
+
controller.disable();
|
|
4331
|
+
controller.name("✓ Copied");
|
|
4332
|
+
|
|
4333
|
+
const copySuccess = () => {
|
|
4334
|
+
setTimeout(() => {
|
|
4335
|
+
controller.name(originalName);
|
|
4336
|
+
controller.enable();
|
|
4337
|
+
}, 1500);
|
|
4338
|
+
};
|
|
4339
|
+
|
|
4340
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
4341
|
+
navigator.clipboard
|
|
4342
|
+
.writeText(code)
|
|
4343
|
+
.then(() => {
|
|
4344
|
+
copySuccess();
|
|
4345
|
+
})
|
|
4346
|
+
.catch((err) => {
|
|
4347
|
+
console.error("Clipboard error:", err);
|
|
4348
|
+
fallbackCopy(code);
|
|
4349
|
+
});
|
|
4350
|
+
} else {
|
|
4351
|
+
fallbackCopy(code);
|
|
4352
|
+
}
|
|
4353
|
+
|
|
4354
|
+
function fallbackCopy(text) {
|
|
4355
|
+
const textarea = document.createElement("textarea");
|
|
4356
|
+
textarea.value = text;
|
|
4357
|
+
textarea.style.position = "fixed";
|
|
4358
|
+
textarea.style.opacity = "0";
|
|
4359
|
+
document.body.appendChild(textarea);
|
|
4360
|
+
textarea.select();
|
|
4361
|
+
try {
|
|
4362
|
+
document.execCommand("copy");
|
|
4363
|
+
copySuccess();
|
|
4364
|
+
} catch (err) {
|
|
4365
|
+
console.error("Copy failed:", err);
|
|
4366
|
+
controller.name(originalName);
|
|
4367
|
+
controller.enable();
|
|
4368
|
+
prompt("Copy this code manually:", text);
|
|
4369
|
+
}
|
|
4370
|
+
document.body.removeChild(textarea);
|
|
4371
|
+
}
|
|
4372
|
+
},
|
|
4373
|
+
};
|
|
4374
|
+
gui.add(copyButton, "copySettings").name("Copy settings");
|
|
4375
|
+
|
|
4376
|
+
refractionFolder.close();
|
|
4377
|
+
surfaceFolder.close();
|
|
4378
|
+
tiltFolder.close();
|
|
4379
|
+
initFolder.close();
|
|
4380
|
+
|
|
4381
|
+
helperGUIs.push({ gui, lenses: lensList });
|
|
4382
|
+
return gui;
|
|
4383
|
+
}
|
|
4384
|
+
|
|
4385
|
+
function generateInitCode(options) {
|
|
4386
|
+
const lines = ["liquidGL({"];
|
|
4387
|
+
|
|
4388
|
+
lines.push(` target: "${options.target}",`);
|
|
4389
|
+
lines.push(` snapshot: "${options.snapshot}",`);
|
|
4390
|
+
lines.push(` resolution: ${options.resolution},`);
|
|
4391
|
+
lines.push(` refraction: ${options.refraction},`);
|
|
4392
|
+
lines.push(` aberration: ${options.aberration},`);
|
|
4393
|
+
lines.push(` bevelDepth: ${options.bevelDepth},`);
|
|
4394
|
+
lines.push(` bevelWidth: ${options.bevelWidth},`);
|
|
4395
|
+
lines.push(` frost: ${options.frost},`);
|
|
4396
|
+
lines.push(` shadow: ${options.shadow},`);
|
|
4397
|
+
lines.push(` specular: ${options.specular},`);
|
|
4398
|
+
lines.push(` reveal: "${options.reveal}",`);
|
|
4399
|
+
lines.push(` tilt: ${options.tilt},`);
|
|
4400
|
+
lines.push(` tiltFactor: ${options.tiltFactor},`);
|
|
4401
|
+
lines.push(` tiltEase: ${options.tiltEase},`);
|
|
4402
|
+
lines.push(` magnify: ${options.magnify},`);
|
|
4403
|
+
lines.push(` helper: false,`);
|
|
4404
|
+
lines.push(`});`);
|
|
4405
|
+
|
|
4406
|
+
return lines.join("\n");
|
|
4407
|
+
}
|
|
4408
|
+
|
|
4065
4409
|
/* --------------------------------------------------
|
|
4066
4410
|
* Public API
|
|
4067
4411
|
* ------------------------------------------------*/
|
|
@@ -4082,6 +4426,7 @@ const liquidGL = (() => {
|
|
|
4082
4426
|
tiltFactor: 5,
|
|
4083
4427
|
tiltEase: 400,
|
|
4084
4428
|
magnify: 1,
|
|
4429
|
+
helper: false,
|
|
4085
4430
|
on: {},
|
|
4086
4431
|
};
|
|
4087
4432
|
const options = { ...defaults, ...userOptions };
|
|
@@ -4140,6 +4485,17 @@ const liquidGL = (() => {
|
|
|
4140
4485
|
renderer._rafId = requestAnimationFrame(loop);
|
|
4141
4486
|
}
|
|
4142
4487
|
|
|
4488
|
+
if (options.helper) {
|
|
4489
|
+
loadLilGui()
|
|
4490
|
+
.then(() => {
|
|
4491
|
+
const instanceIndex = helperGUIs.length;
|
|
4492
|
+
createHelperGUI(instances, options, instanceIndex);
|
|
4493
|
+
})
|
|
4494
|
+
.catch((err) => {
|
|
4495
|
+
console.error("liquidGL: Failed to load helper GUI:", err);
|
|
4496
|
+
});
|
|
4497
|
+
}
|
|
4498
|
+
|
|
4143
4499
|
return instances.length === 1 ? instances[0] : instances;
|
|
4144
4500
|
};
|
|
4145
4501
|
|