Files
Genarrative/packages/image-canvas-core/src/layerTransform.ts
T
menghao 03a4410272
Project CI / Repository checks (push) Successful in 1m5s
Project CI / Frontend tests (push) Successful in 3m20s
Project CI / Backend tests (push) Successful in 4m1s
Project CI / Native shell tests (push) Failing after 11m56s
game agent无限画布开发 (#136)
主要工作是共享同一套“画布内核与通用 UI 源码”,网站和 Tauri 只分别实现宿主适配层。

---------

Co-authored-by: 段舒康 <kdletters@qq.com>
Co-authored-by: kdletters <kdletters@qq.com>
Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/136
Co-authored-by: menghao <mh18530625731@163.com>
Co-committed-by: menghao <mh18530625731@163.com>
2026-08-12 10:54:16 +08:00

81 lines
2.1 KiB
TypeScript

import { clamp } from './model';
import type { CanvasLayer } from './types';
export type CanvasLayerResizeHandle =
| 'left'
| 'top'
| 'right'
| 'bottom'
| 'top-left'
| 'top-right'
| 'bottom-left'
| 'bottom-right';
export type CanvasLayerTransformBounds = Pick<
CanvasLayer,
'x' | 'y' | 'width' | 'height'
>;
const MIN_LAYER_SIZE = 1;
export function resizeCanvasLayerBounds({
initial,
handle,
deltaX,
deltaY,
preserveAspectRatio,
minSize = MIN_LAYER_SIZE,
}: {
initial: CanvasLayerTransformBounds;
handle: CanvasLayerResizeHandle;
deltaX: number;
deltaY: number;
preserveAspectRatio: boolean;
minSize?: number;
}): CanvasLayerTransformBounds {
const safeMinSize = Math.max(MIN_LAYER_SIZE, minSize);
const movesLeft = handle.includes('left');
const movesRight = handle.includes('right');
const movesTop = handle.includes('top');
const movesBottom = handle.includes('bottom');
let width = initial.width + (movesRight ? deltaX : movesLeft ? -deltaX : 0);
let height = initial.height + (movesBottom ? deltaY : movesTop ? -deltaY : 0);
if (preserveAspectRatio) {
const ratio = initial.width / Math.max(initial.height, safeMinSize);
if (movesLeft || movesRight) {
height = width / Math.max(ratio, Number.EPSILON);
} else {
width = height * ratio;
}
}
width = clamp(width, safeMinSize, Number.MAX_SAFE_INTEGER);
height = clamp(height, safeMinSize, Number.MAX_SAFE_INTEGER);
return {
x: movesLeft ? initial.x + initial.width - width : initial.x,
y: movesTop ? initial.y + initial.height - height : initial.y,
width,
height,
};
}
export function transformCanvasLayers(
layers: CanvasLayer[],
transforms: ReadonlyMap<string, Partial<CanvasLayerTransformBounds>>,
) {
return layers.map((layer) => {
const transform = transforms.get(layer.id);
if (!transform || layer.locked) {
return layer;
}
return {
...layer,
x: transform.x ?? layer.x,
y: transform.y ?? layer.y,
width: Math.max(MIN_LAYER_SIZE, transform.width ?? layer.width),
height: Math.max(MIN_LAYER_SIZE, transform.height ?? layer.height),
};
});
}