Files
Genarrative/src/components/image-editor/ImageCanvasLayerPanelView.tsx
T
kdletters d8b935317d 拆分编辑器前端画布视图
抽出素材栏、生成器、舞台工具栏和画布世界视图

补充各拆分视图的聚焦测试

更新 TRACKING.md 记录第三十四阶段验证
2026-06-17 17:48:12 +08:00

91 lines
2.9 KiB
TypeScript

import type { Dispatch, SetStateAction } from 'react';
import { SidebarMediaItem } from './ImageCanvasEditorPrimitives';
import type {
CanvasContextMenuState,
CanvasLayer,
ImageContextMenuState,
} from './ImageCanvasEditorTypes';
export type ImageCanvasLayerPanelViewProps = {
layers: CanvasLayer[];
selectedLayerId: string | null;
selectedLayerIds: string[];
setImageContextMenu: Dispatch<SetStateAction<ImageContextMenuState | null>>;
setContextMenu: Dispatch<SetStateAction<CanvasContextMenuState | null>>;
selectSingleLayer: (layerId: string | null) => void;
resolveContextMenuPosition: (
clientX: number,
clientY: number,
menuKind: 'blank' | 'layer',
) => Omit<CanvasContextMenuState, 'kind' | 'layerId' | 'canvasPoint'>;
getCanvasPointFromClient: (
clientX: number,
clientY: number,
) => { x: number; y: number };
};
export function ImageCanvasLayerPanelView({
layers,
selectedLayerId,
selectedLayerIds,
setImageContextMenu,
setContextMenu,
selectSingleLayer,
resolveContextMenuPosition,
getCanvasPointFromClient,
}: ImageCanvasLayerPanelViewProps) {
return (
<div className="image-canvas-editor__layers-list">
{layers
.slice()
.sort((left, right) => right.zIndex - left.zIndex)
.map((layer) => (
<SidebarMediaItem
key={layer.id}
title={layer.title}
detail={[
`${Math.round(layer.width)} x ${Math.round(layer.height)}`,
layer.groupId ? '已打组' : null,
layer.hidden ? '已隐藏' : null,
layer.locked ? '已锁定' : null,
]
.filter(Boolean)
.join(' · ')}
imageSrc={layer.src}
imageAlt={`图层缩略图:${layer.title}`}
selected={selectedLayerId === layer.id}
primaryLabel={`选择图层${layer.title}`}
onPrimaryClick={() => selectSingleLayer(layer.id)}
rowClassName="image-canvas-editor__layer-row"
primaryClassName="image-canvas-editor__layer-row-button"
thumbnailClassName="image-canvas-editor__layer-row-thumb"
metaClassName="image-canvas-editor__layer-row-meta"
onContextMenu={(event) => {
event.preventDefault();
event.stopPropagation();
if (!selectedLayerIds.includes(layer.id)) {
selectSingleLayer(layer.id);
}
const position = resolveContextMenuPosition(
event.clientX,
event.clientY,
'layer',
);
setImageContextMenu(null);
setContextMenu({
kind: 'layer',
layerId: layer.id,
...position,
canvasPoint: getCanvasPointFromClient(
event.clientX,
event.clientY,
),
});
}}
/>
))}
</div>
);
}