修正:H5 按钮按下缩放真因是触摸→鼠标时序,改用 shim(移除上一版无用的合成保活)
真因(真机定位,更正 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) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
5d21cc7d65
commit
0caf3853af
@@ -100,29 +100,33 @@ export class WebSlot {
|
|||||||
|
|
||||||
onPageEnd(): void {
|
onPageEnd(): void {
|
||||||
this.bridgeCtrl?.onPageEnd();
|
this.bridgeCtrl?.onPageEnd();
|
||||||
this.injectCompositingKeepAlive();
|
this.injectTouchMouseShim();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 🔴 合成保活(修复 H5 内 canvas 动画"定格不上屏")。
|
* 🔴 触摸→鼠标时序修正 shim(修复 H5 引擎"按钮按下缩放"等鼠标驱动效果在触摸下失效)。
|
||||||
* 现象:ArkWeb 默认 ASYNC 渲染下,H5 用 requestAnimationFrame 逐帧重绘 <canvas>(JS 在跑、
|
* 现象:引擎(gameabc)的按下缩放绑在 mousedown(缩小)/mouseup(还原)。Android WebView 触摸合成的
|
||||||
* 像素在变),但 ArkWeb 判定"组件内容未变"不再产出新合成帧,于是 canvas 更新不上屏——
|
* 鼠标事件按真实按住时长跨开,而 ArkWeb 触摸把合成的 mousedown/mouseup **挤在抬手后的 ~12ms 内**,
|
||||||
* 表现为按钮按下缩放等 canvas 动画定格(连上 DevTools 会强制持续合成,故调试时正常)。
|
* 致缩放一闪而过看不见;click 正常故功能无碍。(chrome://inspect 用真鼠标,时序正常,故调试时正常。)
|
||||||
* 修法(H5 零改动,原生注入):插入一个不可见、独立合成层(will-change:transform)的 1px 元素,
|
* 修法(H5 零改动,原生注入):preventDefault(touchstart) 抑制 ArkWeb 那套**错时**的原生合成鼠标事件,
|
||||||
* 每帧微动其 transform,强制 ArkWeb 持续产出合成帧,把 canvas 一并刷上屏(等效 DevTools 效果)。
|
* 改由 pointer 事件按真实时序补发 mousedown/mousemove/mouseup/click(仅 touch 指针)——单次、时序正确,
|
||||||
* rAF 在页面不可见/后台时自动暂停,故仅前台活跃期有开销。每次 onPageEnd 注入,window.__arkKA 幂等。
|
* 不会重复触发。引擎仅监听鼠标事件(触摸时序本正确却失效即证),故无双触发。每次 onPageEnd 注入,幂等。
|
||||||
*/
|
*/
|
||||||
private injectCompositingKeepAlive(): void {
|
private injectTouchMouseShim(): void {
|
||||||
const script: string =
|
const script: string =
|
||||||
"(function(){if(window.__arkKA)return;window.__arkKA=1;" +
|
"(function(){if(window.__msShim)return;window.__msShim=1;" +
|
||||||
"var d=document.createElement('div');" +
|
"function fire(type,ev){var t=ev.target||document.elementFromPoint(ev.clientX,ev.clientY)||document.body;" +
|
||||||
"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';" +
|
"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}));}" +
|
||||||
"function add(){var r=document.body||document.documentElement;if(!r){setTimeout(add,50);return;}r.appendChild(d);" +
|
"var down=false;" +
|
||||||
"var n=0;(function t(){n^=1;d.style.transform='translateZ(0) translateX('+n+'px)';requestAnimationFrame(t);})();}add();})();";
|
"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 {
|
try {
|
||||||
this.controller.runJavaScript(script);
|
this.controller.runJavaScript(script);
|
||||||
} catch (e) {
|
} 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}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user