如何避免iPad上可触摸拖动的border-radius元素上的动画瑕疵?

Pau*_*ite 7 javascript css css3 touch-event ios

我写了一个小例子页面,其中包含可在触摸设备上拖动的元素(基于Peter-Paul Koch编写的代码).

我有两个可拖动的<div>元素:一个绿色块和一个红色球(用球形制成border-radius).拖动与实施ontouchstart,ontouchmove以及ontouchend和"动漫"是通过改变完成topleft这些元素的CSS属性.

当我拖动绿色的时候,一切都是玫瑰和ponycorns.

但是当我在Safari 1(运行iOS 5.1.1)或iPad 3(6.0.1)上拖动Safari中的红色时,我会得到一些浅红色的小径,其中圆圈的后边缘(见下面的截图).

但是,我不会在iPhone 5(6.1.4)上看到这些路径.

我的元素上使用border-radius的工件

有没有办法摆脱这些痕迹?

(奖金问题:这个效果是否有一个术语?"重影"?"文物"?)

Jor*_*ray 16

修复

将此规则添加到#bawl { … }规则集:

-webkit-transform: translateZ(0);
Run Code Online (Sandbox Code Playgroud)

(如果您需要避免硬件加速,可以使用outline: 1px solid transparent- 有关详细信息,请参阅我对类似问题的回答.)

这删除了拖尾的文物,但为什么呢?它是Quartz(iOS中的绘图引擎)的组合,不会将抗锯齿线条剪切到形状的边缘,以及WebKit在部分网页更改后重新绘制网页的方式.

绘制网页

首先,快速和(过度)简化了WebKit如何从DOM节点树获取到表示渲染网页的位图图像.

您已经知道网页被解析为一个元素树,称为DOM.DOM中的每个节点都以某种方式呈现,具体取决于应用于它的样式.节点可能与其他节点重叠或重叠,具体取决于z顺序,透明度,溢出,定位等.

这大致类似于引擎盖下的工作方式.WebKit将每个DOM节点映射到相应的DOM节点RenderObject,该节点具有绘制单个DOM节点所需的所有信息.每个RenderObject都映射到它自己的或祖先的RenderLayer,这是一种处理节点如何"分层"的概念方式 - 在其他节点之上或之下绘制.

为了呈现网页,每个网页RenderLayer都是按照z顺序从后到前绘制的.首先绘制该层后面的孩子,然后是层本身,然后是前面的孩子.为了绘制自己,在RenderLayer相应的RenderObjects 上调用paint方法.

WebKit有两个用于呈现给定的代码路径RenderLayer:软件路径和硬件加速路径.软件路径将每个RenderObject直接绘制到您在浏览器中看到的渲染网页的图像,而硬件路径允许将某些RenderLayers指定为合成图层,这意味着它和它的子画面分别绘制并最终合成为单个GPU的图像.只要RenderLayer页面上的一个或多个s需要硬件加速,或者浏览器中的标志明确要求(例如Chrome),就会使用硬件路径.

更新网页的一部分

当动画或其他事件更改页面的部分外观时,您不希望重绘整个网页.相反,WebKit在更改的区域周围绘制一个框 - 损坏矩形 - 并且只重绘每个RenderLayer与该框重叠的位.RenderLayer完全跳过不与损伤矩重叠的A.

如果您通过软件路径进行渲染,WebKit会直接将损坏矩形重新组合到完整渲染页面的位图图像上,而不会更改图像的其余部分.但是,硬件路径会分别重新绘制每个合成图层,并将它们重新组合成新图像.

出了什么问题

translateZ修复将3D变换应用于元素.这迫使RenderLayer绘制球需要硬件加速,这意味着WebKit将使用硬件路径而不是软件路径.这意味着该问题与使用软件路径有关.

球被涂漆时,边界半径意味着边缘消除锯齿.由于与Quartz相关已知问题,形状的边缘是消除锯齿的,因此当您更改球在页面上的位置时,某些像素落在损伤矩形之外.使用软件路径,浏览器仅重绘已渲染页面图像的更改区域,而保持图像的其余部分不变.落在此区域之外的半透明像素将不会更新,这可以解释移动球时留下的人工制品.

相比之下,硬件路径分别重绘该层(及其子层),然后重新组合页面.从上次渲染图层时没有留下"鬼像素".

TL; DR

当WebKit使用软件渲染路径时,对页面的一部分的更改将直接对表示整个页面的图像进行.出于性能原因,WebKit仅重绘已更改的图像部分.但是,当Quartz绘制一个圆角矩形时,它会对边缘进行反锯齿,使得某些像素落在WebKit知道要重绘的区域之外.修复方法是通过应用3D变换强制该层需要硬件加速,这意味着该元素与页面的其余部分分开绘制并在之后重新组合.