diff --git a/entry/src/main/ets/web/WebSlot.ets b/entry/src/main/ets/web/WebSlot.ets index f9b527d..dcfb9bf 100644 --- a/entry/src/main/ets/web/WebSlot.ets +++ b/entry/src/main/ets/web/WebSlot.ets @@ -100,6 +100,30 @@ export class WebSlot { onPageEnd(): void { this.bridgeCtrl?.onPageEnd(); + this.injectCompositingKeepAlive(); + } + + /** + * 🔴 合成保活(修复 H5 内 canvas 动画"定格不上屏")。 + * 现象:ArkWeb 默认 ASYNC 渲染下,H5 用 requestAnimationFrame 逐帧重绘 (JS 在跑、 + * 像素在变),但 ArkWeb 判定"组件内容未变"不再产出新合成帧,于是 canvas 更新不上屏—— + * 表现为按钮按下缩放等 canvas 动画定格(连上 DevTools 会强制持续合成,故调试时正常)。 + * 修法(H5 零改动,原生注入):插入一个不可见、独立合成层(will-change:transform)的 1px 元素, + * 每帧微动其 transform,强制 ArkWeb 持续产出合成帧,把 canvas 一并刷上屏(等效 DevTools 效果)。 + * rAF 在页面不可见/后台时自动暂停,故仅前台活跃期有开销。每次 onPageEnd 注入,window.__arkKA 幂等。 + */ + private injectCompositingKeepAlive(): 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();})();"; + try { + this.controller.runJavaScript(script); + } catch (e) { + WebSlot.log.w(`[${this.role}] keep-alive inject failed: ${(e as BusinessError).message}`); + } } /** 渲染子进程退出(崩溃/被杀/OOM):重载本 Web 恢复,防白屏(T-M5-04)。