Resize fra nord/vest: juster posisjon slik at motstående kant forblir fast

Når man drar toppen eller venstre kant av et panel, ble bare størrelsen
endret mens posisjon sto fast — som ga inntrykk av at feil kant beveget
seg. Nå beregner BlockShell posisjons-delta (dx, dy) og parent justerer
x/y tilsvarende, slik at den kanten du drar i følger musepekeren.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
vegard 2026-03-19 05:52:00 +00:00
parent da88bfcb1f
commit b8be448908
4 changed files with 31 additions and 11 deletions

View file

@ -230,10 +230,16 @@
if (resizeDir.includes('n')) newH = resizeStartH - dy;
// Clamp
newW = Math.min(constraints.maxWidth, Math.max(constraints.minWidth, newW));
newH = Math.min(constraints.maxHeight, Math.max(constraints.minHeight, newH));
const clampedW = Math.min(constraints.maxWidth, Math.max(constraints.minWidth, newW));
const clampedH = Math.min(constraints.maxHeight, Math.max(constraints.minHeight, newH));
onResize?.(newW, newH);
// Position delta for n/w dragging: move origin to keep the opposite edge fixed
let posDx = 0;
let posDy = 0;
if (resizeDir.includes('w')) posDx = resizeStartW - clampedW;
if (resizeDir.includes('n')) posDy = resizeStartH - clampedH;
onResize?.(clampedW, clampedH, posDx, posDy);
}
function handleResizeEnd() {

View file

@ -70,8 +70,8 @@ export interface BlockShellEvents {
onClose?: () => void;
/** Panel drag-moved (delta in world coords) */
onDragMove?: (dx: number, dy: number) => void;
/** Panel resized */
onResize?: (width: number, height: number) => void;
/** Panel resized. dx/dy are position offsets for n/w edge dragging. */
onResize?: (width: number, height: number, dx?: number, dy?: number) => void;
/** Panel fullscreen state changed */
onFullscreenChange?: (isFullscreen: boolean) => void;
/** Panel minimize state changed (double-click header to toggle) */

View file

@ -165,10 +165,17 @@
}
}
function handlePanelResize(trait: string, width: number, height: number) {
function handlePanelResize(trait: string, width: number, height: number, dx?: number, dy?: number) {
const idx = layout.panels.findIndex(p => p.trait === trait);
if (idx >= 0) {
layout.panels[idx] = { ...layout.panels[idx], width, height };
const panel = layout.panels[idx];
layout.panels[idx] = {
...panel,
width,
height,
x: panel.x + (dx ?? 0),
y: panel.y + (dy ?? 0),
};
layout = { ...layout };
persistLayout();
}
@ -783,7 +790,7 @@
height={panel?.height ?? obj.height}
minimized={panel?.minimized ?? false}
receiver={getReceiverForTrait(trait)}
onResize={(w, h) => handlePanelResize(trait, w, h)}
onResize={(w, h, dx, dy) => handlePanelResize(trait, w, h, dx, dy)}
onClose={() => handlePanelClose(trait)}
onMinimizeChange={(m) => handlePanelMinimize(trait, m)}
onDrop={(payload, shiftKey) => handlePanelDrop(trait, payload, shiftKey)}

View file

@ -182,10 +182,17 @@
}
/** Handle panel resize via BlockShell */
function handlePanelResize(trait: string, width: number, height: number) {
function handlePanelResize(trait: string, width: number, height: number, dx?: number, dy?: number) {
const idx = layout.panels.findIndex(p => p.trait === trait);
if (idx >= 0) {
layout.panels[idx] = { ...layout.panels[idx], width, height };
const panel = layout.panels[idx];
layout.panels[idx] = {
...panel,
width,
height,
x: panel.x + (dx ?? 0),
y: panel.y + (dy ?? 0),
};
layout = { ...layout };
persistLayout();
}
@ -386,7 +393,7 @@
width={panel?.width ?? obj.width}
height={panel?.height ?? obj.height}
minimized={panel?.minimized ?? false}
onResize={(w, h) => handlePanelResize(trait, w, h)}
onResize={(w, h, dx, dy) => handlePanelResize(trait, w, h, dx, dy)}
onClose={() => handlePanelClose(trait)}
onMinimizeChange={(m) => handlePanelMinimize(trait, m)}
>