7c449f0596
使用用户提供的透明 PNG 替换自绘 SVG 音频封面 统一后台素材查询、精选审核、创作主页和画板素材库的音频封面引用 补齐画板图层列表音频图层封面展示 更新相关测试覆盖
98 lines
3.2 KiB
TypeScript
98 lines
3.2 KiB
TypeScript
import type { Dispatch, SetStateAction } from 'react';
|
|
|
|
import { SidebarMediaItem } from './ImageCanvasEditorPrimitives';
|
|
import type {
|
|
CanvasContextMenuState,
|
|
CanvasLayer,
|
|
ImageContextMenuState,
|
|
} from './ImageCanvasEditorTypes';
|
|
|
|
const AUDIO_ASSET_COVER_SRC = '/creation-home/audio-asset-cover.png';
|
|
|
|
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.mediaType === 'audio' ? AUDIO_ASSET_COVER_SRC : layer.src
|
|
}
|
|
objectKey={
|
|
layer.mediaType === 'image' ? layer.objectKey : undefined
|
|
}
|
|
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>
|
|
);
|
|
}
|