拆分图片画布拖拽入画布流程
新增画布拖拽 drop workflow,承接素材库图片和本地文件拖入画布分流 补充拖拽入画布 hook 测试,覆盖遮罩、默认文件夹和无关拖拽不拦截 更新前端拆分文档和 TRACKING 浏览器回归记录
This commit is contained in:
131
src/components/image-editor/useImageCanvasCanvasDropWorkflow.ts
Normal file
131
src/components/image-editor/useImageCanvasCanvasDropWorkflow.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import {
|
||||
type DragEvent as ReactDragEvent,
|
||||
type Dispatch,
|
||||
type SetStateAction,
|
||||
useCallback,
|
||||
useMemo,
|
||||
} from 'react';
|
||||
|
||||
import {
|
||||
ASSET_DRAG_MIME_TYPE,
|
||||
getDraggedAssetId,
|
||||
hasDataTransferType,
|
||||
} from './ImageCanvasEditorModel';
|
||||
import type { EditorAsset, EditorAssetFolder } from './ImageCanvasEditorTypes';
|
||||
|
||||
type UploadFilesToCanvasOptions = {
|
||||
folderId?: string;
|
||||
canvasPoint: { x: number; y: number };
|
||||
addToCanvas: true;
|
||||
};
|
||||
|
||||
type UseImageCanvasCanvasDropWorkflowOptions = {
|
||||
assets: EditorAsset[];
|
||||
assetFolders: EditorAssetFolder[];
|
||||
setUploadDropTarget: Dispatch<SetStateAction<'canvas' | 'assets' | null>>;
|
||||
updateAssetMoveDropFolder: (folderId: string | null) => void;
|
||||
getCanvasDropPoint: (clientX: number, clientY: number) => {
|
||||
x: number;
|
||||
y: number;
|
||||
};
|
||||
addAssetLayer: (
|
||||
asset: EditorAsset,
|
||||
position?: { x: number; y: number },
|
||||
) => void;
|
||||
addUploadedFiles: (
|
||||
files: FileList | File[],
|
||||
options: UploadFilesToCanvasOptions,
|
||||
) => void;
|
||||
};
|
||||
|
||||
export function useImageCanvasCanvasDropWorkflow({
|
||||
assets,
|
||||
assetFolders,
|
||||
setUploadDropTarget,
|
||||
updateAssetMoveDropFolder,
|
||||
getCanvasDropPoint,
|
||||
addAssetLayer,
|
||||
addUploadedFiles,
|
||||
}: UseImageCanvasCanvasDropWorkflowOptions) {
|
||||
const handleCanvasDragOver = useCallback(
|
||||
(event: ReactDragEvent<HTMLDivElement>) => {
|
||||
if (hasDataTransferType(event.dataTransfer, ASSET_DRAG_MIME_TYPE)) {
|
||||
event.preventDefault();
|
||||
setUploadDropTarget('canvas');
|
||||
event.dataTransfer.dropEffect = 'copy';
|
||||
return;
|
||||
}
|
||||
if (hasDataTransferType(event.dataTransfer, 'Files')) {
|
||||
event.preventDefault();
|
||||
setUploadDropTarget('canvas');
|
||||
event.dataTransfer.dropEffect = 'copy';
|
||||
}
|
||||
},
|
||||
[setUploadDropTarget],
|
||||
);
|
||||
|
||||
const handleCanvasDragLeave = useCallback(
|
||||
(event: ReactDragEvent<HTMLDivElement>) => {
|
||||
if (!event.currentTarget.contains(event.relatedTarget as Node | null)) {
|
||||
setUploadDropTarget((currentTarget) =>
|
||||
currentTarget === 'canvas' ? null : currentTarget,
|
||||
);
|
||||
}
|
||||
},
|
||||
[setUploadDropTarget],
|
||||
);
|
||||
|
||||
const handleCanvasDrop = useCallback(
|
||||
(event: ReactDragEvent<HTMLDivElement>) => {
|
||||
const draggedAssetId = getDraggedAssetId(event.dataTransfer);
|
||||
if (draggedAssetId) {
|
||||
const draggedAsset = assets.find((asset) => asset.id === draggedAssetId);
|
||||
if (!draggedAsset) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
setUploadDropTarget(null);
|
||||
updateAssetMoveDropFolder(null);
|
||||
addAssetLayer(
|
||||
draggedAsset,
|
||||
getCanvasDropPoint(event.clientX, event.clientY),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const files = event.dataTransfer.files;
|
||||
if (!files.length) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
setUploadDropTarget(null);
|
||||
updateAssetMoveDropFolder(null);
|
||||
const canvasPoint = getCanvasDropPoint(event.clientX, event.clientY);
|
||||
const defaultFolder =
|
||||
assetFolders.find((folder) => folder.systemDefault) ?? assetFolders[0];
|
||||
addUploadedFiles(files, {
|
||||
folderId: defaultFolder?.id,
|
||||
canvasPoint,
|
||||
addToCanvas: true,
|
||||
});
|
||||
},
|
||||
[
|
||||
addAssetLayer,
|
||||
addUploadedFiles,
|
||||
assetFolders,
|
||||
assets,
|
||||
getCanvasDropPoint,
|
||||
setUploadDropTarget,
|
||||
updateAssetMoveDropFolder,
|
||||
],
|
||||
);
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
handleCanvasDragOver,
|
||||
handleCanvasDragLeave,
|
||||
handleCanvasDrop,
|
||||
}),
|
||||
[handleCanvasDragLeave, handleCanvasDragOver, handleCanvasDrop],
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user