Skip to content

Commit 0a009b1

Browse files
committed
feat: 增加图片拖拽进入舞台的功能
1 parent cf1a6e8 commit 0a009b1

File tree

2 files changed

+93
-29
lines changed

2 files changed

+93
-29
lines changed

app/src/App.tsx

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import { toast } from "sonner";
2121
import { URI } from "vscode-uri";
2222
import { cn } from "./utils/cn";
2323
import { isWindows } from "./utils/platform";
24+
import { DragFileIntoStageEngine } from "./core/service/dataManageService/dragFileIntoStageEngine/dragFileIntoStageEngine";
25+
import { Vector } from "@graphif/data-structures";
2426

2527
export default function App() {
2628
const [maximized, _setMaximized] = useState(false);
@@ -100,34 +102,6 @@ export default function App() {
100102
}
101103
setIsWide(window.innerWidth / window.innerHeight > 1.8);
102104
});
103-
const unlisten2 = getCurrentWindow().onDragDropEvent((event) => {
104-
if (event.payload.type === "over") {
105-
if (event.payload.position.y <= 96) {
106-
// 拖拽到标签页栏区域
107-
setDropState("open");
108-
} else {
109-
// 拖拽到画布区域
110-
setDropState("append");
111-
}
112-
} else if (event.payload.type === "leave") {
113-
setDropState("none");
114-
} else if (event.payload.type === "drop") {
115-
setDropState("none");
116-
if (event.payload.position.y <= 96) {
117-
// 拖拽到标签页栏区域
118-
for (const path of event.payload.paths) {
119-
if (path.endsWith(".prg") || path.endsWith(".json")) {
120-
onOpenFile(URI.file(path), "拖入窗口");
121-
} else {
122-
toast.error("不支持打开此文件");
123-
}
124-
}
125-
} else {
126-
// 拖拽到画布区域
127-
toast("追加到画布……待完善");
128-
}
129-
}
130-
});
131105

132106
if (!telemetryEventSent) {
133107
setTelemetryEventSent(true);
@@ -153,7 +127,6 @@ export default function App() {
153127

154128
return () => {
155129
unlisten1?.then((f) => f());
156-
unlisten2?.then((f) => f());
157130
};
158131
}, []);
159132

@@ -186,6 +159,43 @@ export default function App() {
186159
activeProject.canvas.element.addEventListener("pointerup", () => {
187160
setIgnoreMouseEvents(false);
188161
});
162+
const unlisten2 = getCurrentWindow().onDragDropEvent((event) => {
163+
if (event.payload.type === "over") {
164+
if (event.payload.position.y <= 96) {
165+
// 拖拽到标签页栏区域
166+
setDropState("open");
167+
} else {
168+
// 拖拽到画布区域
169+
setDropState("append");
170+
}
171+
} else if (event.payload.type === "leave") {
172+
setDropState("none");
173+
} else if (event.payload.type === "drop") {
174+
setDropState("none");
175+
if (event.payload.position.y <= 96) {
176+
// 拖拽到标签页栏区域
177+
for (const path of event.payload.paths) {
178+
if (path.endsWith(".prg") || path.endsWith(".json")) {
179+
onOpenFile(URI.file(path), "拖入窗口");
180+
} else {
181+
toast.error("不支持打开此文件");
182+
}
183+
}
184+
} else {
185+
// 拖拽到画布区域
186+
toast("追加到画布……待完善");
187+
// console.log(activeProject, event.payload.paths);
188+
DragFileIntoStageEngine.handleDrop(
189+
activeProject,
190+
event.payload.paths,
191+
new Vector(event.payload.position.x, event.payload.position.y),
192+
);
193+
}
194+
}
195+
});
196+
return () => {
197+
unlisten2?.then((f) => f());
198+
};
189199
}, [activeProject]);
190200

191201
useEffect(() => {
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { Project } from "@/core/Project";
2+
import { Vector } from "@graphif/data-structures";
3+
import { readFile } from "@tauri-apps/plugin-fs";
4+
import { CollisionBox } from "@/core/stage/stageObject/collisionBox/collisionBox";
5+
import { ImageNode } from "@/core/stage/stageObject/entity/ImageNode";
6+
import { Rectangle } from "@graphif/shapes";
7+
8+
/**
9+
* 处理文件拖拽到舞台的引擎
10+
*/
11+
export namespace DragFileIntoStageEngine {
12+
/**
13+
* 处理文件拖拽到舞台
14+
* @param project 当前活动的项目
15+
* @param pathList 拖拽的文件路径列表
16+
* @param mouseLocation 拖拽到的位置(舞台坐标系)
17+
*/
18+
export async function handleDrop(project: Project, pathList: string[], mouseLocation: Vector) {
19+
try {
20+
for (const filePath of pathList) {
21+
// 检查文件是否为PNG格式
22+
if (!filePath.toLowerCase().endsWith(".png")) {
23+
console.warn(`不支持的文件格式: ${filePath}`);
24+
continue;
25+
}
26+
27+
// 使用Tauri的文件系统API读取文件内容
28+
const fileData = await readFile(filePath);
29+
console.log(`读取文件成功: ${filePath}, 大小: ${fileData.length} bytes`);
30+
31+
// 创建Blob对象
32+
const blob = new Blob([fileData], { type: "image/png" });
33+
console.log(`创建Blob成功: ${blob.size} bytes, type: ${blob.type}`);
34+
35+
// 添加到项目的attachments中
36+
const attachmentId = project.addAttachment(blob);
37+
console.log(`添加附件成功, ID: ${attachmentId}`);
38+
39+
// 创建ImageNode并添加到舞台
40+
const imageNode = new ImageNode(project, {
41+
attachmentId,
42+
collisionBox: new CollisionBox([
43+
new Rectangle(project.renderer.transformView2World(mouseLocation), new Vector(300, 150)),
44+
]),
45+
});
46+
47+
project.stageManager.add(imageNode);
48+
console.log(`创建ImageNode成功并添加到舞台, UUID: ${imageNode.uuid}`);
49+
}
50+
} catch (error) {
51+
console.error(`处理拖拽文件失败: ${error instanceof Error ? error.message : String(error)}`);
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)