Merge branch 'dev_vite' of ssh://18.167.251.121:10002/aidlab/aida_front into dev_vite

This commit is contained in:
X1627315083
2025-11-12 10:05:03 +08:00
10 changed files with 88 additions and 19 deletions

View File

@@ -528,6 +528,7 @@ export class RemoveLayerCommand extends Command {
this.layerIndex = this.layers.value.findIndex( this.layerIndex = this.layers.value.findIndex(
(layer) => layer.id === this.layerId (layer) => layer.id === this.layerId
); );
this.removedLayer = this.layers.value[this.layerIndex]; this.removedLayer = this.layers.value[this.layerIndex];
this.isActiveLayer = this.layerId === this.activeLayerId.value; this.isActiveLayer = this.layerId === this.activeLayerId.value;
@@ -593,6 +594,9 @@ export class RemoveLayerCommand extends Command {
} }
}); });
this.layerIndex = this.layers.value.findIndex(
(layer) => layer.id === this.layerId
);
// 从图层列表中删除 // 从图层列表中删除
this.layers.value.splice(this.layerIndex, 1); this.layers.value.splice(this.layerIndex, 1);

View File

@@ -321,6 +321,7 @@ export class CreateTextCommand extends Command {
this.x = options.x; this.x = options.x;
this.y = options.y; this.y = options.y;
this.textOptions = options.textOptions || {}; this.textOptions = options.textOptions || {};
this.options = options;
// 生成唯一ID // 生成唯一ID
this.textId = options?.textId || generateId("text_"); this.textId = options?.textId || generateId("text_");
this.layerId = options?.layerId || generateId("text_layer_"); this.layerId = options?.layerId || generateId("text_layer_");
@@ -331,7 +332,7 @@ export class CreateTextCommand extends Command {
// 默认文本属性 // 默认文本属性
this.defaultOptions = { this.defaultOptions = {
text: t('Canvas.DoubleClickText'), text: options.text || t('Canvas.DoubleClickText'),
fontFamily: "Arial", fontFamily: "Arial",
fontSize: 24, fontSize: 24,
fontWeight: "normal", fontWeight: "normal",
@@ -373,8 +374,8 @@ export class CreateTextCommand extends Command {
originY: "center", originY: "center",
}); });
// 创建文本图层 // 创建文本图层 取15
const layerName = this.textOptions.layerName || "文本图层"; const layerName = this.options.text?.substring(0, 25) || t('Canvas.TextLayer');
const layer = createLayer({ const layer = createLayer({
id: this.layerId, id: this.layerId,
name: layerName, name: layerName,

View File

@@ -619,10 +619,13 @@ export default {
onMounted(() => { onMounted(() => {
// 监听显示文本编辑面板事件 // 监听显示文本编辑面板事件
document.addEventListener("showTextEditor", showEditor); document.addEventListener("showTextEditor", showEditor);
document.addEventListener("hideTextEditor", close);
}); });
onUnmounted(() => { onUnmounted(() => {
document.removeEventListener("showTextEditor", showEditor); document.removeEventListener("showTextEditor", showEditor);
document.removeEventListener("hideTextEditor", close);
}); });
// 返回所有需要在模板中使用的数据和方法 // 返回所有需要在模板中使用的数据和方法

View File

@@ -303,6 +303,19 @@ onMounted(async () => {
commandManager, commandManager,
layerManager, layerManager,
toolManager, toolManager,
pasteText: (text) => {
// console.log("粘贴的文本:", text);
handleAddText(text);
},
pasteImage: (file) => {
// console.log("粘贴的图片:", file);
uploadImageAndCreateLayer({
file,
layerManager,
toolManager,
canvas: canvasManager.canvas,
});
},
}); });
// 绑定快捷键事件 // 绑定快捷键事件
@@ -786,11 +799,11 @@ function triggerLibrary() {
} }
} }
function handleAddText() { function handleAddText(text) {
if (toolManager && canvasManager && canvasManager.canvas) { if (toolManager && canvasManager && canvasManager.canvas) {
// 在画布中央创建文本 // 在画布中央创建文本
const canvasCenter = canvasManager.canvas.getCenter(); const canvasCenter = canvasManager.canvas.getCenter();
toolManager.createText(canvasCenter.left, canvasCenter.top); toolManager.createText(canvasCenter.left, canvasCenter.top, text);
} }
} }

View File

@@ -1818,7 +1818,12 @@ export class LayerManager {
// 存储到剪贴板 // 存储到剪贴板
this.clipboardData = layerCopy; 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}`); console.log(`已复制图层:${layer.name}`);
return this.clipboardData; return this.clipboardData;
@@ -1917,7 +1922,8 @@ export class LayerManager {
* 粘贴图层 * 粘贴图层
* @returns {string} 新创建的图层ID * @returns {string} 新创建的图层ID
*/ */
async pasteLayer() { async pasteLayer(event) {
console.log("剪贴板数据:", this.clipboardData,event);
if (!this.clipboardData) { if (!this.clipboardData) {
console.error("剪贴板中没有图层数据"); console.error("剪贴板中没有图层数据");
return null; return null;

View File

@@ -357,6 +357,9 @@ export class ToolManager {
this.canvasManager?.layerManager?.updateLayersObjectsInteractivity?.(); this.canvasManager?.layerManager?.updateLayersObjectsInteractivity?.();
this.canvas?.renderAll(); this.canvas?.renderAll();
// 隐藏文本编辑面板
this.hideTextEditor();
// 如果切换到非画笔工具,禁用笔刷指示器 // 如果切换到非画笔工具,禁用笔刷指示器
if (!this._shouldShowBrushIndicator(toolId)) { if (!this._shouldShowBrushIndicator(toolId)) {
this._disableBrushIndicator(); this._disableBrushIndicator();
@@ -1014,9 +1017,10 @@ export class ToolManager {
* 创建文字对象并添加到画布 * 创建文字对象并添加到画布
* @param {Number} x 文本位置x坐标 * @param {Number} x 文本位置x坐标
* @param {Number} y 文本位置y坐标 * @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.canvas || !this.layerManager) return null;
if (this.commandManager) { if (this.commandManager) {
@@ -1025,6 +1029,7 @@ export class ToolManager {
layerManager: this.layerManager, layerManager: this.layerManager,
x, x,
y, y,
text,
textOptions: options, 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.toolManager 工具管理器实例
* @param {Object} options.commandManager 命令管理器实例 * @param {Object} options.commandManager 命令管理器实例
* @param {Object} options.layerManager 图层管理器实例 * @param {Object} options.layerManager 图层管理器实例
* @param {Function} options.pasteText 粘贴文本回调函数
* @param {Function} options.pasteImage 粘贴图片回调函数
* @param {HTMLElement} options.container 容器元素,用于添加事件监听 * @param {HTMLElement} options.container 容器元素,用于添加事件监听
*/ */
constructor(options = {}) { constructor(options = {}) {
@@ -17,6 +19,8 @@ export class KeyboardManager {
this.commandManager = options.commandManager; this.commandManager = options.commandManager;
this.layerManager = options.layerManager; this.layerManager = options.layerManager;
this.container = options.container || document; this.container = options.container || document;
this.pasteText = options.pasteText || (() => {});
this.pasteImage = options.pasteImage || (() => {});
// 检测平台类型 // 检测平台类型
this.platform = this.detectPlatform(); this.platform = this.detectPlatform();
@@ -63,6 +67,7 @@ export class KeyboardManager {
// 事件绑定 // 事件绑定
this._handleKeyDown = this.handleKeyDown.bind(this); this._handleKeyDown = this.handleKeyDown.bind(this);
this._handleKeyUp = this.handleKeyUp.bind(this); this._handleKeyUp = this.handleKeyUp.bind(this);
this._handlePaste = this.handlePaste.bind(this);
this._handleTouchStart = this.handleTouchStart.bind(this); this._handleTouchStart = this.handleTouchStart.bind(this);
this._handleTouchMove = this.handleTouchMove.bind(this); this._handleTouchMove = this.handleTouchMove.bind(this);
this._handleTouchEnd = this.handleTouchEnd.bind(this); this._handleTouchEnd = this.handleTouchEnd.bind(this);
@@ -112,7 +117,7 @@ export class KeyboardManager {
// 复制/粘贴 // 复制/粘贴
[`${cmdOrCtrl}+c`]: { action: "copy", description: "复制" }, [`${cmdOrCtrl}+c`]: { action: "copy", description: "复制" },
[`${cmdOrCtrl}+v`]: { action: "paste", description: "粘贴" }, [`${cmdOrCtrl}+v`]: { action: "paste", description: "粘贴", noStop: true },
[`${cmdOrCtrl}+x`]: { action: "cut", description: "剪切" }, [`${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("keydown", this._handleKeyDown);
this.container.addEventListener("keyup", this._handleKeyUp); this.container.addEventListener("keyup", this._handleKeyUp);
this.container.addEventListener("paste", this._handlePaste);
// 如果是触摸设备,添加触摸事件监听 // 如果是触摸设备,添加触摸事件监听
if (this.isTouchDevice) { if (this.isTouchDevice) {
@@ -222,6 +250,7 @@ export class KeyboardManager {
// 移除键盘事件监听 // 移除键盘事件监听
this.container.removeEventListener("keydown", this._handleKeyDown); this.container.removeEventListener("keydown", this._handleKeyDown);
this.container.removeEventListener("keyup", this._handleKeyUp); this.container.removeEventListener("keyup", this._handleKeyUp);
this.container.removeEventListener("paste", this._handlePaste);
// 如果是触摸设备,移除触摸事件监听 // 如果是触摸设备,移除触摸事件监听
if (this.isTouchDevice) { if (this.isTouchDevice) {
@@ -251,7 +280,7 @@ export class KeyboardManager {
const shortcut = this.shortcuts[shortcutKey]; const shortcut = this.shortcuts[shortcutKey];
if (shortcut) { if (shortcut) {
// 阻止默认行为,例如浏览器的保存对话框等 // 阻止默认行为,例如浏览器的保存对话框等
if (shortcutKey.includes(`${this.modifierKeys.cmdOrCtrl}+`)) { if (shortcutKey.includes(`${this.modifierKeys.cmdOrCtrl}+`) && !shortcut.noStop) {
event.preventDefault(); event.preventDefault();
} }
@@ -701,6 +730,7 @@ export class KeyboardManager {
// 移除事件监听 // 移除事件监听
this.container.removeEventListener("keydown", this._handleKeyDown); this.container.removeEventListener("keydown", this._handleKeyDown);
this.container.removeEventListener("keyup", this._handleKeyUp); this.container.removeEventListener("keyup", this._handleKeyUp);
this.container.removeEventListener("paste", this._handlePaste);
// 如果有触摸事件,也移除它们 // 如果有触摸事件,也移除它们
if (this.isTouchDevice) { if (this.isTouchDevice) {

View File

@@ -278,14 +278,6 @@ const isShowLeft = ref(true);
<span></span> <span></span>
<div class="tool-tooltip">更换底图</div> <div class="tool-tooltip">更换底图</div>
</div> </div>
<div class="custom-tool-btn" @click="saveCanvas">
<span></span>
<div class="tool-tooltip">保存画布</div>
</div>
<div class="custom-tool-btn" @click="canvasProject">
<span></span>
<div class="tool-tooltip">读取画布</div>
</div>
<div class="custom-tool-btn" @click="exportJSON"> <div class="custom-tool-btn" @click="exportJSON">
<span></span> <span></span>
<div class="tool-tooltip">导出JSON</div> <div class="tool-tooltip">导出JSON</div>

View File

@@ -1367,6 +1367,7 @@ export default {
liquefactionEnvironment: '准备液化环境', liquefactionEnvironment: '准备液化环境',
liquefactionEnvironmentLoading: '正在准备液化环境,请稍候...', liquefactionEnvironmentLoading: '正在准备液化环境,请稍候...',
LiqueficationFailed: '液化工具启动失败', LiqueficationFailed: '液化工具启动失败',
TextLayer: '文本图层',
DoubleClickText: '双击编辑文本', DoubleClickText: '双击编辑文本',
LiquidationcuoError: '未选择有效图像或图层不适合液化操作', LiquidationcuoError: '未选择有效图像或图层不适合液化操作',
ErrorMessage: '错误提示', ErrorMessage: '错误提示',

View File

@@ -1409,6 +1409,7 @@ export default {
liquefactionEnvironmentLoading: liquefactionEnvironmentLoading:
'The liquefaction environment is being prepared. Please wait a moment...', 'The liquefaction environment is being prepared. Please wait a moment...',
LiqueficationFailed: 'Liquefication tool failed to start.', LiqueficationFailed: 'Liquefication tool failed to start.',
TextLayer: 'Text Layer',
DoubleClickText: 'Double-click to edit the text', DoubleClickText: 'Double-click to edit the text',
LiquidationError: LiquidationError:
'No valid image selected or the layer does not fit the liquefaction operation.', 'No valid image selected or the layer does not fit the liquefaction operation.',