合并图片画布素材分支
将 codex/editor-asset-library 合并到 dev-jenken 保留编辑器生成规范、角色形象和图标素材能力 补回画布布局轻量保存和小地图拖拽手感修复
This commit is contained in:
@@ -305,6 +305,11 @@ type DragState =
|
||||
| {
|
||||
kind: 'minimap';
|
||||
pointerId: number;
|
||||
startClientX: number;
|
||||
startClientY: number;
|
||||
startViewport: CanvasViewport;
|
||||
minimapScale: number;
|
||||
moved: boolean;
|
||||
};
|
||||
|
||||
const EDITOR_ASSETS: EditorAsset[] = [
|
||||
@@ -416,6 +421,7 @@ const SNAP_THRESHOLD_SCREEN_PX = 18;
|
||||
const FIT_VIEW_PADDING = 10;
|
||||
const MINIMAP_SIZE = { width: 132, height: 84 };
|
||||
const MINIMAP_PADDING = 8;
|
||||
const MINIMAP_DRAG_SENSITIVITY = 0.3;
|
||||
const SPEC_GENERATION_COST = 5;
|
||||
const SPEC_GENERATION_SIZE = '2048x1152';
|
||||
const SPEC_FRAME_ORIGINAL_SIZE = { width: 2048, height: 1152 };
|
||||
@@ -601,7 +607,6 @@ function serializeLayer(layer: CanvasLayer): EditorProjectLayerSnapshot {
|
||||
layerId: layer.id,
|
||||
resourceId: layer.resourceId,
|
||||
title: layer.title,
|
||||
src: layer.src,
|
||||
x: layer.x,
|
||||
y: layer.y,
|
||||
width: layer.width,
|
||||
@@ -625,11 +630,13 @@ function serializeLayer(layer: CanvasLayer): EditorProjectLayerSnapshot {
|
||||
|
||||
function hydrateLayer(
|
||||
snapshot: EditorProjectLayerSnapshot,
|
||||
resourcesById: Map<string, { imageSrc: string }>,
|
||||
): CanvasLayer | null {
|
||||
const resourceId =
|
||||
typeof snapshot.resourceId === 'string' ? snapshot.resourceId : '';
|
||||
const layerId = typeof snapshot.layerId === 'string' ? snapshot.layerId : '';
|
||||
const src = typeof snapshot.src === 'string' ? snapshot.src : '';
|
||||
const snapshotSrc = typeof snapshot.src === 'string' ? snapshot.src : '';
|
||||
const src = snapshotSrc || resourcesById.get(resourceId)?.imageSrc || '';
|
||||
const title =
|
||||
typeof snapshot.title === 'string' ? snapshot.title : '画布图片';
|
||||
if (!resourceId || !layerId || !src) {
|
||||
@@ -1543,8 +1550,14 @@ export function ImageCanvasEditorView() {
|
||||
createProjectResourceForLayer(layer, options);
|
||||
});
|
||||
setViewport(project.viewport);
|
||||
const resourcesById = new Map(
|
||||
project.resources.map((resource) => [
|
||||
resource.resourceId,
|
||||
{ imageSrc: resource.imageSrc },
|
||||
]),
|
||||
);
|
||||
const hydratedLayers = project.layers
|
||||
.map(hydrateLayer)
|
||||
.map((layer) => hydrateLayer(layer, resourcesById))
|
||||
.filter((layer): layer is CanvasLayer => Boolean(layer));
|
||||
if (hydratedLayers.length > 0) {
|
||||
layerCounterRef.current = hydratedLayers.length;
|
||||
@@ -3367,6 +3380,28 @@ export function ImageCanvasEditorView() {
|
||||
}));
|
||||
};
|
||||
|
||||
const moveViewportFromMinimapDrag = (
|
||||
dragState: Extract<DragState, { kind: 'minimap' }>,
|
||||
clientX: number,
|
||||
clientY: number,
|
||||
) => {
|
||||
const deltaWorldX =
|
||||
((clientX - dragState.startClientX) / dragState.minimapScale) *
|
||||
MINIMAP_DRAG_SENSITIVITY;
|
||||
const deltaWorldY =
|
||||
((clientY - dragState.startClientY) / dragState.minimapScale) *
|
||||
MINIMAP_DRAG_SENSITIVITY;
|
||||
setViewport({
|
||||
...dragState.startViewport,
|
||||
x:
|
||||
dragState.startViewport.x -
|
||||
deltaWorldX * dragState.startViewport.scale,
|
||||
y:
|
||||
dragState.startViewport.y -
|
||||
deltaWorldY * dragState.startViewport.scale,
|
||||
});
|
||||
};
|
||||
|
||||
const handleMinimapPointerDown = (
|
||||
event: ReactPointerEvent<HTMLButtonElement>,
|
||||
) => {
|
||||
@@ -3377,8 +3412,12 @@ export function ImageCanvasEditorView() {
|
||||
dragStateRef.current = {
|
||||
kind: 'minimap',
|
||||
pointerId: getPointerId(event),
|
||||
startClientX: pointer.x,
|
||||
startClientY: pointer.y,
|
||||
startViewport: { ...viewport },
|
||||
minimapScale: minimapModel?.scale ?? 1,
|
||||
moved: false,
|
||||
};
|
||||
moveViewportFromMinimapPointer(pointer.x, pointer.y);
|
||||
};
|
||||
|
||||
const handlePointerMove = (event: ReactPointerEvent<HTMLDivElement>) => {
|
||||
@@ -3463,7 +3502,14 @@ export function ImageCanvasEditorView() {
|
||||
|
||||
if (dragState.kind === 'minimap') {
|
||||
const pointer = getPointerClient(event);
|
||||
moveViewportFromMinimapPointer(pointer.x, pointer.y);
|
||||
const deltaX = pointer.x - dragState.startClientX;
|
||||
const deltaY = pointer.y - dragState.startClientY;
|
||||
if (!dragState.moved && Math.hypot(deltaX, deltaY) >= 2) {
|
||||
dragState.moved = true;
|
||||
}
|
||||
if (dragState.moved) {
|
||||
moveViewportFromMinimapDrag(dragState, pointer.x, pointer.y);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3534,6 +3580,10 @@ export function ImageCanvasEditorView() {
|
||||
pointerId < 0 ||
|
||||
dragState.pointerId === pointerId)
|
||||
) {
|
||||
if (dragState.kind === 'minimap' && !dragState.moved) {
|
||||
const pointer = getPointerClient(event);
|
||||
moveViewportFromMinimapPointer(pointer.x, pointer.y);
|
||||
}
|
||||
dragStateRef.current = null;
|
||||
setIsPanning(false);
|
||||
setSnapGuide(null);
|
||||
|
||||
Reference in New Issue
Block a user