From 0caf3853af38e44cbcfcf4458bd5e4d88f6aa34b Mon Sep 17 00:00:00 2001 From: lanterngamescn Date: Sat, 27 Jun 2026 00:43:08 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=EF=BC=9AH5=20=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E6=8C=89=E4=B8=8B=E7=BC=A9=E6=94=BE=E7=9C=9F=E5=9B=A0?= =?UTF-8?q?=E6=98=AF=E8=A7=A6=E6=91=B8=E2=86=92=E9=BC=A0=E6=A0=87=E6=97=B6?= =?UTF-8?q?=E5=BA=8F=EF=BC=8C=E6=94=B9=E7=94=A8=20shim=EF=BC=88=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E4=B8=8A=E4=B8=80=E7=89=88=E6=97=A0=E7=94=A8=E7=9A=84?= =?UTF-8?q?=E5=90=88=E6=88=90=E4=BF=9D=E6=B4=BB=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 真因(真机定位,更正 5d21cc7):引擎(gameabc)按下缩放绑 mousedown(缩小)/mouseup(还原)。 Android WebView 触摸合成的鼠标事件按真实按住时长跨开;ArkWeb 把合成的 mousedown/mouseup **挤在抬手后 ~12ms 内** → 缩放一闪而过看不见(click 正常故功能无碍)。chrome://inspect 用真鼠标 时序正常,故"调试时正常、真机直接点不动"。 实测证伪上一版"合成保活"假设:无保活时注入的连续 canvas 动画照样逐帧上屏(5 帧 md5 全不同), 故 ArkWeb 不存在 canvas 合成节流问题,合成保活无必要、已移除(省去 60fps 持续合成的耗电)。 修法(H5 零改动,原生注入,onPageEnd,仅大厅/子游戏容器):preventDefault(touchstart) 抑制 ArkWeb 那套错时的原生合成鼠标事件,改由 pointer 事件按真实时序补发 mousedown/mousemove/mouseup/click (仅 touch 指针),单次、时序正确、不重复触发,并支持拖动。真机验证:按下缩放正常、登录单次触发、 拖动正常。 Co-Authored-By: Claude Opus 4.8 (1M context) --- entry/src/main/ets/web/WebSlot.ets | 34 +++++++++++++++++------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/entry/src/main/ets/web/WebSlot.ets b/entry/src/main/ets/web/WebSlot.ets index dcfb9bf..6c3f05d 100644 --- a/entry/src/main/ets/web/WebSlot.ets +++ b/entry/src/main/ets/web/WebSlot.ets @@ -100,29 +100,33 @@ export class WebSlot { onPageEnd(): void { this.bridgeCtrl?.onPageEnd(); - this.injectCompositingKeepAlive(); + this.injectTouchMouseShim(); } /** - * 🔴 合成保活(修复 H5 内 canvas 动画"定格不上屏")。 - * 现象:ArkWeb 默认 ASYNC 渲染下,H5 用 requestAnimationFrame 逐帧重绘 (JS 在跑、 - * 像素在变),但 ArkWeb 判定"组件内容未变"不再产出新合成帧,于是 canvas 更新不上屏—— - * 表现为按钮按下缩放等 canvas 动画定格(连上 DevTools 会强制持续合成,故调试时正常)。 - * 修法(H5 零改动,原生注入):插入一个不可见、独立合成层(will-change:transform)的 1px 元素, - * 每帧微动其 transform,强制 ArkWeb 持续产出合成帧,把 canvas 一并刷上屏(等效 DevTools 效果)。 - * rAF 在页面不可见/后台时自动暂停,故仅前台活跃期有开销。每次 onPageEnd 注入,window.__arkKA 幂等。 + * 🔴 触摸→鼠标时序修正 shim(修复 H5 引擎"按钮按下缩放"等鼠标驱动效果在触摸下失效)。 + * 现象:引擎(gameabc)的按下缩放绑在 mousedown(缩小)/mouseup(还原)。Android WebView 触摸合成的 + * 鼠标事件按真实按住时长跨开,而 ArkWeb 触摸把合成的 mousedown/mouseup **挤在抬手后的 ~12ms 内**, + * 致缩放一闪而过看不见;click 正常故功能无碍。(chrome://inspect 用真鼠标,时序正常,故调试时正常。) + * 修法(H5 零改动,原生注入):preventDefault(touchstart) 抑制 ArkWeb 那套**错时**的原生合成鼠标事件, + * 改由 pointer 事件按真实时序补发 mousedown/mousemove/mouseup/click(仅 touch 指针)——单次、时序正确, + * 不会重复触发。引擎仅监听鼠标事件(触摸时序本正确却失效即证),故无双触发。每次 onPageEnd 注入,幂等。 */ - private injectCompositingKeepAlive(): void { + private injectTouchMouseShim(): void { const script: string = - "(function(){if(window.__arkKA)return;window.__arkKA=1;" + - "var d=document.createElement('div');" + - "d.style.cssText='position:fixed;left:0;top:0;width:1px;height:1px;opacity:0.02;pointer-events:none;z-index:2147483647;will-change:transform';" + - "function add(){var r=document.body||document.documentElement;if(!r){setTimeout(add,50);return;}r.appendChild(d);" + - "var n=0;(function t(){n^=1;d.style.transform='translateZ(0) translateX('+n+'px)';requestAnimationFrame(t);})();}add();})();"; + "(function(){if(window.__msShim)return;window.__msShim=1;" + + "function fire(type,ev){var t=ev.target||document.elementFromPoint(ev.clientX,ev.clientY)||document.body;" + + "t.dispatchEvent(new MouseEvent(type,{bubbles:true,cancelable:true,view:window,detail:1,clientX:ev.clientX,clientY:ev.clientY,screenX:ev.screenX,screenY:ev.screenY,button:0}));}" + + "var down=false;" + + "document.addEventListener('touchstart',function(e){if(e.cancelable)e.preventDefault();},{passive:false,capture:true});" + + "document.addEventListener('pointerdown',function(ev){if(ev.pointerType!=='touch')return;down=true;fire('mousedown',ev);},true);" + + "document.addEventListener('pointermove',function(ev){if(ev.pointerType!=='touch'||!down)return;fire('mousemove',ev);},true);" + + "document.addEventListener('pointerup',function(ev){if(ev.pointerType!=='touch'||!down)return;down=false;fire('mousemove',ev);fire('mouseup',ev);fire('click',ev);},true);" + + "document.addEventListener('pointercancel',function(ev){if(ev.pointerType!=='touch'||!down)return;down=false;fire('mouseup',ev);},true);})();"; try { this.controller.runJavaScript(script); } catch (e) { - WebSlot.log.w(`[${this.role}] keep-alive inject failed: ${(e as BusinessError).message}`); + WebSlot.log.w(`[${this.role}] touch-mouse shim inject failed: ${(e as BusinessError).message}`); } }