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

前端之家收集整理的这篇文章主要介绍了javascript – 如何在iPad上的触控可拖动border-radius元素上避免动画瑕疵?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我写了一个小例子页面,其中包含可在触摸设备上拖动的元素(基于 code by Peter-Paul Koch).

> My example page

我有两个可拖动的< div>元素:绿色块和红色球(球形边界半径).使用ontouchstart,ontouchmove和ontouchend实现拖动,并通过更改这些元素的顶部和左侧CSS属性来完成“动画”.

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

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

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

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

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

解决方法

修复

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

-webkit-transform: translateZ(0);

(如果您需要避免硬件加速,可以使用outline:1px solid transparent-有关更多详细信息,请参阅my answer to a similar question.)

这消除了拖尾的人工制品,但为什么呢?它是Quartz (the drawing engine in iOS)的组合,不会将抗锯齿线剪裁到形状的边缘,以及WebKit在部分网页更改后重新绘制网页的方式.

绘制网页

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

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

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

要渲染网页,每个RenderLayer都是按z顺序从后到前绘制的.首先绘制该层后面的孩子,然后是层本身,然后是前面的孩子.要绘制自身,RenderLayer会在其相应的RenderObjects上调用paint方法.

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

更新网页的一部分

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

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

出了什么问题

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

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

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

TL; DR

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

猜你在找的JavaScript相关文章