scrcpy-mask/src/components/Mask.vue

179 lines
4.3 KiB
Vue
Raw Normal View History

2024-04-13 09:53:41 +08:00
<script setup lang="ts">
2024-04-25 22:48:05 +08:00
import { Ref, onActivated, ref } from "vue";
2024-04-13 09:53:41 +08:00
import { NDialog } from "naive-ui";
import { useGlobalStore } from "../store/global";
2024-04-14 17:15:39 +08:00
import { onBeforeRouteLeave, useRouter } from "vue-router";
import {
applyShortcuts,
clearShortcuts,
listenToKeyEvent,
unlistenToKeyEvent,
updateScreenSizeAndMaskArea,
} from "../hotkey";
import { getCurrent } from "@tauri-apps/api/window";
2024-04-13 09:53:41 +08:00
const maskRef = ref<HTMLElement | null>(null);
const store = useGlobalStore();
const router = useRouter();
2024-04-25 22:48:05 +08:00
const renderedButtons: Ref<any[]> = ref([]);
2024-04-14 17:15:39 +08:00
onBeforeRouteLeave(() => {
if (maskRef.value && store.controledDevice) {
unlistenToKeyEvent();
clearShortcuts();
2024-04-14 17:15:39 +08:00
}
});
2024-04-13 09:53:41 +08:00
onActivated(async () => {
if (maskRef.value && store.controledDevice) {
const mt = 30;
const ml = 70;
const appWindow = getCurrent();
const size = (await appWindow.outerSize()).toLogical(
await appWindow.scaleFactor()
);
updateScreenSizeAndMaskArea(
[store.screenSizeW, store.screenSizeH],
[size.width - ml, size.height - mt]
);
2024-04-25 22:48:05 +08:00
refreshKeyMappingButton();
applyShortcuts(maskRef.value, store.curKeyMappingConfig);
listenToKeyEvent();
2024-04-13 09:53:41 +08:00
}
});
function toStartServer() {
router.replace({ name: "device" });
}
2024-04-25 22:48:05 +08:00
function refreshKeyMappingButton() {
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);
}
}
2024-04-13 09:53:41 +08:00
</script>
<template>
<div v-show="!store.controledDevice" class="notice">
<div class="content">
<NDialog
:closable="false"
title="未找到受控设备"
content="请启动服务端并控制任意设备"
positive-text="去启动"
type="warning"
@positive-click="toStartServer"
/>
</div>
</div>
<div
v-show="store.controledDevice"
2024-04-14 17:15:39 +08:00
@contextmenu.prevent
2024-04-13 09:53:41 +08:00
class="mask"
ref="maskRef"
2024-04-25 22:48:05 +08:00
>
<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>
2024-04-13 09:53:41 +08:00
</template>
<style scoped lang="scss">
.mask {
background-color: transparent;
2024-04-13 09:53:41 +08:00
overflow: hidden;
2024-04-14 17:15:39 +08:00
cursor: pointer;
2024-04-25 22:48:05 +08:00
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;
}
}
2024-04-13 09:53:41 +08:00
}
.notice {
background-color: rgba(0, 0, 0, 0.5);
2024-04-13 09:53:41 +08:00
display: flex;
justify-content: center;
align-items: center;
.content {
width: 80%;
}
}
</style>