fix(wanglanmei-ref): 双修真输入坐标断层——页面壳状态行改浮层(canvas顶到0,0满幅,旧布局下推29px且裁底致真机底部按钮不可点)+driver加rect坐标映射(zone canvas系→页面CSS系),轨迹双系留痕
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
43623609bd
commit
572b3721b5
@ -25,29 +25,35 @@
|
||||
font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
overflow: hidden;
|
||||
}
|
||||
/* 收编修(轮1评估段):状态行改浮层、wrap 零内边距——canvas 必须顶在 (0,0) 满幅 390×844。
|
||||
旧 flex 列布局把 canvas 下推 ≈29px:e2e 真输入坐标整体偏移,且 844 视口裁掉 canvas 底部 29px
|
||||
(真机亲玩底部按钮点不到)。状态行 pointer-events:none 防截触摸。 */
|
||||
#wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 0;
|
||||
position: relative;
|
||||
width: 390px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
#game {
|
||||
width: 390px;
|
||||
height: 844px;
|
||||
background: #f6e7c9;
|
||||
display: block;
|
||||
border-radius: 8px;
|
||||
touch-action: none; /* 触摸全交 JS(pointer 桥接),禁浏览器默认手势 */
|
||||
}
|
||||
#status {
|
||||
position: absolute; /* 浮层叠于 canvas 顶部,不占布局流 */
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 2;
|
||||
pointer-events: none; /* 绝不截触摸 */
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
min-height: 15px;
|
||||
max-width: 390px;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
opacity: 0.85;
|
||||
text-shadow: 0 1px 2px rgba(46, 35, 27, 0.8); /* 深底浮字可读性 */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@ -103,11 +103,27 @@ async function listZones(phaseTag) {
|
||||
if (phaseTag) evidence.zonesSeenByPhase[phaseTag] = zs.map((z) => z.id);
|
||||
return zs;
|
||||
}
|
||||
/** CDP 真触摸点按(touchStart→touchEnd 成对;轨迹留痕)。 */
|
||||
/* 坐标映射:geometry() 的 zone 坐标在 canvas 逻辑空间(VIEW),CDP dispatch 用页面 CSS 坐标。
|
||||
首跑实翻教训:页面壳曾把 canvas 下推 ≈29px,zone 坐标直发全部偏移 → 一律经 rect 映射换算。 */
|
||||
let MAP = { l: 0, t: 0, sx: 1, sy: 1 };
|
||||
async function initMapping() {
|
||||
const m = await cdp.evaluate(`(function(){
|
||||
var c = document.getElementById('game'); var r = c.getBoundingClientRect();
|
||||
var dpr = window.devicePixelRatio || 1;
|
||||
return { l: r.left, t: r.top, w: r.width, h: r.height, vw: c.width / dpr, vh: c.height / dpr };
|
||||
})()`);
|
||||
MAP = { l: m.l, t: m.t, sx: m.w / m.vw, sy: m.h / m.vh };
|
||||
evidence.meta.coordMap = { rect: m, map: MAP };
|
||||
console.log(' · 坐标映射:', JSON.stringify(evidence.meta.coordMap));
|
||||
}
|
||||
const toClient = (x, y) => ({ x: MAP.l + x * MAP.sx, y: MAP.t + y * MAP.sy });
|
||||
|
||||
/** CDP 真触摸点按(touchStart→touchEnd 成对;轨迹留痕,zone 系与页面系双记)。 */
|
||||
async function tapAt(x, y, zoneId) {
|
||||
await cdp.send('Input.dispatchTouchEvent', { type: 'touchStart', touchPoints: [{ x, y }] });
|
||||
const c = toClient(x, y);
|
||||
await cdp.send('Input.dispatchTouchEvent', { type: 'touchStart', touchPoints: [{ x: c.x, y: c.y }] });
|
||||
await cdp.send('Input.dispatchTouchEvent', { type: 'touchEnd', touchPoints: [] });
|
||||
trajectory.push({ seq: trajectory.length, wallMs: Date.now(), kind: 'tap', zoneId: zoneId || null, x, y });
|
||||
trajectory.push({ seq: trajectory.length, wallMs: Date.now(), kind: 'tap', zoneId: zoneId || null, x, y, clientX: c.x, clientY: c.y });
|
||||
await delay(90); // 让真事件经浏览器→输入桥落地
|
||||
await stepFrames(3); // 推帧消化(反馈注册/状态机流转)
|
||||
}
|
||||
@ -119,16 +135,17 @@ async function tapZone(id) {
|
||||
await tapAt(z.x, z.y, id);
|
||||
return true;
|
||||
}
|
||||
/** 真触摸拖拽(touchStart→分段 touchMove→touchEnd;价格滑条用)。 */
|
||||
/** 真触摸拖拽(touchStart→分段 touchMove→touchEnd;价格滑条用;坐标同样经 rect 映射)。 */
|
||||
async function dragTouch(x0, y0, x1, y1, zoneId, steps = 8) {
|
||||
await cdp.send('Input.dispatchTouchEvent', { type: 'touchStart', touchPoints: [{ x: x0, y: y0 }] });
|
||||
const a = toClient(x0, y0), b = toClient(x1, y1);
|
||||
await cdp.send('Input.dispatchTouchEvent', { type: 'touchStart', touchPoints: [{ x: a.x, y: a.y }] });
|
||||
for (let i = 1; i <= steps; i++) {
|
||||
const x = x0 + ((x1 - x0) * i) / steps, y = y0 + ((y1 - y0) * i) / steps;
|
||||
const x = a.x + ((b.x - a.x) * i) / steps, y = a.y + ((b.y - a.y) * i) / steps;
|
||||
await cdp.send('Input.dispatchTouchEvent', { type: 'touchMove', touchPoints: [{ x, y }] });
|
||||
await delay(16);
|
||||
}
|
||||
await cdp.send('Input.dispatchTouchEvent', { type: 'touchEnd', touchPoints: [] });
|
||||
trajectory.push({ seq: trajectory.length, wallMs: Date.now(), kind: 'drag', zoneId: zoneId || null, x: x0, y: y0, x1, y1 });
|
||||
trajectory.push({ seq: trajectory.length, wallMs: Date.now(), kind: 'drag', zoneId: zoneId || null, x: x0, y: y0, x1, y1, clientX: a.x, clientY: a.y });
|
||||
await delay(90);
|
||||
await stepFrames(3);
|
||||
}
|
||||
@ -156,6 +173,7 @@ async function shot(name, withHash) {
|
||||
/* 门 A:boot+probe 链(FORENSICS §4-1/2) */
|
||||
cdp = await connectRef(URL_EVIDENCE);
|
||||
try {
|
||||
await initMapping(); // zone(canvas 逻辑系)→页面 CSS 系映射,一切真输入坐标经此换算
|
||||
const probe = await F('FZ.probe()');
|
||||
fs.writeFileSync(path.join(OUT_DIR, 'probe.jsonl'), (probe.jsonl || '') + '\n');
|
||||
check(probe.verify && probe.verify.ok === true, `probe 链 verify.ok(实际:${JSON.stringify(probe.verify)})`);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user