mirror of
https://github.com/AkiChase/scrcpy-mask
synced 2025-02-23 15:32:17 +08:00
feat(mask): render buttons on the mask
This commit is contained in:
parent
2cc8b5b30a
commit
31f0a4a3ca
@ -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
|
||||||
|
@ -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() {
|
||||||
// 配置文件读取到store中,不要每次都io读取
|
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);
|
||||||
|
@ -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 store中的curKeyMappingConfig
|
||||||
// TODO 4. 右键空白区域添加按键
|
// TODO 4. 右键空白区域添加按键
|
||||||
// TODO 5. 左键可拖动按钮(并显示到顶部),右键按钮进行修改、删除
|
// TODO 5. 左键可拖动按钮(并显示到顶部),右键按钮进行修改、删除
|
||||||
|
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user