@almadar/ui 5.42.0 → 5.43.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/dist/avl/index.cjs +317 -119
- package/dist/avl/index.js +317 -119
- package/dist/components/game/organisms/physics-sim/SimulationCanvas.d.ts +8 -2
- package/dist/components/index.cjs +317 -119
- package/dist/components/index.js +317 -119
- package/dist/hooks/index.cjs +68 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +68 -1
- package/dist/hooks/useRenderInterpolation.d.ts +33 -0
- package/dist/providers/index.cjs +317 -119
- package/dist/providers/index.js +317 -119
- package/dist/runtime/index.cjs +317 -119
- package/dist/runtime/index.js +317 -119
- package/package.json +1 -1
package/dist/avl/index.cjs
CHANGED
|
@@ -31086,6 +31086,78 @@ var init_GameOverScreen = __esm({
|
|
|
31086
31086
|
GameOverScreen.displayName = "GameOverScreen";
|
|
31087
31087
|
}
|
|
31088
31088
|
});
|
|
31089
|
+
function useRenderInterpolation(options = {}) {
|
|
31090
|
+
const tickIntervalMs = options.tickIntervalMs ?? 1e3 / 30;
|
|
31091
|
+
const prevRef = React91.useRef(null);
|
|
31092
|
+
const currRef = React91.useRef(null);
|
|
31093
|
+
const rafRef = React91.useRef(null);
|
|
31094
|
+
const onSnapshot = React91.useCallback((entities) => {
|
|
31095
|
+
prevRef.current = currRef.current;
|
|
31096
|
+
currRef.current = { entities, arrivedAt: performance.now() };
|
|
31097
|
+
}, []);
|
|
31098
|
+
const getInterpolated = React91.useCallback((now2) => {
|
|
31099
|
+
const out = /* @__PURE__ */ new Map();
|
|
31100
|
+
const curr = currRef.current;
|
|
31101
|
+
if (!curr) return out;
|
|
31102
|
+
const prev = prevRef.current;
|
|
31103
|
+
if (!prev) {
|
|
31104
|
+
for (const e of curr.entities) out.set(e.id, { x: e.x, y: e.y });
|
|
31105
|
+
return out;
|
|
31106
|
+
}
|
|
31107
|
+
const rawAlpha = (now2 - curr.arrivedAt) / tickIntervalMs;
|
|
31108
|
+
const alpha = rawAlpha < 0 ? 0 : rawAlpha > 1 ? 1 : rawAlpha;
|
|
31109
|
+
const prevMap = /* @__PURE__ */ new Map();
|
|
31110
|
+
for (const e of prev.entities) prevMap.set(e.id, e);
|
|
31111
|
+
for (const c of curr.entities) {
|
|
31112
|
+
const p2 = prevMap.get(c.id);
|
|
31113
|
+
if (!p2) {
|
|
31114
|
+
out.set(c.id, { x: c.x, y: c.y });
|
|
31115
|
+
} else {
|
|
31116
|
+
out.set(c.id, {
|
|
31117
|
+
x: p2.x + (c.x - p2.x) * alpha,
|
|
31118
|
+
y: p2.y + (c.y - p2.y) * alpha
|
|
31119
|
+
});
|
|
31120
|
+
}
|
|
31121
|
+
}
|
|
31122
|
+
return out;
|
|
31123
|
+
}, [tickIntervalMs]);
|
|
31124
|
+
const startLoop = React91.useCallback(
|
|
31125
|
+
(draw) => {
|
|
31126
|
+
let active = true;
|
|
31127
|
+
const loop = () => {
|
|
31128
|
+
if (!active) return;
|
|
31129
|
+
try {
|
|
31130
|
+
draw(getInterpolated(performance.now()));
|
|
31131
|
+
} catch {
|
|
31132
|
+
}
|
|
31133
|
+
rafRef.current = requestAnimationFrame(loop);
|
|
31134
|
+
};
|
|
31135
|
+
rafRef.current = requestAnimationFrame(loop);
|
|
31136
|
+
return () => {
|
|
31137
|
+
active = false;
|
|
31138
|
+
if (rafRef.current !== null) {
|
|
31139
|
+
cancelAnimationFrame(rafRef.current);
|
|
31140
|
+
rafRef.current = null;
|
|
31141
|
+
}
|
|
31142
|
+
};
|
|
31143
|
+
},
|
|
31144
|
+
[getInterpolated]
|
|
31145
|
+
);
|
|
31146
|
+
React91.useEffect(() => {
|
|
31147
|
+
return () => {
|
|
31148
|
+
if (rafRef.current !== null) {
|
|
31149
|
+
cancelAnimationFrame(rafRef.current);
|
|
31150
|
+
rafRef.current = null;
|
|
31151
|
+
}
|
|
31152
|
+
};
|
|
31153
|
+
}, []);
|
|
31154
|
+
return { onSnapshot, getInterpolated, startLoop };
|
|
31155
|
+
}
|
|
31156
|
+
var init_useRenderInterpolation = __esm({
|
|
31157
|
+
"hooks/useRenderInterpolation.ts"() {
|
|
31158
|
+
"use client";
|
|
31159
|
+
}
|
|
31160
|
+
});
|
|
31089
31161
|
function PlatformerCanvas({
|
|
31090
31162
|
player,
|
|
31091
31163
|
platforms = [
|
|
@@ -31154,8 +31226,43 @@ function PlatformerCanvas({
|
|
|
31154
31226
|
y: 336,
|
|
31155
31227
|
width: 32,
|
|
31156
31228
|
height: 48,
|
|
31229
|
+
vx: 0,
|
|
31230
|
+
vy: 0,
|
|
31231
|
+
grounded: true,
|
|
31157
31232
|
facingRight: true
|
|
31158
31233
|
};
|
|
31234
|
+
const playerRef = React91.useRef(resolvedPlayer);
|
|
31235
|
+
playerRef.current = resolvedPlayer;
|
|
31236
|
+
const interp = useRenderInterpolation();
|
|
31237
|
+
React91.useEffect(() => {
|
|
31238
|
+
interp.onSnapshot([{ id: "player", x: resolvedPlayer.x, y: resolvedPlayer.y }]);
|
|
31239
|
+
}, [resolvedPlayer.x, resolvedPlayer.y]);
|
|
31240
|
+
const propsRef = React91.useRef({
|
|
31241
|
+
platforms,
|
|
31242
|
+
worldWidth,
|
|
31243
|
+
worldHeight,
|
|
31244
|
+
canvasWidth,
|
|
31245
|
+
canvasHeight,
|
|
31246
|
+
followCamera,
|
|
31247
|
+
bgColor,
|
|
31248
|
+
playerSprite,
|
|
31249
|
+
tileSprites,
|
|
31250
|
+
backgroundImage,
|
|
31251
|
+
assetBaseUrl
|
|
31252
|
+
});
|
|
31253
|
+
propsRef.current = {
|
|
31254
|
+
platforms,
|
|
31255
|
+
worldWidth,
|
|
31256
|
+
worldHeight,
|
|
31257
|
+
canvasWidth,
|
|
31258
|
+
canvasHeight,
|
|
31259
|
+
followCamera,
|
|
31260
|
+
bgColor,
|
|
31261
|
+
playerSprite,
|
|
31262
|
+
tileSprites,
|
|
31263
|
+
backgroundImage,
|
|
31264
|
+
assetBaseUrl
|
|
31265
|
+
};
|
|
31159
31266
|
const handleKeyDown = React91.useCallback((e) => {
|
|
31160
31267
|
if (keysRef.current.has(e.code)) return;
|
|
31161
31268
|
keysRef.current.add(e.code);
|
|
@@ -31204,124 +31311,149 @@ function PlatformerCanvas({
|
|
|
31204
31311
|
canvas.width = canvasWidth * dpr;
|
|
31205
31312
|
canvas.height = canvasHeight * dpr;
|
|
31206
31313
|
ctx.scale(dpr, dpr);
|
|
31207
|
-
|
|
31208
|
-
|
|
31209
|
-
|
|
31210
|
-
|
|
31211
|
-
|
|
31212
|
-
|
|
31213
|
-
|
|
31214
|
-
|
|
31215
|
-
|
|
31216
|
-
|
|
31217
|
-
|
|
31218
|
-
|
|
31219
|
-
|
|
31220
|
-
|
|
31221
|
-
|
|
31222
|
-
|
|
31223
|
-
|
|
31224
|
-
|
|
31225
|
-
|
|
31226
|
-
|
|
31227
|
-
|
|
31228
|
-
|
|
31229
|
-
|
|
31230
|
-
|
|
31231
|
-
|
|
31232
|
-
|
|
31233
|
-
|
|
31234
|
-
|
|
31235
|
-
|
|
31236
|
-
|
|
31237
|
-
|
|
31238
|
-
|
|
31239
|
-
|
|
31240
|
-
|
|
31241
|
-
|
|
31242
|
-
const px = plat.x - camX;
|
|
31243
|
-
const py = plat.y - camY;
|
|
31244
|
-
const platType = plat.type ?? "ground";
|
|
31245
|
-
const spriteUrl = tileSprites?.[platType];
|
|
31246
|
-
const tileImg = spriteUrl ? loadImage(spriteUrl) : null;
|
|
31247
|
-
if (tileImg) {
|
|
31248
|
-
const tileW = tileImg.naturalWidth;
|
|
31249
|
-
const tileH = tileImg.naturalHeight;
|
|
31250
|
-
const scaleH = plat.height / tileH;
|
|
31251
|
-
const scaledW = tileW * scaleH;
|
|
31252
|
-
for (let tx = 0; tx < plat.width; tx += scaledW) {
|
|
31253
|
-
const drawW = Math.min(scaledW, plat.width - tx);
|
|
31254
|
-
const srcW = drawW / scaleH;
|
|
31255
|
-
ctx.drawImage(tileImg, 0, 0, srcW, tileH, px + tx, py, drawW, plat.height);
|
|
31256
|
-
}
|
|
31314
|
+
}, [canvasWidth, canvasHeight]);
|
|
31315
|
+
React91.useEffect(() => {
|
|
31316
|
+
const drawFrame = (positions) => {
|
|
31317
|
+
const canvas = canvasRef.current;
|
|
31318
|
+
if (!canvas) return;
|
|
31319
|
+
const ctx = canvas.getContext("2d");
|
|
31320
|
+
if (!ctx) return;
|
|
31321
|
+
const {
|
|
31322
|
+
platforms: plats,
|
|
31323
|
+
worldWidth: ww,
|
|
31324
|
+
worldHeight: wh,
|
|
31325
|
+
canvasWidth: cw,
|
|
31326
|
+
canvasHeight: ch,
|
|
31327
|
+
followCamera: fc,
|
|
31328
|
+
bgColor: bg,
|
|
31329
|
+
playerSprite: pSprite,
|
|
31330
|
+
tileSprites: tSprites,
|
|
31331
|
+
backgroundImage: bgImg
|
|
31332
|
+
} = propsRef.current;
|
|
31333
|
+
const auth = playerRef.current;
|
|
31334
|
+
const interped = positions.get("player");
|
|
31335
|
+
const px = interped?.x ?? auth.x;
|
|
31336
|
+
const py = interped?.y ?? auth.y;
|
|
31337
|
+
let camX = 0;
|
|
31338
|
+
let camY = 0;
|
|
31339
|
+
if (fc) {
|
|
31340
|
+
camX = Math.max(0, Math.min(px - cw / 2, ww - cw));
|
|
31341
|
+
camY = Math.max(0, Math.min(py - ch / 2 - 50, wh - ch));
|
|
31342
|
+
}
|
|
31343
|
+
const bgImage = bgImg ? loadImage(bgImg) : null;
|
|
31344
|
+
if (bgImage) {
|
|
31345
|
+
ctx.drawImage(bgImage, 0, 0, cw, ch);
|
|
31346
|
+
} else if (bg) {
|
|
31347
|
+
ctx.fillStyle = bg;
|
|
31348
|
+
ctx.fillRect(0, 0, cw, ch);
|
|
31257
31349
|
} else {
|
|
31258
|
-
const
|
|
31259
|
-
|
|
31260
|
-
|
|
31261
|
-
ctx.fillStyle =
|
|
31262
|
-
ctx.fillRect(
|
|
31263
|
-
|
|
31264
|
-
|
|
31265
|
-
|
|
31266
|
-
|
|
31267
|
-
|
|
31268
|
-
|
|
31350
|
+
const grad = ctx.createLinearGradient(0, 0, 0, ch);
|
|
31351
|
+
grad.addColorStop(0, SKY_GRADIENT_TOP);
|
|
31352
|
+
grad.addColorStop(1, SKY_GRADIENT_BOTTOM);
|
|
31353
|
+
ctx.fillStyle = grad;
|
|
31354
|
+
ctx.fillRect(0, 0, cw, ch);
|
|
31355
|
+
}
|
|
31356
|
+
ctx.strokeStyle = GRID_COLOR;
|
|
31357
|
+
ctx.lineWidth = 1;
|
|
31358
|
+
const gridSize = 32;
|
|
31359
|
+
for (let gx = -camX % gridSize; gx < cw; gx += gridSize) {
|
|
31360
|
+
ctx.beginPath();
|
|
31361
|
+
ctx.moveTo(gx, 0);
|
|
31362
|
+
ctx.lineTo(gx, ch);
|
|
31363
|
+
ctx.stroke();
|
|
31364
|
+
}
|
|
31365
|
+
for (let gy = -camY % gridSize; gy < ch; gy += gridSize) {
|
|
31366
|
+
ctx.beginPath();
|
|
31367
|
+
ctx.moveTo(0, gy);
|
|
31368
|
+
ctx.lineTo(cw, gy);
|
|
31369
|
+
ctx.stroke();
|
|
31370
|
+
}
|
|
31371
|
+
for (const plat of plats) {
|
|
31372
|
+
const platX = plat.x - camX;
|
|
31373
|
+
const platY = plat.y - camY;
|
|
31374
|
+
const platType = plat.type ?? "ground";
|
|
31375
|
+
const spriteUrl = tSprites?.[platType];
|
|
31376
|
+
const tileImg = spriteUrl ? loadImage(spriteUrl) : null;
|
|
31377
|
+
if (tileImg) {
|
|
31378
|
+
const tileW = tileImg.naturalWidth;
|
|
31379
|
+
const tileH = tileImg.naturalHeight;
|
|
31380
|
+
const scaleH = plat.height / tileH;
|
|
31381
|
+
const scaledW = tileW * scaleH;
|
|
31382
|
+
for (let tx = 0; tx < plat.width; tx += scaledW) {
|
|
31383
|
+
const drawW = Math.min(scaledW, plat.width - tx);
|
|
31384
|
+
const srcW = drawW / scaleH;
|
|
31385
|
+
ctx.drawImage(tileImg, 0, 0, srcW, tileH, platX + tx, platY, drawW, plat.height);
|
|
31386
|
+
}
|
|
31387
|
+
} else {
|
|
31388
|
+
const color = PLATFORM_COLORS[platType] ?? PLATFORM_COLORS.ground;
|
|
31389
|
+
ctx.fillStyle = color;
|
|
31390
|
+
ctx.fillRect(platX, platY, plat.width, plat.height);
|
|
31391
|
+
ctx.fillStyle = "rgba(255, 255, 255, 0.15)";
|
|
31392
|
+
ctx.fillRect(platX, platY, plat.width, 3);
|
|
31393
|
+
ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
|
|
31394
|
+
ctx.fillRect(platX, platY + plat.height - 2, plat.width, 2);
|
|
31395
|
+
if (platType === "hazard") {
|
|
31396
|
+
ctx.strokeStyle = "#e74c3c";
|
|
31397
|
+
ctx.lineWidth = 2;
|
|
31398
|
+
for (let sx = platX; sx < platX + plat.width; sx += 12) {
|
|
31399
|
+
ctx.beginPath();
|
|
31400
|
+
ctx.moveTo(sx, platY);
|
|
31401
|
+
ctx.lineTo(sx + 6, platY + plat.height);
|
|
31402
|
+
ctx.stroke();
|
|
31403
|
+
}
|
|
31404
|
+
}
|
|
31405
|
+
if (platType === "goal") {
|
|
31406
|
+
ctx.fillStyle = "rgba(241, 196, 15, 0.5)";
|
|
31269
31407
|
ctx.beginPath();
|
|
31270
|
-
ctx.
|
|
31271
|
-
ctx.
|
|
31272
|
-
ctx.stroke();
|
|
31408
|
+
ctx.arc(platX + plat.width / 2, platY - 10, 8, 0, Math.PI * 2);
|
|
31409
|
+
ctx.fill();
|
|
31273
31410
|
}
|
|
31274
31411
|
}
|
|
31275
|
-
if (platType === "goal") {
|
|
31276
|
-
ctx.fillStyle = "rgba(241, 196, 15, 0.5)";
|
|
31277
|
-
ctx.beginPath();
|
|
31278
|
-
ctx.arc(px + plat.width / 2, py - 10, 8, 0, Math.PI * 2);
|
|
31279
|
-
ctx.fill();
|
|
31280
|
-
}
|
|
31281
31412
|
}
|
|
31282
|
-
|
|
31283
|
-
|
|
31284
|
-
|
|
31285
|
-
|
|
31286
|
-
|
|
31287
|
-
|
|
31288
|
-
|
|
31289
|
-
|
|
31290
|
-
|
|
31291
|
-
|
|
31292
|
-
|
|
31293
|
-
|
|
31294
|
-
|
|
31413
|
+
const pw = auth.width ?? 24;
|
|
31414
|
+
const ph = auth.height ?? 32;
|
|
31415
|
+
const ppx = px - camX;
|
|
31416
|
+
const ppy = py - camY;
|
|
31417
|
+
const facingRight = auth.facingRight ?? true;
|
|
31418
|
+
const playerImg = pSprite ? loadImage(pSprite) : null;
|
|
31419
|
+
if (playerImg) {
|
|
31420
|
+
ctx.save();
|
|
31421
|
+
if (!facingRight) {
|
|
31422
|
+
ctx.translate(ppx + pw, ppy);
|
|
31423
|
+
ctx.scale(-1, 1);
|
|
31424
|
+
ctx.drawImage(playerImg, 0, 0, pw, ph);
|
|
31425
|
+
} else {
|
|
31426
|
+
ctx.drawImage(playerImg, ppx, ppy, pw, ph);
|
|
31427
|
+
}
|
|
31428
|
+
ctx.restore();
|
|
31295
31429
|
} else {
|
|
31296
|
-
ctx.
|
|
31430
|
+
ctx.fillStyle = PLAYER_COLOR;
|
|
31431
|
+
const radius = Math.min(pw, ph) * 0.25;
|
|
31432
|
+
ctx.beginPath();
|
|
31433
|
+
ctx.moveTo(ppx + radius, ppy);
|
|
31434
|
+
ctx.lineTo(ppx + pw - radius, ppy);
|
|
31435
|
+
ctx.quadraticCurveTo(ppx + pw, ppy, ppx + pw, ppy + radius);
|
|
31436
|
+
ctx.lineTo(ppx + pw, ppy + ph - radius);
|
|
31437
|
+
ctx.quadraticCurveTo(ppx + pw, ppy + ph, ppx + pw - radius, ppy + ph);
|
|
31438
|
+
ctx.lineTo(ppx + radius, ppy + ph);
|
|
31439
|
+
ctx.quadraticCurveTo(ppx, ppy + ph, ppx, ppy + ph - radius);
|
|
31440
|
+
ctx.lineTo(ppx, ppy + radius);
|
|
31441
|
+
ctx.quadraticCurveTo(ppx, ppy, ppx + radius, ppy);
|
|
31442
|
+
ctx.fill();
|
|
31443
|
+
const eyeY = ppy + ph * 0.3;
|
|
31444
|
+
const eyeSize = 3;
|
|
31445
|
+
const eyeOffsetX = facingRight ? pw * 0.55 : pw * 0.2;
|
|
31446
|
+
ctx.fillStyle = PLAYER_EYE_COLOR;
|
|
31447
|
+
ctx.beginPath();
|
|
31448
|
+
ctx.arc(ppx + eyeOffsetX, eyeY, eyeSize, 0, Math.PI * 2);
|
|
31449
|
+
ctx.fill();
|
|
31450
|
+
ctx.beginPath();
|
|
31451
|
+
ctx.arc(ppx + eyeOffsetX + 7, eyeY, eyeSize, 0, Math.PI * 2);
|
|
31452
|
+
ctx.fill();
|
|
31297
31453
|
}
|
|
31298
|
-
|
|
31299
|
-
|
|
31300
|
-
|
|
31301
|
-
const radius = Math.min(pw, ph) * 0.25;
|
|
31302
|
-
ctx.beginPath();
|
|
31303
|
-
ctx.moveTo(ppx + radius, ppy);
|
|
31304
|
-
ctx.lineTo(ppx + pw - radius, ppy);
|
|
31305
|
-
ctx.quadraticCurveTo(ppx + pw, ppy, ppx + pw, ppy + radius);
|
|
31306
|
-
ctx.lineTo(ppx + pw, ppy + ph - radius);
|
|
31307
|
-
ctx.quadraticCurveTo(ppx + pw, ppy + ph, ppx + pw - radius, ppy + ph);
|
|
31308
|
-
ctx.lineTo(ppx + radius, ppy + ph);
|
|
31309
|
-
ctx.quadraticCurveTo(ppx, ppy + ph, ppx, ppy + ph - radius);
|
|
31310
|
-
ctx.lineTo(ppx, ppy + radius);
|
|
31311
|
-
ctx.quadraticCurveTo(ppx, ppy, ppx + radius, ppy);
|
|
31312
|
-
ctx.fill();
|
|
31313
|
-
const eyeY = ppy + ph * 0.3;
|
|
31314
|
-
const eyeSize = 3;
|
|
31315
|
-
const eyeOffsetX = facingRight ? pw * 0.55 : pw * 0.2;
|
|
31316
|
-
ctx.fillStyle = PLAYER_EYE_COLOR;
|
|
31317
|
-
ctx.beginPath();
|
|
31318
|
-
ctx.arc(ppx + eyeOffsetX, eyeY, eyeSize, 0, Math.PI * 2);
|
|
31319
|
-
ctx.fill();
|
|
31320
|
-
ctx.beginPath();
|
|
31321
|
-
ctx.arc(ppx + eyeOffsetX + 7, eyeY, eyeSize, 0, Math.PI * 2);
|
|
31322
|
-
ctx.fill();
|
|
31323
|
-
}
|
|
31324
|
-
}, [player, platforms, worldWidth, worldHeight, canvasWidth, canvasHeight, followCamera, bgColor, playerSprite, tileSprites, backgroundImage, assetBaseUrl, loadedImages]);
|
|
31454
|
+
};
|
|
31455
|
+
return interp.startLoop(drawFrame);
|
|
31456
|
+
}, [interp.startLoop, loadImage]);
|
|
31325
31457
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
31326
31458
|
"canvas",
|
|
31327
31459
|
{
|
|
@@ -31339,6 +31471,7 @@ var init_PlatformerCanvas = __esm({
|
|
|
31339
31471
|
init_cn();
|
|
31340
31472
|
init_useEventBus();
|
|
31341
31473
|
init_verificationRegistry();
|
|
31474
|
+
init_useRenderInterpolation();
|
|
31342
31475
|
PLATFORM_COLORS = {
|
|
31343
31476
|
ground: "#4a7c59",
|
|
31344
31477
|
platform: "#7c6b4a",
|
|
@@ -31721,13 +31854,13 @@ var init_MapView = __esm({
|
|
|
31721
31854
|
shadowSize: [41, 41]
|
|
31722
31855
|
});
|
|
31723
31856
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
31724
|
-
const { useEffect:
|
|
31857
|
+
const { useEffect: useEffect79, useRef: useRef71, useCallback: useCallback118, useState: useState115 } = React91__namespace.default;
|
|
31725
31858
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
31726
31859
|
const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
31727
31860
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
31728
31861
|
const map = useMap();
|
|
31729
|
-
const prevRef =
|
|
31730
|
-
|
|
31862
|
+
const prevRef = useRef71({ centerLat, centerLng, zoom });
|
|
31863
|
+
useEffect79(() => {
|
|
31731
31864
|
const prev = prevRef.current;
|
|
31732
31865
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
31733
31866
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -31738,7 +31871,7 @@ var init_MapView = __esm({
|
|
|
31738
31871
|
}
|
|
31739
31872
|
function MapClickHandler({ onMapClick }) {
|
|
31740
31873
|
const map = useMap();
|
|
31741
|
-
|
|
31874
|
+
useEffect79(() => {
|
|
31742
31875
|
if (!onMapClick) return;
|
|
31743
31876
|
const handler = (e) => {
|
|
31744
31877
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -31767,7 +31900,7 @@ var init_MapView = __esm({
|
|
|
31767
31900
|
}) {
|
|
31768
31901
|
const eventBus = useEventBus3();
|
|
31769
31902
|
const [clickedPosition, setClickedPosition] = useState115(null);
|
|
31770
|
-
const handleMapClick =
|
|
31903
|
+
const handleMapClick = useCallback118((lat, lng) => {
|
|
31771
31904
|
if (showClickedPin) {
|
|
31772
31905
|
setClickedPosition({ lat, lng });
|
|
31773
31906
|
}
|
|
@@ -31776,7 +31909,7 @@ var init_MapView = __esm({
|
|
|
31776
31909
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
31777
31910
|
}
|
|
31778
31911
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
31779
|
-
const handleMarkerClick =
|
|
31912
|
+
const handleMarkerClick = useCallback118((marker) => {
|
|
31780
31913
|
onMarkerClick?.(marker);
|
|
31781
31914
|
if (markerClickEvent) {
|
|
31782
31915
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -47239,11 +47372,13 @@ function SimulationCanvas({
|
|
|
47239
47372
|
height = 400,
|
|
47240
47373
|
running,
|
|
47241
47374
|
speed = 1,
|
|
47375
|
+
bodies: externalBodies,
|
|
47242
47376
|
className
|
|
47243
47377
|
}) {
|
|
47244
47378
|
const preset = React91.useMemo(() => resolvePreset(presetProp), [presetProp]);
|
|
47245
47379
|
const canvasRef = React91.useRef(null);
|
|
47246
47380
|
const bodiesRef = React91.useRef(structuredClone(preset.bodies));
|
|
47381
|
+
const interp = useRenderInterpolation();
|
|
47247
47382
|
React91.useEffect(() => {
|
|
47248
47383
|
bodiesRef.current = structuredClone(preset.bodies);
|
|
47249
47384
|
}, [preset]);
|
|
@@ -47341,6 +47476,67 @@ function SimulationCanvas({
|
|
|
47341
47476
|
}
|
|
47342
47477
|
}, [width, height, preset]);
|
|
47343
47478
|
React91.useEffect(() => {
|
|
47479
|
+
if (!externalBodies) return;
|
|
47480
|
+
interp.onSnapshot(externalBodies.map((b) => ({ id: b.id, x: b.x, y: b.y })));
|
|
47481
|
+
}, [externalBodies]);
|
|
47482
|
+
const presetRef = React91.useRef(preset);
|
|
47483
|
+
presetRef.current = preset;
|
|
47484
|
+
const widthRef = React91.useRef(width);
|
|
47485
|
+
widthRef.current = width;
|
|
47486
|
+
const heightRef = React91.useRef(height);
|
|
47487
|
+
heightRef.current = height;
|
|
47488
|
+
React91.useEffect(() => {
|
|
47489
|
+
if (!externalBodies) return;
|
|
47490
|
+
const drawInterpolated = (positions) => {
|
|
47491
|
+
const canvas = canvasRef.current;
|
|
47492
|
+
if (!canvas) return;
|
|
47493
|
+
const ctx = canvas.getContext("2d");
|
|
47494
|
+
if (!ctx) return;
|
|
47495
|
+
const bodies = bodiesRef.current;
|
|
47496
|
+
const p2 = presetRef.current;
|
|
47497
|
+
const w = widthRef.current;
|
|
47498
|
+
const h = heightRef.current;
|
|
47499
|
+
ctx.clearRect(0, 0, w, h);
|
|
47500
|
+
ctx.fillStyle = p2.backgroundColor ?? "#1a1a2e";
|
|
47501
|
+
ctx.fillRect(0, 0, w, h);
|
|
47502
|
+
if (p2.constraints) {
|
|
47503
|
+
for (const c of p2.constraints) {
|
|
47504
|
+
const a = bodies[c.bodyA];
|
|
47505
|
+
const b = bodies[c.bodyB];
|
|
47506
|
+
if (a && b) {
|
|
47507
|
+
const aPos = positions.get(a.id) ?? a;
|
|
47508
|
+
const bPos = positions.get(b.id) ?? b;
|
|
47509
|
+
ctx.beginPath();
|
|
47510
|
+
ctx.moveTo(aPos.x, aPos.y);
|
|
47511
|
+
ctx.lineTo(bPos.x, bPos.y);
|
|
47512
|
+
ctx.strokeStyle = "#533483";
|
|
47513
|
+
ctx.lineWidth = 1;
|
|
47514
|
+
ctx.setLineDash([4, 4]);
|
|
47515
|
+
ctx.stroke();
|
|
47516
|
+
ctx.setLineDash([]);
|
|
47517
|
+
}
|
|
47518
|
+
}
|
|
47519
|
+
}
|
|
47520
|
+
for (const body of bodies) {
|
|
47521
|
+
const pos = positions.get(body.id) ?? body;
|
|
47522
|
+
ctx.beginPath();
|
|
47523
|
+
ctx.arc(pos.x, pos.y, body.radius, 0, Math.PI * 2);
|
|
47524
|
+
ctx.fillStyle = body.color ?? "#e94560";
|
|
47525
|
+
ctx.fill();
|
|
47526
|
+
if (p2.showVelocity) {
|
|
47527
|
+
ctx.beginPath();
|
|
47528
|
+
ctx.moveTo(pos.x, pos.y);
|
|
47529
|
+
ctx.lineTo(pos.x + body.vx * 0.1, pos.y + body.vy * 0.1);
|
|
47530
|
+
ctx.strokeStyle = "#16213e";
|
|
47531
|
+
ctx.lineWidth = 2;
|
|
47532
|
+
ctx.stroke();
|
|
47533
|
+
}
|
|
47534
|
+
}
|
|
47535
|
+
};
|
|
47536
|
+
return interp.startLoop(drawInterpolated);
|
|
47537
|
+
}, [externalBodies !== void 0, interp.startLoop]);
|
|
47538
|
+
React91.useEffect(() => {
|
|
47539
|
+
if (externalBodies !== void 0) return;
|
|
47344
47540
|
if (!running) return;
|
|
47345
47541
|
let raf;
|
|
47346
47542
|
const loop = () => {
|
|
@@ -47350,10 +47546,11 @@ function SimulationCanvas({
|
|
|
47350
47546
|
};
|
|
47351
47547
|
raf = requestAnimationFrame(loop);
|
|
47352
47548
|
return () => cancelAnimationFrame(raf);
|
|
47353
|
-
}, [running, step, draw]);
|
|
47549
|
+
}, [running, step, draw, externalBodies]);
|
|
47354
47550
|
React91.useEffect(() => {
|
|
47551
|
+
if (externalBodies !== void 0) return;
|
|
47355
47552
|
draw();
|
|
47356
|
-
}, [draw]);
|
|
47553
|
+
}, [draw, externalBodies]);
|
|
47357
47554
|
React91.useEffect(() => {
|
|
47358
47555
|
if (typeof window === "undefined") return;
|
|
47359
47556
|
const canvas = canvasRef.current;
|
|
@@ -47379,6 +47576,7 @@ var init_SimulationCanvas = __esm({
|
|
|
47379
47576
|
init_atoms2();
|
|
47380
47577
|
init_verificationRegistry();
|
|
47381
47578
|
init_presets();
|
|
47579
|
+
init_useRenderInterpolation();
|
|
47382
47580
|
SimulationCanvas.displayName = "SimulationCanvas";
|
|
47383
47581
|
}
|
|
47384
47582
|
});
|