添加画布粘贴外部文字和图片

This commit is contained in:
李志鹏
2025-11-11 17:35:00 +08:00
parent 9c6dd126e0
commit e5fc07e5e3
9 changed files with 84 additions and 19 deletions

View File

@@ -1818,7 +1818,12 @@ export class LayerManager {
// 存储到剪贴板
this.clipboardData = layerCopy;
const input = document.createElement("input");
input.value = "aida_copy_canvas_layer: " + layer.name;
document.body.appendChild(input);
input.select();
document.execCommand("copy");
document.body.removeChild(input);
console.log(`已复制图层:${layer.name}`);
return this.clipboardData;
@@ -1917,7 +1922,8 @@ export class LayerManager {
* 粘贴图层
* @returns {string} 新创建的图层ID
*/
async pasteLayer() {
async pasteLayer(event) {
console.log("剪贴板数据:", this.clipboardData,event);
if (!this.clipboardData) {
console.error("剪贴板中没有图层数据");
return null;

View File

@@ -357,6 +357,9 @@ export class ToolManager {
this.canvasManager?.layerManager?.updateLayersObjectsInteractivity?.();
this.canvas?.renderAll();
// 隐藏文本编辑面板
this.hideTextEditor();
// 如果切换到非画笔工具,禁用笔刷指示器
if (!this._shouldShowBrushIndicator(toolId)) {
this._disableBrushIndicator();
@@ -1014,9 +1017,10 @@ export class ToolManager {
* 创建文字对象并添加到画布
* @param {Number} x 文本位置x坐标
* @param {Number} y 文本位置y坐标
* @param {Object} options 文本选项
* @param {String} [text] 文本内容
* @param {Object} [options] 文本选项
*/
async createText(x, y, options = {}) {
async createText(x, y, text, options = {}) {
// 使用命令模式创建文本
if (!this.canvas || !this.layerManager) return null;
if (this.commandManager) {
@@ -1025,6 +1029,7 @@ export class ToolManager {
layerManager: this.layerManager,
x,
y,
text,
textOptions: options,
});
// 执行命令
@@ -1179,6 +1184,19 @@ export class ToolManager {
})
);
}
/**
* 隐藏文本编辑面板
*/
hideTextEditor() {
// 这个方法将在TextEditorPanel组件实现后调用
console.log("隐藏文本编辑面板");
// 将发出一个事件让Vue组件捕获并隐藏编辑面板
document.dispatchEvent(
new CustomEvent("hideTextEditor", {
detail: {},
})
);
}
/**
* 清理资源

View File

@@ -10,6 +10,8 @@ export class KeyboardManager {
* @param {Object} options.toolManager 工具管理器实例
* @param {Object} options.commandManager 命令管理器实例
* @param {Object} options.layerManager 图层管理器实例
* @param {Function} options.pasteText 粘贴文本回调函数
* @param {Function} options.pasteImage 粘贴图片回调函数
* @param {HTMLElement} options.container 容器元素,用于添加事件监听
*/
constructor(options = {}) {
@@ -17,6 +19,8 @@ export class KeyboardManager {
this.commandManager = options.commandManager;
this.layerManager = options.layerManager;
this.container = options.container || document;
this.pasteText = options.pasteText || (() => {});
this.pasteImage = options.pasteImage || (() => {});
// 检测平台类型
this.platform = this.detectPlatform();
@@ -63,6 +67,7 @@ export class KeyboardManager {
// 事件绑定
this._handleKeyDown = this.handleKeyDown.bind(this);
this._handleKeyUp = this.handleKeyUp.bind(this);
this._handlePaste = this.handlePaste.bind(this);
this._handleTouchStart = this.handleTouchStart.bind(this);
this._handleTouchMove = this.handleTouchMove.bind(this);
this._handleTouchEnd = this.handleTouchEnd.bind(this);
@@ -112,7 +117,7 @@ export class KeyboardManager {
// 复制/粘贴
[`${cmdOrCtrl}+c`]: { action: "copy", description: "复制" },
[`${cmdOrCtrl}+v`]: { action: "paste", description: "粘贴" },
[`${cmdOrCtrl}+v`]: { action: "paste", description: "粘贴", noStop: true },
[`${cmdOrCtrl}+x`]: { action: "cut", description: "剪切" },
// 删除
@@ -196,6 +201,28 @@ export class KeyboardManager {
};
}
/**
* 处理粘贴事件
* @param {ClipboardEvent} event 粘贴事件
*/
handlePaste(event) {
event.preventDefault(); // 阻止默认粘贴行为
const text = event.clipboardData?.getData("text/plain") || "";
if(/^aida_copy_canvas_layer/.test(text)) return;
const items = event.clipboardData?.items || [];
console.log(this);
for (const item of items) {
if (item.type.indexOf("text/plain") !== -1) {
item.getAsString((text) => {
this.pasteText(text);
});
} else if (item.type.indexOf("image") !== -1) {
const blob = item.getAsFile();
this.pasteImage(blob);
}
}
}
/**
* 初始化并开始监听键盘事件
*/
@@ -203,6 +230,7 @@ export class KeyboardManager {
// 添加键盘事件监听
this.container.addEventListener("keydown", this._handleKeyDown);
this.container.addEventListener("keyup", this._handleKeyUp);
this.container.addEventListener("paste", this._handlePaste);
// 如果是触摸设备,添加触摸事件监听
if (this.isTouchDevice) {
@@ -222,6 +250,7 @@ export class KeyboardManager {
// 移除键盘事件监听
this.container.removeEventListener("keydown", this._handleKeyDown);
this.container.removeEventListener("keyup", this._handleKeyUp);
this.container.removeEventListener("paste", this._handlePaste);
// 如果是触摸设备,移除触摸事件监听
if (this.isTouchDevice) {
@@ -251,7 +280,7 @@ export class KeyboardManager {
const shortcut = this.shortcuts[shortcutKey];
if (shortcut) {
// 阻止默认行为,例如浏览器的保存对话框等
if (shortcutKey.includes(`${this.modifierKeys.cmdOrCtrl}+`)) {
if (shortcutKey.includes(`${this.modifierKeys.cmdOrCtrl}+`) && !shortcut.noStop) {
event.preventDefault();
}
@@ -701,6 +730,7 @@ export class KeyboardManager {
// 移除事件监听
this.container.removeEventListener("keydown", this._handleKeyDown);
this.container.removeEventListener("keyup", this._handleKeyUp);
this.container.removeEventListener("paste", this._handlePaste);
// 如果有触摸事件,也移除它们
if (this.isTouchDevice) {