feat(mask): render buttons on the mask

This commit is contained in:
AkiChase 2024-04-25 22:48:05 +08:00
parent 2cc8b5b30a
commit 31f0a4a3ca
4 changed files with 112 additions and 12 deletions

View File

@ -190,6 +190,12 @@ async function onMenuSelect(key: string) {
return; return;
} }
if (store.controledDevice) {
message.error("请先关闭当前控制设备");
store.hideLoading();
return;
}
localStore.set("screenSize", { localStore.set("screenSize", {
sizeW: store.screenSizeW, sizeW: store.screenSizeW,
sizeH: store.screenSizeH, sizeH: store.screenSizeH,
@ -309,7 +315,7 @@ async function refreshDevices() {
</div> </div>
</div> </div>
<NFlex justify="space-between" align="center"> <NFlex justify="space-between" align="center">
<NH4 prefix="bar">可用设备</NH4> <NH4 style="margin: 20px 0" prefix="bar">可用设备</NH4>
<NButton <NButton
tertiary tertiary
circle circle

View File

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { onActivated, ref } from "vue"; import { Ref, onActivated, ref } from "vue";
import { NDialog } from "naive-ui"; import { NDialog } from "naive-ui";
import { useGlobalStore } from "../store/global"; import { useGlobalStore } from "../store/global";
import { onBeforeRouteLeave, useRouter } from "vue-router"; import { onBeforeRouteLeave, useRouter } from "vue-router";
@ -17,6 +17,8 @@ const maskRef = ref<HTMLElement | null>(null);
const store = useGlobalStore(); const store = useGlobalStore();
const router = useRouter(); const router = useRouter();
const renderedButtons: Ref<any[]> = ref([]);
onBeforeRouteLeave(() => { onBeforeRouteLeave(() => {
if (maskRef.value && store.controledDevice) { if (maskRef.value && store.controledDevice) {
unlistenToKeyEvent(); unlistenToKeyEvent();
@ -37,6 +39,7 @@ onActivated(async () => {
[size.width - ml, size.height - mt] [size.width - ml, size.height - mt]
); );
refreshKeyMappingButton();
applyShortcuts(maskRef.value, store.curKeyMappingConfig); applyShortcuts(maskRef.value, store.curKeyMappingConfig);
listenToKeyEvent(); listenToKeyEvent();
} }
@ -46,8 +49,29 @@ function toStartServer() {
router.replace({ name: "device" }); router.replace({ name: "device" });
} }
// TODO 3. function refreshKeyMappingButton() {
// storeio const curKeyMappingConfig = store.curKeyMappingConfig;
const relativeSize = curKeyMappingConfig.relativeSize;
const maskSizeW = maskRef?.value?.clientWidth;
const maskSizeH = maskRef?.value?.clientHeight;
if (maskSizeW && maskSizeH) {
const relativePosToMaskPos = (x: number, y: number) => {
return {
x: Math.round((x / relativeSize.w) * maskSizeW),
y: Math.round((y / relativeSize.h) * maskSizeH),
};
};
const buttons: any = [];
for (let keyObject of curKeyMappingConfig.list) {
const { x, y } = relativePosToMaskPos(keyObject.posX, keyObject.posY);
keyObject.x = x;
keyObject.y = y;
buttons.push(keyObject);
}
renderedButtons.value = buttons;
console.log(renderedButtons.value);
}
}
</script> </script>
<template> <template>
@ -68,7 +92,40 @@ function toStartServer() {
@contextmenu.prevent @contextmenu.prevent
class="mask" class="mask"
ref="maskRef" ref="maskRef"
></div> >
<template v-for="button in renderedButtons">
<div
v-if="button.type === 'SteeringWheel'"
class="mask-steering-wheel"
:style="{
left: button.x - 75 + 'px',
top: button.y - 75 + 'px',
}"
>
<div class="wheel-container">
<i></i>
<div>{{ button.key.up }}</div>
<i></i>
<div>{{ button.key.left }}</div>
<div class="wheel-center"></div>
<div>{{ button.key.right }}</div>
<i></i>
<div>{{ button.key.down }}</div>
<i></i>
</div>
</div>
<div
v-else
class="mask-button"
:style="{
left: button.x + 'px',
top: button.y - 14 + 'px',
}"
>
{{ button.key }}
</div>
</template>
</div>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
@ -76,6 +133,37 @@ function toStartServer() {
background-color: transparent; background-color: transparent;
overflow: hidden; overflow: hidden;
cursor: pointer; cursor: pointer;
position: relative;
border-right: 1px solid var(--bg-color);
border-bottom: 1px solid var(--bg-color);
border-radius: 0 0 5px 0;
& > .mask-button {
position: absolute;
background-color: rgba(0, 0, 0, 0.2);
color: rgba(255, 255, 255, 0.6);
border-radius: 5px;
padding: 5px;
font-size: 12px;
}
& > .mask-steering-wheel {
position: absolute;
background-color: rgba(0, 0, 0, 0.2);
color: rgba(255, 255, 255, 0.6);
border-radius: 50%;
width: 150px;
height: 150px;
font-size: 12px;
.wheel-container {
display: grid;
grid-template-columns: repeat(3, 50px);
grid-template-rows: repeat(3, 50px);
justify-items: center;
align-items: center;
}
}
} }
.notice { .notice {
background-color: rgba(0, 0, 0, 0.5); background-color: rgba(0, 0, 0, 0.5);

View File

@ -2,7 +2,7 @@
import { Ref, onActivated, ref } from "vue"; import { Ref, onActivated, ref } from "vue";
import { onBeforeRouteLeave } from "vue-router"; import { onBeforeRouteLeave } from "vue-router";
// TODO 4-. global store // TODO 4-. global storecurKeyMappingConfig
// TODO 4. // TODO 4.
// TODO 5. // TODO 5.

View File

@ -22,7 +22,7 @@ export const useGlobalStore = defineStore("counter", () => {
const controledDevice: Ref<ControledDevice | null> = ref(null); const controledDevice: Ref<ControledDevice | null> = ref(null);
const curKeyMappingConfig = { const curKeyMappingConfig: any = {
relativeSize: { w: 1280, h: 720 }, relativeSize: { w: 1280, h: 720 },
title: "王者荣耀-暃", title: "王者荣耀-暃",
list: [ list: [
@ -107,8 +107,8 @@ export const useGlobalStore = defineStore("counter", () => {
note: "回复", note: "回复",
key: "KeyC", key: "KeyC",
time: 80, time: 80,
posX: 650, posX: 740,
posY: 740, posY: 650,
pointerId: 3, pointerId: 3,
}, },
{ {
@ -188,8 +188,8 @@ export const useGlobalStore = defineStore("counter", () => {
type: "TriggerWhenPressedSkill", type: "TriggerWhenPressedSkill",
note: "装备技能", note: "装备技能",
key: "WheelDown", key: "WheelDown",
posX: 130, posX: 1150,
posY: 440, posY: 280,
directional: false, directional: false,
rangeOrTime: 80, rangeOrTime: 80,
pointerId: 3, pointerId: 3,
@ -222,6 +222,8 @@ export const useGlobalStore = defineStore("counter", () => {
}, },
], ],
}, },
posX: 1185,
posY: 40,
pointerId: 5, pointerId: 5,
}, },
{ {
@ -243,6 +245,8 @@ export const useGlobalStore = defineStore("counter", () => {
}, },
], ],
}, },
posX: 40,
posY: 300,
pointerId: 5, pointerId: 5,
}, },
{ {
@ -264,6 +268,8 @@ export const useGlobalStore = defineStore("counter", () => {
}, },
], ],
}, },
posX: 250,
posY: 230,
pointerId: 5, pointerId: 5,
}, },
], ],
@ -276,6 +282,6 @@ export const useGlobalStore = defineStore("counter", () => {
controledDevice, controledDevice,
screenSizeW, screenSizeW,
screenSizeH, screenSizeH,
curKeyMappingConfig curKeyMappingConfig,
}; };
}); });