mirror of
https://github.com/AkiChase/scrcpy-mask
synced 2025-04-21 04:25:13 +08:00
feat(hotkey): add several functional shortcut
This commit is contained in:
parent
73db78a5e1
commit
9f1847cb16
@ -1,6 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { getCurrent } from "@tauri-apps/api/window";
|
||||
import { onActivated, onMounted, ref } from "vue";
|
||||
import { Ref, onActivated, ref } from "vue";
|
||||
import { onBeforeRouteLeave } from "vue-router";
|
||||
|
||||
// TODO 添加右侧按键列表用于拖放
|
||||
@ -10,13 +9,12 @@ const keyboardElement = ref<HTMLElement | null>(null);
|
||||
const mouseX = ref(0);
|
||||
const mouseY = ref(0);
|
||||
|
||||
let posFactor = 1;
|
||||
function clientxToPosx(clientx: number) {
|
||||
return clientx < 70 ? 0 : Math.floor((clientx - 70) * posFactor);
|
||||
return clientx < 70 ? 0 : Math.floor(clientx - 70);
|
||||
}
|
||||
|
||||
function clientyToPosy(clienty: number) {
|
||||
return clienty < 30 ? 0 : Math.floor((clienty - 30) * posFactor);
|
||||
return clienty < 30 ? 0 : Math.floor(clienty - 30);
|
||||
}
|
||||
|
||||
let ignoreMousemove = true;
|
||||
@ -27,17 +25,23 @@ function mousemoveHandler(event: MouseEvent) {
|
||||
mouseY.value = clientyToPosy(event.clientY);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const appWindow = getCurrent();
|
||||
posFactor = await appWindow.scaleFactor();
|
||||
});
|
||||
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);
|
||||
}
|
||||
|
||||
onActivated(() => {
|
||||
keyboardElement.value?.addEventListener("mousemove", mousemoveHandler);
|
||||
document.addEventListener("keyup", keyupHandler);
|
||||
});
|
||||
|
||||
onBeforeRouteLeave(() => {
|
||||
keyboardElement.value?.removeEventListener("mousemove", mousemoveHandler);
|
||||
document.removeEventListener("keyup", keyupHandler);
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -45,6 +49,9 @@ onBeforeRouteLeave(() => {
|
||||
<div ref="keyboardElement" class="keyboard">
|
||||
此处最好用其他颜色的蒙版,和右侧的按键列表区同色
|
||||
<div>{{ mouseX }}, {{ mouseY }}</div>
|
||||
<div v-for="code in keyboardCodeList">
|
||||
{{ code }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -14,6 +14,8 @@ import {
|
||||
useMessage,
|
||||
} from "naive-ui";
|
||||
import {
|
||||
LogicalPosition,
|
||||
LogicalSize,
|
||||
PhysicalPosition,
|
||||
PhysicalSize,
|
||||
getCurrent,
|
||||
@ -25,19 +27,21 @@ let unlistenResize: UnlistenFn = () => {};
|
||||
let unlistenMove: UnlistenFn = () => {};
|
||||
|
||||
async function refreshAreaModel(size?: PhysicalSize, pos?: PhysicalPosition) {
|
||||
const appWindow = getCurrent();
|
||||
const factor = await appWindow.scaleFactor();
|
||||
// header size and sidebar size
|
||||
const mt = 30 * factor;
|
||||
const ml = 70 * factor;
|
||||
const factor = await getCurrent().scaleFactor();
|
||||
|
||||
if (pos !== undefined) {
|
||||
areaModel.value.posX = Math.floor(pos.x + ml);
|
||||
areaModel.value.posY = Math.floor(pos.y + mt);
|
||||
const logicalSize = size?.toLogical(factor);
|
||||
const logicalPos = pos?.toLogical(factor);
|
||||
// header size and sidebar size
|
||||
const mt = 30;
|
||||
const ml = 70;
|
||||
|
||||
if (logicalPos !== undefined) {
|
||||
areaModel.value.posX = Math.floor(logicalPos.x + ml);
|
||||
areaModel.value.posY = Math.floor(logicalPos.y + mt);
|
||||
}
|
||||
if (size !== undefined) {
|
||||
areaModel.value.sizeW = Math.floor(size.width - ml);
|
||||
areaModel.value.sizeH = Math.floor(size.height - mt);
|
||||
if (logicalSize !== undefined) {
|
||||
areaModel.value.sizeW = Math.floor(logicalSize.width - ml);
|
||||
areaModel.value.sizeH = Math.floor(logicalSize.height - mt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,6 +49,7 @@ const message = useMessage();
|
||||
|
||||
const formRef = ref<FormInst | null>(null);
|
||||
|
||||
// logical pos and size of the mask area
|
||||
const areaModel = ref({
|
||||
posX: 0,
|
||||
posY: 0,
|
||||
@ -92,6 +97,7 @@ function handleAdjustClick(e: MouseEvent) {
|
||||
});
|
||||
}
|
||||
|
||||
// TODO 等待官方合并修复分支后检查表现是否正常
|
||||
// move and resize window to the selected window (control) area
|
||||
async function adjustMaskArea() {
|
||||
// header size and sidebar size
|
||||
@ -99,26 +105,20 @@ async function adjustMaskArea() {
|
||||
const ml = 70;
|
||||
|
||||
const appWindow = getCurrent();
|
||||
const factor = await appWindow.scaleFactor();
|
||||
|
||||
const pos = new PhysicalPosition(
|
||||
areaModel.value.posX,
|
||||
areaModel.value.posY
|
||||
).toLogical(factor);
|
||||
pos.y -= mt;
|
||||
pos.x -= ml;
|
||||
const pos = new LogicalPosition(
|
||||
areaModel.value.posX - ml,
|
||||
areaModel.value.posY - mt
|
||||
);
|
||||
|
||||
if (pos.x <= 0 || pos.y <= 0) {
|
||||
message.warning("蒙版区域坐标过小,可能导致其他部分不可见");
|
||||
}
|
||||
|
||||
const size = new PhysicalSize(
|
||||
areaModel.value.sizeW,
|
||||
areaModel.value.sizeH
|
||||
).toLogical(factor);
|
||||
size.width += ml;
|
||||
size.height += mt;
|
||||
|
||||
const size = new LogicalSize(
|
||||
areaModel.value.sizeW + ml,
|
||||
areaModel.value.sizeH + mt
|
||||
);
|
||||
await appWindow.setPosition(pos);
|
||||
await appWindow.setSize(size);
|
||||
}
|
||||
|
585
src/hotkey.ts
585
src/hotkey.ts
@ -6,42 +6,223 @@ import {
|
||||
touch,
|
||||
} from "./frontcommand/scrcpyMaskCmd";
|
||||
|
||||
let posFactor = 1; // it will be replaced in initMouseShortcuts
|
||||
function clientxToPosx(clientx: number) {
|
||||
return clientx < 70 ? 0 : Math.floor((clientx - 70) * posFactor);
|
||||
return clientx < 70 ? 0 : Math.floor(clientx - 70);
|
||||
}
|
||||
|
||||
function clientyToPosy(clienty: number) {
|
||||
return clienty < 30 ? 0 : Math.floor((clienty - 30) * posFactor);
|
||||
return clienty < 30 ? 0 : Math.floor(clienty - 30);
|
||||
}
|
||||
|
||||
function clientxToSkillOffsetx(clientx: number, range: number, scale = 0.5) {
|
||||
// Get the offset relative to the center of the screen
|
||||
let offsetX = clientxToPosx(clientx) - screenSizeW / 2;
|
||||
return Math.max(-range, Math.min(range, Math.round(offsetX * scale)));
|
||||
function clientxToPosOffsetx(clientx: number, posx: number, scale: number) {
|
||||
let offsetX = clientxToPosx(clientx) - posx;
|
||||
return Math.round(offsetX * scale);
|
||||
}
|
||||
|
||||
function clientyToSkillOffsety(clienty: number, range: number, scale = 0.5) {
|
||||
// Get the offset relative to the center of the screen
|
||||
let offsetY = clientyToPosy(clienty) - screenSizeH / 2;
|
||||
return Math.max(-range, Math.min(range, Math.round(offsetY * scale)));
|
||||
function clientyToPosOffsety(clienty: number, posy: number, scale: number) {
|
||||
let offsetY = clientyToPosy(clienty) - posy;
|
||||
return Math.round(offsetY * scale);
|
||||
}
|
||||
|
||||
function clientxToCenterOffsetx(clientx: number, range: number, scale = 0.5) {
|
||||
return Math.max(
|
||||
-range,
|
||||
Math.min(range, clientxToPosOffsetx(clientx, screenSizeW / 2, scale))
|
||||
);
|
||||
}
|
||||
|
||||
function clientyToCenterOffsety(clienty: number, range: number, scale = 0.5) {
|
||||
return Math.max(
|
||||
-range,
|
||||
Math.min(range, clientyToPosOffsety(clienty, screenSizeH * 0.57, scale))
|
||||
);
|
||||
}
|
||||
|
||||
async function sleep(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
// TODO 取消技能
|
||||
// 仅仅针对技能快捷键,要求传入pointer_id(所有技能键的都一样), 取消位置
|
||||
// 在down时就执行
|
||||
// 执行时直接删除对应的loopDownKeyCBMap, upKeyCBMap键值对,恢复cursor,然后将触点使用touch-move到取消位置然后up
|
||||
// TODO 普通点击
|
||||
// 直接用default的touch,按下时长是写死的100ms
|
||||
// TODO 视野移动
|
||||
// 关键在于中心位置应该是传入的坐标,要重新计算相对偏移
|
||||
// TODO 宏
|
||||
// 宏也是分为down,loop,up三个阶段
|
||||
// 目前只需要支持sleep, touch, swipe三个指令即可
|
||||
function calculateMacroPosX(pos: [string, number] | number): number {
|
||||
if (typeof pos === "number") {
|
||||
return pos;
|
||||
}
|
||||
if (typeof pos === "string") {
|
||||
return clientxToPosx(mouseX);
|
||||
} else {
|
||||
if (pos[0] === "mouse") {
|
||||
return clientxToPosx(mouseX) + pos[1];
|
||||
} else {
|
||||
throw new Error("Invalid pos");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateMacroPosY(pos: [string, number] | number): number {
|
||||
if (typeof pos === "number") {
|
||||
return pos;
|
||||
}
|
||||
if (typeof pos === "string") {
|
||||
return clientyToPosy(mouseY);
|
||||
} else {
|
||||
if (pos[0] === "mouse") {
|
||||
return clientyToPosy(mouseY) + pos[1];
|
||||
} else {
|
||||
throw new Error("Invalid pos");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateMacroPosList(
|
||||
posList: [[string, number] | number, [string, number] | number][]
|
||||
): { x: number; y: number }[] {
|
||||
return posList.map((posPair) => {
|
||||
return {
|
||||
x: calculateMacroPosX(posPair[0]),
|
||||
y: calculateMacroPosY(posPair[1]),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// TODO 方向轮盘也放到loop内吧,两个独立的循环不太好。但至少要将轮盘的循环间隔调低。
|
||||
// TODO 偶尔不定时抽风(但等待一会就能恢复正常),表现为setinterval中的回调函数没有执行
|
||||
|
||||
// add shortcuts for observation
|
||||
function addObservationShortcuts(
|
||||
key: string,
|
||||
posX: number,
|
||||
posY: number,
|
||||
scale: number,
|
||||
pointerId: number
|
||||
) {
|
||||
let observationMouseX = 0;
|
||||
let observationMouseY = 0;
|
||||
addShortcut(
|
||||
key,
|
||||
async () => {
|
||||
observationMouseX = clientxToPosx(mouseX);
|
||||
observationMouseY = clientyToPosy(mouseY);
|
||||
await touch({
|
||||
action: TouchAction.Down,
|
||||
pointerId,
|
||||
screen: {
|
||||
w: screenSizeW,
|
||||
h: screenSizeH,
|
||||
},
|
||||
pos: {
|
||||
x: posX,
|
||||
y: posY,
|
||||
},
|
||||
});
|
||||
},
|
||||
async () => {
|
||||
await touch({
|
||||
action: TouchAction.Move,
|
||||
pointerId,
|
||||
screen: {
|
||||
w: screenSizeW,
|
||||
h: screenSizeH,
|
||||
},
|
||||
pos: {
|
||||
x: posX + clientxToPosOffsetx(mouseX, observationMouseX, scale),
|
||||
y: posY + clientyToPosOffsety(mouseY, observationMouseY, scale),
|
||||
},
|
||||
});
|
||||
},
|
||||
async () => {
|
||||
await touch({
|
||||
action: TouchAction.Up,
|
||||
pointerId,
|
||||
screen: {
|
||||
w: screenSizeW,
|
||||
h: screenSizeH,
|
||||
},
|
||||
pos: {
|
||||
x: posX + clientxToPosOffsetx(mouseX, observationMouseY, scale),
|
||||
y: posY + clientyToPosOffsety(mouseY, observationMouseY, scale),
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// add shortcuts for simple tap (touch for 100 ms when pressed)
|
||||
function addTapShortcuts(
|
||||
key: string,
|
||||
posX: number,
|
||||
posY: number,
|
||||
pointerId: number
|
||||
) {
|
||||
addShortcut(
|
||||
key,
|
||||
async () => {
|
||||
await touch({
|
||||
action: TouchAction.Default,
|
||||
pointerId,
|
||||
screen: {
|
||||
w: screenSizeW,
|
||||
h: screenSizeH,
|
||||
},
|
||||
pos: {
|
||||
x: posX,
|
||||
y: posY,
|
||||
},
|
||||
});
|
||||
},
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
}
|
||||
|
||||
// add shortcuts for cancel skill
|
||||
function addCancelSkillShortcuts(
|
||||
key: string,
|
||||
posX: number,
|
||||
posY: number,
|
||||
pointerId: number
|
||||
) {
|
||||
addShortcut(
|
||||
key,
|
||||
async () => {
|
||||
// delete the callback
|
||||
for (const cancelAbleKey of cancelAbleKeyList) {
|
||||
loopDownKeyCBMap.delete(cancelAbleKey);
|
||||
upKeyCBMap.delete(cancelAbleKey);
|
||||
}
|
||||
|
||||
let distance = 0;
|
||||
while (distance <= 20) {
|
||||
await touch({
|
||||
action: TouchAction.Move,
|
||||
pointerId,
|
||||
screen: {
|
||||
w: screenSizeW,
|
||||
h: screenSizeH,
|
||||
},
|
||||
pos: {
|
||||
x: posX + distance,
|
||||
y: posY,
|
||||
},
|
||||
});
|
||||
await sleep(5);
|
||||
distance += 1;
|
||||
}
|
||||
await touch({
|
||||
action: TouchAction.Up,
|
||||
pointerId,
|
||||
screen: {
|
||||
w: screenSizeW,
|
||||
h: screenSizeH,
|
||||
},
|
||||
pos: {
|
||||
x: posX,
|
||||
y: posY,
|
||||
},
|
||||
});
|
||||
},
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
}
|
||||
|
||||
// add shortcuts for trigger when pressed skill
|
||||
function addTriggerWhenPressedSkillShortcuts(
|
||||
@ -54,7 +235,6 @@ function addTriggerWhenPressedSkillShortcuts(
|
||||
range: number,
|
||||
pointerId: number
|
||||
) {
|
||||
skillKeyList.push(key);
|
||||
if (directional) {
|
||||
addShortcut(
|
||||
key,
|
||||
@ -70,8 +250,8 @@ function addTriggerWhenPressedSkillShortcuts(
|
||||
pos: [
|
||||
{ x: posX, y: posY },
|
||||
{
|
||||
x: posX + clientxToSkillOffsetx(mouseX, range),
|
||||
y: posY + clientyToSkillOffsety(mouseY, range),
|
||||
x: posX + clientxToCenterOffsetx(mouseX, range),
|
||||
y: posY + clientyToCenterOffsety(mouseY, range),
|
||||
},
|
||||
],
|
||||
intervalBetweenPos: 0,
|
||||
@ -81,30 +261,11 @@ function addTriggerWhenPressedSkillShortcuts(
|
||||
undefined
|
||||
);
|
||||
} else {
|
||||
addShortcut(
|
||||
key,
|
||||
// down
|
||||
async () => {
|
||||
await touch({
|
||||
action: TouchAction.Down,
|
||||
pointerId,
|
||||
screen: {
|
||||
w: screenSizeW,
|
||||
h: screenSizeH,
|
||||
},
|
||||
pos: {
|
||||
x: posX,
|
||||
y: posY,
|
||||
},
|
||||
});
|
||||
},
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
addTapShortcuts(key, posX, posY, pointerId);
|
||||
}
|
||||
}
|
||||
|
||||
// add shortcuts for directionless skill
|
||||
// add shortcuts for directionless skill (cancelable)
|
||||
function addDirectionlessSkillShortcuts(
|
||||
key: string,
|
||||
// pos relative to the device
|
||||
@ -112,12 +273,10 @@ function addDirectionlessSkillShortcuts(
|
||||
posY: number,
|
||||
pointerId: number
|
||||
) {
|
||||
skillKeyList.push(key);
|
||||
addShortcut(
|
||||
key,
|
||||
// down
|
||||
async () => {
|
||||
document.body.style.cursor = "pointer";
|
||||
await touch({
|
||||
action: TouchAction.Down,
|
||||
pointerId,
|
||||
@ -135,7 +294,6 @@ function addDirectionlessSkillShortcuts(
|
||||
undefined,
|
||||
// up
|
||||
async () => {
|
||||
document.body.style.cursor = "";
|
||||
await touch({
|
||||
action: TouchAction.Up,
|
||||
pointerId,
|
||||
@ -148,11 +306,12 @@ function addDirectionlessSkillShortcuts(
|
||||
y: posY,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// add shortcuts for directional skill
|
||||
// add shortcuts for directional skill (cancelable)
|
||||
function addDirectionalSkillShortcuts(
|
||||
key: string,
|
||||
// pos relative to the device
|
||||
@ -161,12 +320,10 @@ function addDirectionalSkillShortcuts(
|
||||
range: number,
|
||||
pointerId: number
|
||||
) {
|
||||
skillKeyList.push(key);
|
||||
addShortcut(
|
||||
key,
|
||||
// down
|
||||
async () => {
|
||||
document.body.style.cursor = "pointer";
|
||||
await swipe({
|
||||
action: SwipeAction.NoUp,
|
||||
pointerId,
|
||||
@ -177,8 +334,8 @@ function addDirectionalSkillShortcuts(
|
||||
pos: [
|
||||
{ x: posX, y: posY },
|
||||
{
|
||||
x: posX + clientxToSkillOffsetx(mouseX, range),
|
||||
y: posY + clientyToSkillOffsety(mouseY, range),
|
||||
x: posX + clientxToCenterOffsetx(mouseX, range),
|
||||
y: posY + clientyToCenterOffsety(mouseY, range),
|
||||
},
|
||||
],
|
||||
intervalBetweenPos: 0,
|
||||
@ -194,14 +351,13 @@ function addDirectionalSkillShortcuts(
|
||||
h: screenSizeH,
|
||||
},
|
||||
pos: {
|
||||
x: posX + clientxToSkillOffsetx(mouseX, range),
|
||||
y: posY + clientyToSkillOffsety(mouseY, range),
|
||||
x: posX + clientxToCenterOffsetx(mouseX, range),
|
||||
y: posY + clientyToCenterOffsety(mouseY, range),
|
||||
},
|
||||
});
|
||||
},
|
||||
// up
|
||||
async () => {
|
||||
document.body.style.cursor = "";
|
||||
await touch({
|
||||
action: TouchAction.Up,
|
||||
pointerId,
|
||||
@ -210,11 +366,12 @@ function addDirectionalSkillShortcuts(
|
||||
h: screenSizeH,
|
||||
},
|
||||
pos: {
|
||||
x: posX + clientxToSkillOffsetx(mouseX, range),
|
||||
y: posY + clientyToSkillOffsety(mouseY, range),
|
||||
x: posX + clientxToCenterOffsetx(mouseX, range),
|
||||
y: posY + clientyToCenterOffsety(mouseY, range),
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
@ -358,10 +515,10 @@ interface wheelKey {
|
||||
}
|
||||
type stringKeyFlag = Record<string, boolean>;
|
||||
|
||||
// add baisc left click shortcuts
|
||||
function addLeftClickShortcuts(pointerId: number) {
|
||||
// add baisc click shortcuts
|
||||
function addClickShortcuts(key: string, pointerId: number) {
|
||||
addShortcut(
|
||||
"M0",
|
||||
key,
|
||||
async () => {
|
||||
await touch({
|
||||
action: TouchAction.Down,
|
||||
@ -411,41 +568,40 @@ let screenSizeW: number;
|
||||
let screenSizeH: number;
|
||||
let mouseX = 0;
|
||||
let mouseY = 0;
|
||||
let oldMouseX = 0;
|
||||
let oldMouseY = 0;
|
||||
|
||||
const downKeyMap: Map<string, boolean> = new Map();
|
||||
const downKeyCBMap: Map<string, () => Promise<void>> = new Map();
|
||||
const loopDownKeyCBMap: Map<string, () => Promise<void>> = new Map();
|
||||
const upKeyCBMap: Map<string, () => Promise<void>> = new Map();
|
||||
|
||||
const skillKeyList: string[] = [];
|
||||
const cancelAbleKeyList: string[] = [];
|
||||
|
||||
function keydownHandler(event: KeyboardEvent) {
|
||||
if (event.repeat) return;
|
||||
if (downKeyMap.has(event.key)) {
|
||||
event.preventDefault();
|
||||
event.preventDefault();
|
||||
if (downKeyMap.has(event.code)) {
|
||||
// execute the down callback (if there is) asyncily
|
||||
let cb = downKeyCBMap.get(event.key);
|
||||
let cb = downKeyCBMap.get(event.code);
|
||||
if (cb) cb();
|
||||
downKeyMap.set(event.key, true);
|
||||
downKeyMap.set(event.code, true);
|
||||
}
|
||||
}
|
||||
|
||||
function keyupHandler(event: KeyboardEvent) {
|
||||
if (downKeyMap.has(event.key)) {
|
||||
event.preventDefault();
|
||||
event.preventDefault();
|
||||
if (downKeyMap.has(event.code)) {
|
||||
// execute the up callback (if there is) asyncily
|
||||
let cb = upKeyCBMap.get(event.key);
|
||||
let cb = upKeyCBMap.get(event.code);
|
||||
if (cb) cb();
|
||||
downKeyMap.set(event.key, false);
|
||||
downKeyMap.set(event.code, false);
|
||||
}
|
||||
}
|
||||
|
||||
function handleMouseDown(event: MouseEvent) {
|
||||
mouseX = event.clientX;
|
||||
mouseY = event.clientY;
|
||||
event.preventDefault();
|
||||
let key = "M" + event.button.toString();
|
||||
if (downKeyMap.has(key)) {
|
||||
event.preventDefault();
|
||||
// execute the down callback asyncily
|
||||
let cb = downKeyCBMap.get(key);
|
||||
if (cb) cb();
|
||||
@ -454,9 +610,11 @@ function handleMouseDown(event: MouseEvent) {
|
||||
}
|
||||
|
||||
function handleMouseUp(event: MouseEvent) {
|
||||
mouseX = event.clientX;
|
||||
mouseY = event.clientY;
|
||||
event.preventDefault();
|
||||
let key = "M" + event.button.toString();
|
||||
if (downKeyMap.has(key)) {
|
||||
event.preventDefault();
|
||||
// execute the up callback asyncily
|
||||
let cb = upKeyCBMap.get(key);
|
||||
if (cb) cb();
|
||||
@ -465,8 +623,6 @@ function handleMouseUp(event: MouseEvent) {
|
||||
}
|
||||
|
||||
function handleMouseMove(event: MouseEvent) {
|
||||
oldMouseX = mouseX;
|
||||
oldMouseY = mouseY;
|
||||
mouseX = event.clientX;
|
||||
mouseY = event.clientY;
|
||||
}
|
||||
@ -475,65 +631,266 @@ function addShortcut(
|
||||
key: string,
|
||||
downCB: () => Promise<void>,
|
||||
loopCB?: () => Promise<void>,
|
||||
upCB?: () => Promise<void>
|
||||
upCB?: () => Promise<void>,
|
||||
cancelAble = false // only work with downCB && upCB
|
||||
) {
|
||||
downKeyMap.set(key, false);
|
||||
|
||||
if (downCB && loopCB)
|
||||
downKeyCBMap.set(key, async () => {
|
||||
downCB();
|
||||
loopDownKeyCBMap.set(key, loopCB);
|
||||
});
|
||||
else if (downCB) {
|
||||
downKeyCBMap.set(key, downCB);
|
||||
}
|
||||
|
||||
if (upCB) {
|
||||
if (cancelAble && downCB && upCB) {
|
||||
cancelAbleKeyList.push(key);
|
||||
const cancelAbleUpCB = async () => {
|
||||
loopDownKeyCBMap.delete(key);
|
||||
upKeyCBMap.delete(key);
|
||||
await upCB();
|
||||
};
|
||||
if (loopCB)
|
||||
downKeyCBMap.set(key, async () => {
|
||||
loopDownKeyCBMap.set(key, loopCB);
|
||||
upKeyCBMap.set(key, cancelAbleUpCB);
|
||||
await downCB();
|
||||
});
|
||||
else {
|
||||
// no loopCB
|
||||
downKeyCBMap.set(key, async () => {
|
||||
upKeyCBMap.set(key, cancelAbleUpCB);
|
||||
await downCB();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (downCB && loopCB)
|
||||
downKeyCBMap.set(key, async () => {
|
||||
downCB();
|
||||
loopDownKeyCBMap.set(key, loopCB);
|
||||
});
|
||||
else if (downCB) {
|
||||
// no loopCB
|
||||
downKeyCBMap.set(key, downCB);
|
||||
}
|
||||
|
||||
if (upCB) {
|
||||
upKeyCBMap.set(key, async () => {
|
||||
loopDownKeyCBMap.delete(key);
|
||||
upCB();
|
||||
});
|
||||
else upKeyCBMap.set(key, upCB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* execute the json object macro
|
||||
* @param macro
|
||||
* @example
|
||||
* await execMacro([
|
||||
* {
|
||||
* type: "touch",
|
||||
* // op, pointerId, posX, posY
|
||||
* args: ["down", 5, ["mouse", -10], 600],
|
||||
* },
|
||||
* {
|
||||
* type: "sleep",
|
||||
* // time(ms)
|
||||
* args: [1000],
|
||||
* },
|
||||
* {
|
||||
* type: "touch",
|
||||
* args: ["up", 5, ["mouse", 10], 600],
|
||||
* },
|
||||
* {
|
||||
* type: "swipe",
|
||||
* // op, pointerId, posList, intervalBetweenPos
|
||||
* args: [
|
||||
* "default", 5,
|
||||
* [
|
||||
* [
|
||||
* ["mouse", 100],
|
||||
* ["mouse", -100],
|
||||
* ],
|
||||
* ["mouse", "mouse"],
|
||||
* ],
|
||||
* 1000,
|
||||
* ],
|
||||
* },
|
||||
* ]);
|
||||
*/
|
||||
async function execMacro(macro: any[]) {
|
||||
for (const cmd of macro) {
|
||||
if (!cmd.hasOwnProperty("type") || !cmd.hasOwnProperty("args")) {
|
||||
console.error("Invalid command: ", cmd);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
switch (cmd.type) {
|
||||
case "sleep":
|
||||
await sleep(cmd.args[0]);
|
||||
break;
|
||||
case "touch":
|
||||
let touchAction;
|
||||
switch (cmd.args[0]) {
|
||||
case "default":
|
||||
touchAction = TouchAction.Default;
|
||||
break;
|
||||
case "down":
|
||||
touchAction = TouchAction.Down;
|
||||
break;
|
||||
case "up":
|
||||
touchAction = TouchAction.Up;
|
||||
break;
|
||||
case "move":
|
||||
touchAction = TouchAction.Move;
|
||||
break;
|
||||
default:
|
||||
console.error("Invalid touch action: ", cmd.args[0]);
|
||||
return;
|
||||
}
|
||||
await touch({
|
||||
action: touchAction,
|
||||
pointerId: cmd.args[1],
|
||||
screen: {
|
||||
w: screenSizeW,
|
||||
h: screenSizeH,
|
||||
},
|
||||
pos: {
|
||||
x: calculateMacroPosX(cmd.args[2]),
|
||||
y: calculateMacroPosY(cmd.args[3]),
|
||||
},
|
||||
});
|
||||
break;
|
||||
case "swipe":
|
||||
let swipeAction;
|
||||
switch (cmd.args[0]) {
|
||||
case "default":
|
||||
swipeAction = SwipeAction.Default;
|
||||
break;
|
||||
case "noUp":
|
||||
swipeAction = SwipeAction.NoUp;
|
||||
break;
|
||||
case "noDown":
|
||||
swipeAction = SwipeAction.NoDown;
|
||||
break;
|
||||
default:
|
||||
console.error("Invalid swipe action: ", cmd.args[0]);
|
||||
return;
|
||||
}
|
||||
await swipe({
|
||||
action: swipeAction,
|
||||
pointerId: cmd.args[1],
|
||||
screen: {
|
||||
w: screenSizeW,
|
||||
h: screenSizeH,
|
||||
},
|
||||
pos: calculateMacroPosList(cmd.args[2]),
|
||||
intervalBetweenPos: cmd.args[3],
|
||||
});
|
||||
break;
|
||||
default:
|
||||
console.error("Invalid command: ", cmd);
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Invalid command: ", cmd, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let timmerId: number = 0;
|
||||
export function listenToKeyEvent() {
|
||||
document.addEventListener("keydown", keydownHandler);
|
||||
document.addEventListener("keyup", keyupHandler);
|
||||
timmerId = setInterval(() => {
|
||||
loopDownKeyCBMap.forEach((cb) => {
|
||||
cb();
|
||||
});
|
||||
}, 50);
|
||||
}
|
||||
|
||||
export function unlistenToKeyEvent() {
|
||||
document.removeEventListener("keydown", keydownHandler);
|
||||
document.removeEventListener("keyup", keyupHandler);
|
||||
clearInterval(timmerId);
|
||||
}
|
||||
|
||||
export function initShortcuts(
|
||||
element: HTMLElement,
|
||||
factor: number,
|
||||
screenSize: [number, number]
|
||||
screenSize: [number, number],
|
||||
element: HTMLElement
|
||||
) {
|
||||
posFactor = factor;
|
||||
screenSizeW = screenSize[0];
|
||||
screenSizeH = screenSize[1];
|
||||
|
||||
element.addEventListener("mousedown", handleMouseDown);
|
||||
element.addEventListener("mousemove", handleMouseMove);
|
||||
element.addEventListener("mouseup", handleMouseUp);
|
||||
element.addEventListener("keydown", keydownHandler);
|
||||
element.addEventListener("keyup", keyupHandler);
|
||||
element.addEventListener("mouseout", handleMouseUp); // mouse out of the element as mouse up
|
||||
|
||||
addLeftClickShortcuts(0);
|
||||
addClickShortcuts("M0", 0);
|
||||
addSteeringWheelKeyboardShortcuts(
|
||||
{
|
||||
left: "a",
|
||||
right: "d",
|
||||
up: "w",
|
||||
down: "s",
|
||||
left: "KeyA",
|
||||
right: "KeyD",
|
||||
up: "KeyW",
|
||||
down: "KeyS",
|
||||
},
|
||||
180,
|
||||
560,
|
||||
100,
|
||||
1
|
||||
);
|
||||
addDirectionalSkillShortcuts("Alt", 1025, 500, 200, 2);
|
||||
addDirectionalSkillShortcuts("q", 950, 610, 200, 2);
|
||||
addDirectionalSkillShortcuts("e", 1160, 420, 200, 2);
|
||||
addTriggerWhenPressedSkillShortcuts("M4", 1160, 420, false, 0, 2);
|
||||
setInterval(() => {
|
||||
loopDownKeyCBMap.forEach((cb) => {
|
||||
if (oldMouseX !== mouseX && oldMouseY !== mouseY) {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
}, 50);
|
||||
addDirectionalSkillShortcuts("KeyQ", 950, 610, 100, 2); // skill 1
|
||||
addDirectionalSkillShortcuts("AltLeft", 1025, 500, 100, 2); // skill 2
|
||||
addDirectionalSkillShortcuts("KeyE", 1160, 420, 100, 2); // skill 3
|
||||
addTriggerWhenPressedSkillShortcuts("M4", 1160, 420, false, 0, 2); // skill 3 (no direction and trigger when pressed)
|
||||
addDirectionlessSkillShortcuts("M1", 1150, 280, 2); // equipment skill (middle mouse click)
|
||||
addCancelSkillShortcuts("Space", 1160, 140, 2); // cancel skill
|
||||
|
||||
addTapShortcuts("KeyB", 650, 650, 3); // home
|
||||
addTapShortcuts("KeyC", 740, 650, 3); // recover
|
||||
addDirectionalSkillShortcuts("KeyF", 840, 650, 100, 2); // summoner skills
|
||||
addTriggerWhenPressedSkillShortcuts("ControlLeft", 840, 650, false, 0, 3); // summoner skills (no direction and trigger when pressed)
|
||||
addTapShortcuts("M2", 1165, 620, 3); // attack (right click)
|
||||
|
||||
addObservationShortcuts("M3", 1000, 200, 0.5, 4); // observation
|
||||
|
||||
// panel
|
||||
addShortcut(
|
||||
"Tab",
|
||||
async () => {
|
||||
await execMacro([
|
||||
{
|
||||
type: "touch",
|
||||
args: ["default", 5, 1185, 40],
|
||||
},
|
||||
]);
|
||||
},
|
||||
undefined,
|
||||
async () => {
|
||||
await execMacro([
|
||||
{
|
||||
type: "touch",
|
||||
args: ["default", 5, 1220, 100],
|
||||
},
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
// shop
|
||||
addShortcut(
|
||||
"ShiftLeft",
|
||||
async () => {
|
||||
await execMacro([
|
||||
{
|
||||
type: "touch",
|
||||
args: ["default", 5, 40, 300],
|
||||
},
|
||||
]);
|
||||
},
|
||||
undefined,
|
||||
async () => {
|
||||
await execMacro([
|
||||
{
|
||||
type: "touch",
|
||||
args: ["default", 5, 1200, 60],
|
||||
},
|
||||
]);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ export const useGlobalStore = defineStore("counter", () => {
|
||||
scid: string;
|
||||
deviceName: string;
|
||||
device: Device;
|
||||
screenSize: [number, number];
|
||||
}
|
||||
|
||||
const controledDevice: Ref<ControledDevice|null> = ref(null);
|
||||
|
Loading…
Reference in New Issue
Block a user