mirror of
https://github.com/AkiChase/scrcpy-mask
synced 2025-02-23 07:22:17 +08:00
feat(KeyBoard): add basic keyboard setting
This commit is contained in:
parent
31f0a4a3ca
commit
8730e47672
@ -69,7 +69,6 @@ function refreshKeyMappingButton() {
|
||||
buttons.push(keyObject);
|
||||
}
|
||||
renderedButtons.value = buttons;
|
||||
console.log(renderedButtons.value);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -104,13 +103,13 @@ function refreshKeyMappingButton() {
|
||||
>
|
||||
<div class="wheel-container">
|
||||
<i></i>
|
||||
<div>{{ button.key.up }}</div>
|
||||
<span>{{ button.key.up }}</span>
|
||||
<i></i>
|
||||
<div>{{ button.key.left }}</div>
|
||||
<div class="wheel-center"></div>
|
||||
<div>{{ button.key.right }}</div>
|
||||
<span>{{ button.key.left }}</span>
|
||||
<span class="wheel-center"></span>
|
||||
<span>{{ button.key.right }}</span>
|
||||
<i></i>
|
||||
<div>{{ button.key.down }}</div>
|
||||
<span>{{ button.key.down }}</span>
|
||||
<i></i>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,80 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import { Ref, onActivated, ref } from "vue";
|
||||
import { onBeforeRouteLeave } from "vue-router";
|
||||
import { ref } from "vue";
|
||||
import KeyInfo from "./KeyInfo.vue";
|
||||
import KeySetting from "./KeySetting.vue";
|
||||
|
||||
// TODO 4-. 读写本地配置文件,替换到global store中的curKeyMappingConfig
|
||||
// TODO 4. 右键空白区域添加按键
|
||||
// TODO 5. 左键可拖动按钮(并显示到顶部),右键按钮进行修改、删除
|
||||
|
||||
const keyboardElement = ref<HTMLElement | null>(null);
|
||||
const mouseX = ref(0);
|
||||
const mouseY = ref(0);
|
||||
|
||||
function clientxToPosx(clientx: number) {
|
||||
return clientx < 70 ? 0 : Math.floor(clientx - 70);
|
||||
}
|
||||
|
||||
function clientyToPosy(clienty: number) {
|
||||
return clienty < 30 ? 0 : Math.floor(clienty - 30);
|
||||
}
|
||||
|
||||
let ignoreMousemove = true;
|
||||
function mousemoveHandler(event: MouseEvent) {
|
||||
ignoreMousemove = !ignoreMousemove;
|
||||
if (ignoreMousemove) return;
|
||||
mouseX.value = clientxToPosx(event.clientX);
|
||||
mouseY.value = clientyToPosy(event.clientY);
|
||||
}
|
||||
|
||||
const keyboardCodeList: Ref<string[]> = ref([]);
|
||||
function keyupHandler(event: KeyboardEvent) {
|
||||
event.preventDefault();
|
||||
if (keyboardCodeList.value.length > 10) {
|
||||
keyboardCodeList.value.shift();
|
||||
keyboardCodeList.value.push(event.code);
|
||||
} else keyboardCodeList.value.push(event.code);
|
||||
}
|
||||
|
||||
function mousedownHandler(event: MouseEvent) {
|
||||
event.preventDefault();
|
||||
const key = `M${event.button}`;
|
||||
if (keyboardCodeList.value.length > 10) {
|
||||
keyboardCodeList.value.shift();
|
||||
keyboardCodeList.value.push(key);
|
||||
} else keyboardCodeList.value.push(key);
|
||||
}
|
||||
|
||||
function mouseupHandler(event: MouseEvent) {
|
||||
event.preventDefault();
|
||||
const key = `M${event.button}`;
|
||||
if (keyboardCodeList.value.length > 10) {
|
||||
keyboardCodeList.value.shift();
|
||||
keyboardCodeList.value.push(key);
|
||||
} else keyboardCodeList.value.push(key);
|
||||
}
|
||||
|
||||
onActivated(() => {
|
||||
keyboardElement.value?.addEventListener("mousemove", mousemoveHandler);
|
||||
keyboardElement.value?.addEventListener("mousedown", mousedownHandler);
|
||||
keyboardElement.value?.addEventListener("mouseup", mouseupHandler);
|
||||
document.addEventListener("keyup", keyupHandler);
|
||||
});
|
||||
|
||||
onBeforeRouteLeave(() => {
|
||||
keyboardElement.value?.removeEventListener("mousemove", mousemoveHandler);
|
||||
keyboardElement.value?.removeEventListener("mousedown", mousedownHandler);
|
||||
keyboardElement.value?.removeEventListener("mouseup", mouseupHandler);
|
||||
document.removeEventListener("keyup", keyupHandler);
|
||||
});
|
||||
const keyInfoShowFlag = ref(false);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="keyboardElement" class="keyboard" @contextmenu.prevent>
|
||||
此处最好用其他颜色的蒙版,和右侧的按键列表区同色
|
||||
<div>{{ mouseX }}, {{ mouseY }}</div>
|
||||
<div v-for="code in keyboardCodeList">
|
||||
{{ code }}
|
||||
</div>
|
||||
<div id="keyboardElement" class="keyboard">
|
||||
<KeySetting v-model="keyInfoShowFlag"/>
|
||||
<KeyInfo v-model="keyInfoShowFlag" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -83,5 +22,6 @@ onBeforeRouteLeave(() => {
|
||||
color: var(--light-color);
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
|
163
src/components/keyboard/KeyInfo.vue
Normal file
163
src/components/keyboard/KeyInfo.vue
Normal file
@ -0,0 +1,163 @@
|
||||
<script setup lang="ts">
|
||||
import { NIcon } from "naive-ui";
|
||||
import { CloseCircle } from "@vicons/ionicons5";
|
||||
import { Ref, onActivated, ref } from "vue";
|
||||
import { onBeforeRouteLeave } from "vue-router";
|
||||
|
||||
const showFlag = defineModel({ required: true });
|
||||
|
||||
const mouseX = ref(0);
|
||||
const mouseY = ref(0);
|
||||
|
||||
function clientxToPosx(clientx: number) {
|
||||
return clientx < 70 ? 0 : Math.floor(clientx - 70);
|
||||
}
|
||||
|
||||
function clientyToPosy(clienty: number) {
|
||||
return clienty < 30 ? 0 : Math.floor(clienty - 30);
|
||||
}
|
||||
|
||||
let ignoreMousemove = true;
|
||||
function mousemoveHandler(event: MouseEvent) {
|
||||
ignoreMousemove = !ignoreMousemove;
|
||||
if (ignoreMousemove) return;
|
||||
mouseX.value = clientxToPosx(event.clientX);
|
||||
mouseY.value = clientyToPosy(event.clientY);
|
||||
}
|
||||
|
||||
const keyboardCodeList: Ref<string[]> = ref([]);
|
||||
function keyupHandler(event: KeyboardEvent) {
|
||||
event.preventDefault();
|
||||
if (keyboardCodeList.value.length > 10) {
|
||||
keyboardCodeList.value.shift();
|
||||
keyboardCodeList.value.push(event.code);
|
||||
} else keyboardCodeList.value.push(event.code);
|
||||
}
|
||||
|
||||
function mousedownHandler(event: MouseEvent) {
|
||||
event.preventDefault();
|
||||
const key = `M${event.button}`;
|
||||
if (keyboardCodeList.value.length > 10) {
|
||||
keyboardCodeList.value.shift();
|
||||
keyboardCodeList.value.push(key);
|
||||
} else keyboardCodeList.value.push(key);
|
||||
}
|
||||
|
||||
onActivated(() => {
|
||||
const keyboardElement = document.getElementById("keyboardElement");
|
||||
if (keyboardElement) {
|
||||
keyboardElement.addEventListener("mousemove", mousemoveHandler);
|
||||
keyboardElement.addEventListener("mousedown", mousedownHandler);
|
||||
document.addEventListener("keyup", keyupHandler);
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeRouteLeave(() => {
|
||||
const keyboardElement = document.getElementById("keyboardElement");
|
||||
if (keyboardElement) {
|
||||
keyboardElement.removeEventListener("mousemove", mousemoveHandler);
|
||||
keyboardElement.removeEventListener("mousedown", mousedownHandler);
|
||||
document.removeEventListener("keyup", keyupHandler);
|
||||
}
|
||||
});
|
||||
|
||||
let lastPosX = 0;
|
||||
let lastPosY = 0;
|
||||
function dragHandler(downEvent: MouseEvent) {
|
||||
if (
|
||||
downEvent.target instanceof HTMLElement &&
|
||||
downEvent.target.className === "key-info-header"
|
||||
) {
|
||||
const target = downEvent.target;
|
||||
downEvent.preventDefault();
|
||||
target.style.setProperty("cursor", "grabbing");
|
||||
const element = downEvent.target.parentElement;
|
||||
const x = downEvent.clientX;
|
||||
const y = downEvent.clientY;
|
||||
const moveHandler = (moveEvent: MouseEvent) => {
|
||||
let left = lastPosX + moveEvent.clientX - x;
|
||||
let top = lastPosY + moveEvent.clientY - y;
|
||||
element?.style.setProperty("left", `${left < 0 ? 0 : left}px`);
|
||||
element?.style.setProperty("top", `${top < 0 ? 0 : top}px`);
|
||||
};
|
||||
window.addEventListener("mousemove", moveHandler);
|
||||
const upHandler = (upEvent: MouseEvent) => {
|
||||
lastPosX = lastPosX + upEvent.clientX - x;
|
||||
lastPosY = lastPosY + upEvent.clientY - y;
|
||||
window.removeEventListener("mousemove", moveHandler);
|
||||
window.removeEventListener("mouseup", upHandler);
|
||||
target.style.setProperty("cursor", "grab");
|
||||
};
|
||||
window.addEventListener("mouseup", upHandler);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-show="showFlag" class="key-info" @contextmenu.prevent>
|
||||
<div class="key-info-header" @mousedown="dragHandler">
|
||||
Key Info
|
||||
<div class="key-info-close" @click="showFlag = false">
|
||||
<NIcon><CloseCircle></CloseCircle></NIcon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="key-info-content">
|
||||
<div style="border-bottom: 1px solid var(--light-color)">
|
||||
{{ mouseX }}, {{ mouseY }}
|
||||
</div>
|
||||
<div v-if="keyboardCodeList.length === 0">Press any key</div>
|
||||
<div v-for="code in keyboardCodeList">
|
||||
{{ code }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.key-info {
|
||||
color: var(--light-color);
|
||||
background-color: var(--content-bg-color);
|
||||
width: 120px;
|
||||
border-radius: 10px;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
position: absolute;
|
||||
z-index: 8;
|
||||
|
||||
.key-info-header {
|
||||
background-color: var(--gray-color);
|
||||
color: var(--bg-color);
|
||||
font-weight: bold;
|
||||
height: 20px;
|
||||
border-radius: 10px 10px 0 0;
|
||||
text-align: center;
|
||||
cursor: grab;
|
||||
position: relative;
|
||||
|
||||
.key-info-close {
|
||||
position: absolute;
|
||||
transition: color 0.3s;
|
||||
right: 5px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--content-bg-color);
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: var(--red-color);
|
||||
}
|
||||
&:active {
|
||||
color: var(--red-pressed-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.key-info-content {
|
||||
text-align: center;
|
||||
border: 1px solid var(--gray-color);
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
123
src/components/keyboard/KeySetting.vue
Normal file
123
src/components/keyboard/KeySetting.vue
Normal file
@ -0,0 +1,123 @@
|
||||
<script setup lang="ts">
|
||||
import { Settings, CloseCircle } from "@vicons/ionicons5";
|
||||
import { NButton, NIcon, NH4, NSelect, NFlex } from "naive-ui";
|
||||
import { ref } from "vue";
|
||||
|
||||
const showKeyInfoFlag = defineModel({ required: true });
|
||||
|
||||
const showSetting = ref(false);
|
||||
const selectedKeyMappingName = ref("王者荣耀-暃");
|
||||
const KeyMappingNameOptions = ref([
|
||||
{
|
||||
label: "王者荣耀-暃",
|
||||
value: "王者荣耀-暃",
|
||||
},
|
||||
]);
|
||||
|
||||
function dragHandler(downEvent: MouseEvent) {
|
||||
const target = document.querySelector(
|
||||
".keyboard .key-setting-btn"
|
||||
) as HTMLElement;
|
||||
downEvent.preventDefault();
|
||||
const x = downEvent.clientX;
|
||||
const y = downEvent.clientY;
|
||||
|
||||
let moveFlag = false;
|
||||
let lastPosX = 100;
|
||||
let lastPosY = 100;
|
||||
const moveHandler = (moveEvent: MouseEvent) => {
|
||||
let right = lastPosX + x - moveEvent.clientX;
|
||||
let bottom = lastPosY + y - moveEvent.clientY;
|
||||
target.style.setProperty("right", `${right < 0 ? 0 : right}px`);
|
||||
target.style.setProperty("bottom", `${bottom < 0 ? 0 : bottom}px`);
|
||||
};
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
moveFlag = true;
|
||||
target.style.setProperty("cursor", "grabbing");
|
||||
window.addEventListener("mousemove", moveHandler);
|
||||
}, 1000);
|
||||
|
||||
const upHandler = (upEvent: MouseEvent) => {
|
||||
clearTimeout(timer);
|
||||
window.removeEventListener("mousemove", moveHandler);
|
||||
window.removeEventListener("mouseup", upHandler);
|
||||
if (moveFlag) {
|
||||
lastPosX = lastPosX + x - upEvent.clientX;
|
||||
lastPosY = lastPosY + y - upEvent.clientY;
|
||||
target.style.setProperty("cursor", "pointer");
|
||||
} else {
|
||||
showSetting.value = !showSetting.value;
|
||||
}
|
||||
};
|
||||
window.addEventListener("mouseup", upHandler);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NButton
|
||||
circle
|
||||
type="info"
|
||||
size="large"
|
||||
class="key-setting-btn"
|
||||
@mousedown="dragHandler"
|
||||
>
|
||||
<template #icon>
|
||||
<NIcon><Settings /></NIcon>
|
||||
</template>
|
||||
</NButton>
|
||||
<div class="key-setting" v-show="showSetting">
|
||||
<NButton text class="key-setting-close" @click="showSetting = false">
|
||||
<NIcon><CloseCircle></CloseCircle></NIcon>
|
||||
</NButton>
|
||||
<NH4 prefix="bar">按键方案</NH4>
|
||||
<NSelect
|
||||
v-model:value="selectedKeyMappingName"
|
||||
:options="KeyMappingNameOptions"
|
||||
/>
|
||||
<NFlex style="margin-top: 20px">
|
||||
<NButton>新建方案</NButton>
|
||||
<NButton>复制方案</NButton>
|
||||
<NButton>删除方案</NButton>
|
||||
<NButton>重命名</NButton>
|
||||
</NFlex>
|
||||
<NH4 prefix="bar">其他</NH4>
|
||||
<NFlex>
|
||||
<NButton>导入</NButton>
|
||||
<NButton>导出</NButton>
|
||||
<NButton @click="showKeyInfoFlag = !showKeyInfoFlag">按键信息</NButton>
|
||||
</NFlex>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.key-setting-btn {
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
right: 100px;
|
||||
bottom: 100px;
|
||||
}
|
||||
|
||||
.key-setting {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 70%;
|
||||
height: 70%;
|
||||
margin: auto;
|
||||
background-color: var(--content-bg-color);
|
||||
padding: 0 50px;
|
||||
border: 1px solid var(--gray-color);
|
||||
border-radius: 10px;
|
||||
z-index: 10;
|
||||
|
||||
.key-setting-close {
|
||||
font-size: 24px;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -10,6 +10,8 @@
|
||||
--gray-color: #6b6e76;
|
||||
--red-color: #fc5185;
|
||||
--red-pressed-color: #f4336d;
|
||||
--blue-color: #70C0E8;
|
||||
--blue-pressed-color: #66AFD3;
|
||||
}
|
||||
|
||||
html,
|
||||
|
Loading…
Reference in New Issue
Block a user