分包+刷新逻辑
This commit is contained in:
78
src/composables/useCanvasPointer.js
Normal file
78
src/composables/useCanvasPointer.js
Normal file
@@ -0,0 +1,78 @@
|
||||
// src/composables/useCanvasPointer.js
|
||||
import { ref } from "vue";
|
||||
|
||||
/**
|
||||
* @param {{ phone, toBuffer, getWs: (index:number)=>WebSocket|null }} deps
|
||||
* 依赖项对象,包含手机信息、缓冲转换和WebSocket获取函数
|
||||
*/
|
||||
export function useCanvasPointer(deps) {
|
||||
const { phone, toBuffer, getWs } = deps;
|
||||
|
||||
const canvasRef = ref({}); // { [udid]: HTMLCanvasElement } - 存储设备ID到Canvas元素的映射
|
||||
const frameMeta = ref({}); // { [udid]: { w,h, rotation? } } - 存储设备ID到帧元数据的映射
|
||||
|
||||
/**
|
||||
* 初始化画布
|
||||
* @param {string} udid - 设备唯一标识符
|
||||
*/
|
||||
function initCanvas(udid) {
|
||||
const canvas = canvasRef.value[udid];
|
||||
if (!canvas) return;
|
||||
const dpr = window.devicePixelRatio || 1; // 获取设备像素比
|
||||
// 设置画布样式尺寸
|
||||
canvas.style.width = `${phone.value.width * 1.4}px`;
|
||||
canvas.style.height = `${phone.value.height * 1.4}px`;
|
||||
// 设置画布实际像素尺寸
|
||||
canvas.width = phone.value.width * 1.4 * dpr;
|
||||
canvas.height = phone.value.height * 1.4 * dpr;
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.scale(dpr, dpr);
|
||||
// 可选:参考网格(已设为透明)
|
||||
ctx.strokeStyle = "#ffffff00";
|
||||
for (let x = 0; x <= phone.value.width; x += 100) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, 0);
|
||||
ctx.lineTo(x, phone.value.height);
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
function getCanvasCoordinate(event, udid) {
|
||||
const canvas = canvasRef.value[udid];
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
const rx = (event.clientX - rect.left) / rect.width;
|
||||
const ry = (event.clientY - rect.top) / rect.height;
|
||||
|
||||
const meta = frameMeta.value[udid] || { w: 320, h: 720, rotation: 0 };
|
||||
let x = rx * meta.w;
|
||||
let y = ry * meta.h;
|
||||
|
||||
switch (meta.rotation ?? 0) {
|
||||
case 90: [x, y] = [meta.w - y, x]; break;
|
||||
case 180: [x, y] = [meta.w - x, meta.h - y]; break;
|
||||
case 270: [x, y] = [y, meta.h - x]; break;
|
||||
}
|
||||
x = Math.max(0, Math.min(meta.w - 1, x));
|
||||
y = Math.max(0, Math.min(meta.h - 1, y));
|
||||
return { x: Math.round(x), y: Math.round(y), w: meta.w, h: meta.h };
|
||||
}
|
||||
|
||||
// 统一发包:point 用帧坐标,screenSize 用帧宽高
|
||||
function sendPointer(udid, index, action /* 0 down,1 up,2 move */, x, y) {
|
||||
const meta = frameMeta.value[udid] || { w: 320, h: 720, rotation: 0 };
|
||||
const payload = {
|
||||
type: 2,
|
||||
action,
|
||||
pointerId: 0,
|
||||
position: { point: { x, y }, screenSize: { width: meta.w, height: meta.h } },
|
||||
pressure: action === 1 ? 0 : 1,
|
||||
buttons: action === 1 ? 0 : 1,
|
||||
};
|
||||
const ws = getWs(index);
|
||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||
ws.send(toBuffer(payload));
|
||||
}
|
||||
}
|
||||
|
||||
return { canvasRef, frameMeta, initCanvas, getCanvasCoordinate, sendPointer };
|
||||
}
|
||||
Reference in New Issue
Block a user