ad72e4691c
生成视频结果写入编辑器资源和素材库,并返回视频素材快照 上传视频使用真实视频尺寸创建素材和画布图层 素材库视频卡片使用签名地址渲染首帧预览并显示视频标签 剪贴板图片粘贴重新接入系统粘贴和右键粘贴路径 多选图层拖拽保留已有选区并批量移动 图标规范引用支持对象存储资源和素材引用,不再要求 Data URL 音效和背景音乐生成失败展示上游详细原因
88 lines
2.5 KiB
TypeScript
88 lines
2.5 KiB
TypeScript
import type {
|
|
CanvasGenerationDialogState,
|
|
CanvasLayer,
|
|
} from './ImageCanvasEditorTypes';
|
|
|
|
export const CANVAS_GENERATION_SELECTION_PREFIX = 'generation-dialog:';
|
|
|
|
export function getCanvasGenerationSelectionId(dialogId: string) {
|
|
return `${CANVAS_GENERATION_SELECTION_PREFIX}${dialogId}`;
|
|
}
|
|
|
|
export function getCanvasGenerationDialogIdFromSelectionId(targetId: string) {
|
|
return targetId.startsWith(CANVAS_GENERATION_SELECTION_PREFIX)
|
|
? targetId.slice(CANVAS_GENERATION_SELECTION_PREFIX.length)
|
|
: null;
|
|
}
|
|
|
|
export function isCanvasGenerationSelectionId(targetId: string) {
|
|
return getCanvasGenerationDialogIdFromSelectionId(targetId) !== null;
|
|
}
|
|
|
|
export function getSelectedLayerIds(selectionIds: string[]) {
|
|
return selectionIds.filter(
|
|
(selectionId) => !isCanvasGenerationSelectionId(selectionId),
|
|
);
|
|
}
|
|
|
|
export function getSelectedGenerationDialogIds(selectionIds: string[]) {
|
|
return selectionIds.flatMap((selectionId) => {
|
|
const dialogId = getCanvasGenerationDialogIdFromSelectionId(selectionId);
|
|
return dialogId ? [dialogId] : [];
|
|
});
|
|
}
|
|
|
|
export function dedupeSelectionIds(selectionIds: string[]) {
|
|
return Array.from(new Set(selectionIds));
|
|
}
|
|
|
|
export function firstSelectedLayerId(selectionIds: string[]) {
|
|
return getSelectedLayerIds(selectionIds)[0] ?? null;
|
|
}
|
|
|
|
export function normalizeCanvasSelectionIds({
|
|
selectionIds,
|
|
layers,
|
|
generationDialogs,
|
|
}: {
|
|
selectionIds: string[];
|
|
layers: CanvasLayer[];
|
|
generationDialogs: CanvasGenerationDialogState[];
|
|
}) {
|
|
const layerIds = new Set(layers.map((layer) => layer.id));
|
|
const generationDialogIds = new Set(
|
|
generationDialogs.map((dialog) => dialog.id),
|
|
);
|
|
return dedupeSelectionIds(selectionIds).filter((selectionId) => {
|
|
if (isCanvasGenerationSelectionId(selectionId)) {
|
|
const dialogId = getCanvasGenerationDialogIdFromSelectionId(selectionId);
|
|
return Boolean(dialogId && generationDialogIds.has(dialogId));
|
|
}
|
|
return layerIds.has(selectionId);
|
|
});
|
|
}
|
|
|
|
export function resolvePointerSelection({
|
|
targetId,
|
|
selectedIds,
|
|
isMultiSelectGesture,
|
|
}: {
|
|
targetId: string;
|
|
selectedIds: string[];
|
|
isMultiSelectGesture: boolean;
|
|
}) {
|
|
if (!isMultiSelectGesture) {
|
|
if (selectedIds.includes(targetId)) {
|
|
return selectedIds;
|
|
}
|
|
return [targetId];
|
|
}
|
|
if (!selectedIds.includes(targetId)) {
|
|
return [...selectedIds, targetId];
|
|
}
|
|
if (selectedIds.length <= 1) {
|
|
return [targetId];
|
|
}
|
|
return selectedIds.filter((selectedId) => selectedId !== targetId);
|
|
}
|