Files
aida_front/src/component/Canvas/CanvasEditor/components/KeyboardShortcutHelp.vue

519 lines
13 KiB
Vue
Raw Normal View History

2025-06-09 10:25:54 +08:00
<script setup>
import { ref, inject, onMounted } from "vue";
import { Skeleton } from "ant-design-vue";
2025-07-20 18:19:34 +08:00
import { useI18n } from 'vue-i18n'
const {t} = useI18n()
2025-06-09 10:25:54 +08:00
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),
2025-06-09 10:25:54 +08:00
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 = {
2025-07-20 20:27:13 +08:00
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: "保存",
2025-06-09 10:25:54 +08:00
selectTool: "选择工具",
2025-07-20 20:27:13 +08:00
increaseBrushSize: {
label:t('Canvas.DecreaseBrush'),
value:"减少画笔大小",
},
decreaseBrushSize: {
label:t('Canvas.IncreaseBrush'),
value:"增加画笔大小",
},
2025-06-09 10:25:54 +08:00
toggleTempTool: "临时切换工具",
// newLayer: "新建图层",
// groupLayers: "组合图层",
// ungroupLayers: "取消组合",
// mergeLayers: "合并图层",
2025-06-09 10:25:54 +08:00
};
// 工具ID到显示名称的映射
const toolDisplayMap = {
2025-07-20 20:27:13 +08:00
select: {
label:t('Canvas.SelectionMode'),
value:"选择模式",
},
draw: {
label:t('Canvas.PaintingMode'),
value:"绘制模式",
},
eraser: {
label:t('Canvas.EraserMode'),
value:"橡皮擦模式",
},
2025-07-20 18:19:34 +08:00
// eyedropper: t('Canvas.Cut'),
2025-07-20 20:27:13 +08:00
// pan: '移动画布',
pan: {
label:t('Canvas.MoveCanvas'),
value:"移动画布",
},
lasso: {
label:t('Canvas.LassoTool'),
value:"套索工具",
},
2025-07-20 18:19:34 +08:00
// area_custom: t('Canvas.Cut'),
// wave: t('Canvas.Cut'),
2025-07-20 20:27:13 +08:00
liquify: {
label:t('Canvas.LiquifyTool'),
value:"液化工具",
},
2025-06-09 10:25:54 +08:00
};
// 处理每个快捷键
for (const shortcut of managerShortcuts) {
let actionDisplay = actionDisplayMap[shortcut.action] || shortcut.action;
// 特殊处理工具选择
if (shortcut.action === "selectTool" && shortcut.param && toolDisplayMap[shortcut.param]) {
2025-06-09 10:25:54 +08:00
actionDisplay = toolDisplayMap[shortcut.param];
}
result.push({
action: actionDisplay,
windows: shortcut.key.replace(/cmdOrCtrl\+/g, "Ctrl+"),
mac: shortcut.key.replace(/cmdOrCtrl\+/g, "⌘+"),
2025-09-24 16:26:40 +08:00
touch: shortcut.touch || t('Canvas.touchTools'),
2025-06-09 10:25:54 +08:00
displayKey: shortcut.displayKey,
});
}
// 添加一些组件特定的快捷键
result.push({
2025-07-20 18:19:34 +08:00
action: t('Canvas.ZoomCanvas'),
windows: t('Canvas.MouseWheel'),
mac: t('Canvas.MacZoomCanvas'),
2025-06-09 10:25:54 +08:00
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: "无",
// },
2025-06-09 10:25:54 +08:00
{
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: "点击吸色工具",
// },
2025-06-09 10:25:54 +08:00
{
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: ["撤销", "重做", "复制", "粘贴", "剪切", "删除选中元素", "上传图片"],
2025-06-09 10:25:54 +08:00
view: ["缩放画布", "移动画布"],
tools: [
"绘画模式",
"选择模式",
"橡皮擦模式",
// "吸色工具",
2025-06-09 10:25:54 +08:00
"套索工具",
// "自由选区工具",
// "波浪工具",
2025-06-09 10:25:54 +08:00
"液化工具",
],
brush: ["增加笔触大小", "减小笔触大小", "增加材质图片大小", "减小材质图片大小"],
// layer: ["新建图层", "组合图层", "取消组合", "合并图层"],
2025-06-09 10:25:54 +08:00
};
2025-07-20 20:27:13 +08:00
return shortcuts.value.filter((s) => categoryMap[category]?.includes(s.action.value));
2025-06-09 10:25:54 +08:00
}
</script>
<template>
<div class="keyboard-shortcut-help">
2025-07-20 18:19:34 +08:00
<h2>{{ $t('Canvas.KeyboardShortcutsOperationGuide') }}</h2>
2025-06-09 10:25:54 +08:00
<Skeleton active :loading="loading">
<div class="platform-info">
2025-07-20 18:19:34 +08:00
{{$t('Canvas.TheDetectedPlatform')}}:
2025-06-09 10:25:54 +08:00
<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>
2025-09-24 16:26:40 +08:00
<span v-else>{{ $t('Canvas.other') }}</span>
<span v-if="platform.isTouchDevice"> ({{ $t('Canvas.touchDevice') }})</span>
2025-06-09 10:25:54 +08:00
</div>
<div class="shortcuts-category">
2025-07-20 18:19:34 +08:00
<h3> {{$t('Canvas.BasicOperations')}}</h3>
2025-06-09 10:25:54 +08:00
<table class="shortcuts-table">
<thead>
<tr>
2025-07-20 18:19:34 +08:00
<th>{{$t('Canvas.BasicOperations')}}</th>
<th>{{$t('Canvas.ShortcutGesture')}}</th>
2025-06-09 10:25:54 +08:00
</tr>
</thead>
<tbody>
2025-07-20 20:27:13 +08:00
<tr v-for="item in getShortcutsByCategory('basic')" :key="item.action.label">
<td>{{ item.action.label }}</td>
2025-06-09 10:25:54 +08:00
<td>{{ getShortcutForCurrentPlatform(item) }}</td>
</tr>
</tbody>
</table>
</div>
<div class="shortcuts-category">
2025-07-20 18:19:34 +08:00
<h3>{{ $t('Canvas.viewOperations') }}</h3>
2025-06-09 10:25:54 +08:00
<table class="shortcuts-table">
<thead>
<tr>
2025-07-20 18:19:34 +08:00
<th>{{ $t('Canvas.Operation') }}</th>
<th>{{ $t('Canvas.ShortcutGesture') }}</th>
2025-06-09 10:25:54 +08:00
</tr>
</thead>
<tbody>
2025-07-20 20:27:13 +08:00
<tr v-for="item in getShortcutsByCategory('view')" :key="item.action.label">
<td>{{ item.action.label }}</td>
2025-06-09 10:25:54 +08:00
<td>{{ getShortcutForCurrentPlatform(item) }}</td>
</tr>
</tbody>
</table>
</div>
<div class="shortcuts-category">
2025-07-20 18:19:34 +08:00
<h3>{{ $t('Canvas.toolSwitching') }}</h3>
2025-06-09 10:25:54 +08:00
<table class="shortcuts-table">
<thead>
<tr>
2025-07-20 18:19:34 +08:00
<th>{{ $t('Canvas.Operation') }}</th>
<th>{{ $t('Canvas.ShortcutGesture') }}</th>
2025-06-09 10:25:54 +08:00
</tr>
</thead>
<tbody>
2025-07-20 20:27:13 +08:00
<tr v-for="item in getShortcutsByCategory('tools')" :key="item.action.label">
<td>{{ item.action.label }}</td>
2025-06-09 10:25:54 +08:00
<td>{{ getShortcutForCurrentPlatform(item) }}</td>
</tr>
</tbody>
</table>
</div>
<div class="shortcuts-category">
2025-07-20 18:19:34 +08:00
<h3>{{ $t('Canvas.toolSwitching') }}</h3>
2025-06-09 10:25:54 +08:00
<table class="shortcuts-table">
<thead>
<tr>
2025-07-20 18:19:34 +08:00
<th>{{ $t('Canvas.Operation') }}</th>
<th>{{ $t('Canvas.ShortcutGesture') }}</th>
2025-06-09 10:25:54 +08:00
</tr>
</thead>
<tbody>
2025-07-20 20:27:13 +08:00
<tr v-for="item in getShortcutsByCategory('brush')" :key="item.action.label">
<td>{{ item.action.label }}</td>
2025-06-09 10:25:54 +08:00
<td>{{ getShortcutForCurrentPlatform(item) }}</td>
</tr>
</tbody>
</table>
</div>
<!-- <div class="shortcuts-category">
2025-06-09 10:25:54 +08:00
<h3>图层操作</h3>
<table class="shortcuts-table">
<thead>
<tr>
<th>操作</th>
<th>快捷键/手势</th>
</tr>
</thead>
<tbody>
2025-07-20 20:27:13 +08:00
<tr v-for="item in getShortcutsByCategory('layer')" :key="item.action.label">
<td>{{ item.action.label }}</td>
2025-06-09 10:25:54 +08:00
<td>{{ getShortcutForCurrentPlatform(item) }}</td>
</tr>
</tbody>
</table>
</div> -->
2025-06-09 10:25:54 +08:00
<div class="touch-tips" v-if="platform.isTouchDevice">
2025-09-24 16:26:40 +08:00
<h3>{{ $t('Canvas.touchDevicePrompts') }}</h3>
2025-06-09 10:25:54 +08:00
<ul>
2025-09-24 16:26:40 +08:00
<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>
2025-06-09 10:25:54 +08:00
</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 {
2025-11-03 16:52:43 +08:00
background-color: #F9FAFA;
2025-06-09 10:25:54 +08:00
}
.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>