Files
aida_front/src/component/Canvas/CanvasEditor/components/KeyboardShortcutHelp.vue
2025-11-03 16:52:43 +08:00

519 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
import { ref, inject, onMounted } from "vue";
import { Skeleton } from "ant-design-vue";
import { useI18n } from 'vue-i18n'
const {t} = useI18n()
const loading = ref(true);
const shortcuts = ref([]);
const keyboardManager = inject("keyboardManager", null);
const platform = ref({});
// 初始化键盘快捷键信息
onMounted(() => {
// 添加延迟以显示骨架屏效果
setTimeout(() => {
if (keyboardManager) {
// 使用KeyboardManager的平台检测
platform.value = {
isMac: keyboardManager.platform === "mac",
isIOS: keyboardManager.platform === "ios",
isIPad: keyboardManager.platform === "ios" && /iPad/.test(window.navigator.userAgent),
isTouchDevice: keyboardManager.isTouchDevice,
isWindows: keyboardManager.platform === "windows",
isAndroid: keyboardManager.platform === "android",
};
// 使用KeyboardManager的API获取所有快捷键
const managerShortcuts = keyboardManager.getShortcuts();
// 转换为组件所需的格式
shortcuts.value = convertShortcuts(managerShortcuts);
} else {
// 如果没有注入keyboardManager使用默认检测和默认快捷键
platform.value = detectPlatform();
shortcuts.value = generateDefaultShortcuts();
}
loading.value = false;
}, 500);
});
// 转换KeyboardManager返回的快捷键格式为组件需要的格式
function convertShortcuts(managerShortcuts) {
// 转换快捷键列表
const result = [];
// 基本的Action到显示名称的映射
const actionDisplayMap = {
undo: {
label:t('Canvas.Undo'),
value:"撤销",
},
redo: {
label:t('Canvas.Redo'),
value:"重做",
},
delete: {
label:t('Canvas.DeleteSelectedElement'),
value:"删除选中元素",
},
selectAll: {
label:"全选",
value:"全选",
},
copy: {
label:t('Canvas.Copy'),
value:"复制",
},
paste: {
label:t('Canvas.Pase'),
value:"粘贴",
},
cut: {
label:t('Canvas.Cut'),
value:"剪切",
},
save: "保存",
selectTool: "选择工具",
increaseBrushSize: {
label:t('Canvas.DecreaseBrush'),
value:"减少画笔大小",
},
decreaseBrushSize: {
label:t('Canvas.IncreaseBrush'),
value:"增加画笔大小",
},
toggleTempTool: "临时切换工具",
// newLayer: "新建图层",
// groupLayers: "组合图层",
// ungroupLayers: "取消组合",
// mergeLayers: "合并图层",
};
// 工具ID到显示名称的映射
const toolDisplayMap = {
select: {
label:t('Canvas.SelectionMode'),
value:"选择模式",
},
draw: {
label:t('Canvas.PaintingMode'),
value:"绘制模式",
},
eraser: {
label:t('Canvas.EraserMode'),
value:"橡皮擦模式",
},
// eyedropper: t('Canvas.Cut'),
// pan: '移动画布',
pan: {
label:t('Canvas.MoveCanvas'),
value:"移动画布",
},
lasso: {
label:t('Canvas.LassoTool'),
value:"套索工具",
},
// area_custom: t('Canvas.Cut'),
// wave: t('Canvas.Cut'),
liquify: {
label:t('Canvas.LiquifyTool'),
value:"液化工具",
},
};
// 处理每个快捷键
for (const shortcut of managerShortcuts) {
let actionDisplay = actionDisplayMap[shortcut.action] || shortcut.action;
// 特殊处理工具选择
if (shortcut.action === "selectTool" && shortcut.param && toolDisplayMap[shortcut.param]) {
actionDisplay = toolDisplayMap[shortcut.param];
}
result.push({
action: actionDisplay,
windows: shortcut.key.replace(/cmdOrCtrl\+/g, "Ctrl+"),
mac: shortcut.key.replace(/cmdOrCtrl\+/g, "⌘+"),
touch: shortcut.touch || t('Canvas.touchTools'),
displayKey: shortcut.displayKey,
});
}
// 添加一些组件特定的快捷键
result.push({
action: t('Canvas.ZoomCanvas'),
windows: t('Canvas.MouseWheel'),
mac: t('Canvas.MacZoomCanvas'),
touch: "双指捏合",
});
return result;
}
// 检测平台 - 作为备用
function detectPlatform() {
const userAgent = window.navigator.userAgent;
return {
isMac: /Mac/.test(userAgent),
isIOS: /iPad|iPhone|iPod/.test(userAgent) && !window.MSStream,
isIPad: /iPad/.test(userAgent),
isTouchDevice: "ontouchstart" in window || navigator.maxTouchPoints > 0,
isWindows: /Win/.test(userAgent),
isAndroid: /Android/.test(userAgent),
};
}
// 生成默认快捷键描述
function generateDefaultShortcuts() {
return [
{
action: "撤销",
windows: "Ctrl+Z",
mac: "⌘+Z",
touch: "双指向右轻扫",
},
{
action: "重做",
windows: "Ctrl+Y 或 Ctrl+Shift+Z",
mac: "⌘+Shift+Z",
touch: "双指向左轻扫",
},
{
action: "删除选中元素",
windows: "Delete 或 Backspace",
mac: "Delete 或 ⌫",
touch: "长按选中元素后点击删除",
},
// {
// action: "全选",
// windows: "Ctrl+A",
// mac: "⌘+A",
// touch: "无",
// },
{
action: "复制",
windows: "Ctrl+C",
mac: "⌘+C",
touch: "无",
},
{
action: "粘贴",
windows: "Ctrl+V",
mac: "⌘+V",
touch: "无",
},
{
action: "剪切",
windows: "Ctrl+X",
mac: "⌘+X",
touch: "无",
},
{
action: "缩放画布",
windows: "鼠标滚轮",
mac: "鼠标滚轮 或 触控板缩放手势",
touch: "双指捏合",
},
{
action: "移动画布",
windows: "Alt+拖动 或 鼠标中键拖动",
mac: "Option+拖动 或 触控板双指拖动",
touch: "双指拖动",
},
{
action: "绘画模式",
windows: "B",
mac: "B",
touch: "点击画笔工具",
},
{
action: "选择模式",
windows: "M",
mac: "M",
touch: "点击选择工具",
},
{
action: "橡皮擦模式",
windows: "E",
mac: "E",
touch: "点击橡皮擦工具",
},
// {
// action: "吸色工具",
// windows: "I",
// mac: "I",
// touch: "点击吸色工具",
// },
{
action: "增加笔触大小",
windows: "]",
mac: "]",
touch: "拖动笔刷大小滑块",
},
{
action: "减小笔触大小",
windows: "[",
mac: "[",
touch: "拖动笔刷大小滑块",
},
{
action: "增加材质图片大小",
windows: "Shift+]",
mac: "⇧+]",
touch: "拖动材质大小滑块",
},
{
action: "减小材质图片大小",
windows: "Shift+[",
mac: "⇧+[",
touch: "拖动材质大小滑块",
},
{
action: "上传图片",
windows: "Ctrl+O",
mac: "⌘+O",
touch: "点击上传按钮",
},
];
}
// 获取当前平台的快捷键文本
function getShortcutForCurrentPlatform(shortcut) {
if (platform.value.isTouchDevice) {
return shortcut.touch;
} else if (platform.value.isMac) {
return shortcut.displayKey || shortcut.mac;
} else {
return shortcut.displayKey || shortcut.windows;
}
}
// 按分类获取快捷键
function getShortcutsByCategory(category) {
const categoryMap = {
// basic: ["撤销", "重做", "全选", "复制", "粘贴", "剪切", "删除选中元素", "上传图片"],
basic: ["撤销", "重做", "复制", "粘贴", "剪切", "删除选中元素", "上传图片"],
view: ["缩放画布", "移动画布"],
tools: [
"绘画模式",
"选择模式",
"橡皮擦模式",
// "吸色工具",
"套索工具",
// "自由选区工具",
// "波浪工具",
"液化工具",
],
brush: ["增加笔触大小", "减小笔触大小", "增加材质图片大小", "减小材质图片大小"],
// layer: ["新建图层", "组合图层", "取消组合", "合并图层"],
};
return shortcuts.value.filter((s) => categoryMap[category]?.includes(s.action.value));
}
</script>
<template>
<div class="keyboard-shortcut-help">
<h2>{{ $t('Canvas.KeyboardShortcutsOperationGuide') }}</h2>
<Skeleton active :loading="loading">
<div class="platform-info">
{{$t('Canvas.TheDetectedPlatform')}}:
<span v-if="platform.isMac">MacOS</span>
<span v-else-if="platform.isWindows">Windows</span>
<span v-else-if="platform.isIPad">iPad</span>
<span v-else-if="platform.isIOS">iOS</span>
<span v-else-if="platform.isAndroid">Android</span>
<span v-else>{{ $t('Canvas.other') }}</span>
<span v-if="platform.isTouchDevice"> ({{ $t('Canvas.touchDevice') }})</span>
</div>
<div class="shortcuts-category">
<h3> {{$t('Canvas.BasicOperations')}}</h3>
<table class="shortcuts-table">
<thead>
<tr>
<th>{{$t('Canvas.BasicOperations')}}</th>
<th>{{$t('Canvas.ShortcutGesture')}}</th>
</tr>
</thead>
<tbody>
<tr v-for="item in getShortcutsByCategory('basic')" :key="item.action.label">
<td>{{ item.action.label }}</td>
<td>{{ getShortcutForCurrentPlatform(item) }}</td>
</tr>
</tbody>
</table>
</div>
<div class="shortcuts-category">
<h3>{{ $t('Canvas.viewOperations') }}</h3>
<table class="shortcuts-table">
<thead>
<tr>
<th>{{ $t('Canvas.Operation') }}</th>
<th>{{ $t('Canvas.ShortcutGesture') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="item in getShortcutsByCategory('view')" :key="item.action.label">
<td>{{ item.action.label }}</td>
<td>{{ getShortcutForCurrentPlatform(item) }}</td>
</tr>
</tbody>
</table>
</div>
<div class="shortcuts-category">
<h3>{{ $t('Canvas.toolSwitching') }}</h3>
<table class="shortcuts-table">
<thead>
<tr>
<th>{{ $t('Canvas.Operation') }}</th>
<th>{{ $t('Canvas.ShortcutGesture') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="item in getShortcutsByCategory('tools')" :key="item.action.label">
<td>{{ item.action.label }}</td>
<td>{{ getShortcutForCurrentPlatform(item) }}</td>
</tr>
</tbody>
</table>
</div>
<div class="shortcuts-category">
<h3>{{ $t('Canvas.toolSwitching') }}</h3>
<table class="shortcuts-table">
<thead>
<tr>
<th>{{ $t('Canvas.Operation') }}</th>
<th>{{ $t('Canvas.ShortcutGesture') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="item in getShortcutsByCategory('brush')" :key="item.action.label">
<td>{{ item.action.label }}</td>
<td>{{ getShortcutForCurrentPlatform(item) }}</td>
</tr>
</tbody>
</table>
</div>
<!-- <div class="shortcuts-category">
<h3>图层操作</h3>
<table class="shortcuts-table">
<thead>
<tr>
<th>操作</th>
<th>快捷键/手势</th>
</tr>
</thead>
<tbody>
<tr v-for="item in getShortcutsByCategory('layer')" :key="item.action.label">
<td>{{ item.action.label }}</td>
<td>{{ getShortcutForCurrentPlatform(item) }}</td>
</tr>
</tbody>
</table>
</div> -->
<div class="touch-tips" v-if="platform.isTouchDevice">
<h3>{{ $t('Canvas.touchDevicePrompts') }}</h3>
<ul>
<li>{{ $t('Canvas.touchDevicePrompts_1') }}</li>
<li>{{ $t('Canvas.touchDevicePrompts_2') }}</li>
<li>{{ $t('Canvas.touchDevicePrompts_3') }}</li>
<li>{{ $t('Canvas.touchDevicePrompts_4') }}</li>
<li>{{ $t('Canvas.touchDevicePrompts_5') }}</li>
<li>{{ $t('Canvas.touchDevicePrompts_6') }}</li>
</ul>
</div>
</Skeleton>
</div>
</template>
<style scoped>
.keyboard-shortcut-help {
padding: 20px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
max-width: 600px;
margin: 0 auto;
}
h2 {
margin-top: 0;
margin-bottom: 16px;
font-size: 18px;
}
h3 {
font-size: 16px;
margin-top: 20px;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid #eaeaea;
}
.platform-info {
margin-bottom: 16px;
padding: 8px;
background-color: #f0f9ff;
border-radius: 4px;
font-size: 14px;
}
.shortcuts-category {
margin-bottom: 20px;
}
.shortcuts-table {
width: 100%;
border-collapse: collapse;
}
.shortcuts-table th,
.shortcuts-table td {
border: 1px solid #eaeaea;
padding: 8px 10px;
text-align: left;
}
.shortcuts-table th {
background-color: #F9FAFA;
}
.touch-tips {
margin-top: 20px;
padding: 10px;
background-color: #fffbeb;
border-radius: 4px;
border-left: 3px solid #fbbf24;
}
.touch-tips ul {
margin: 10px 0 0;
padding-left: 20px;
}
.touch-tips li {
margin-bottom: 5px;
}
@media (pointer: coarse) {
.keyboard-shortcut-help {
padding: 15px;
}
.shortcuts-table th,
.shortcuts-table td {
padding: 12px 8px;
font-size: 15px;
}
}
</style>