0

几周前,我在 Android 中遇到了一个错误,如果您使用 css 在本机 Android 浏览器(WebKit 534.4)上放置一个画布元素,position:absolute; top:10px; left:100px;则将复制的 Canvas(显然 android 使用一个用于 GPU 加速)呈现给浏览器而忽略定位。

因此,如果我的位置有一个画布,top:100px; left:100px;我的画布将完美地放置在适当的位置,但 GPU 加速画布将忽略它并将位于左上角(请参阅我之前的问题中的图像

Android本机浏览器复制HTML5画布(在chrome中很好)

我找到了一个解决方案,改为使用 CSS 翻译,就像这样,transform: translate(100px, 100px);现在解决了这个问题,因为 GPU 加速画布呈现在同一个地方(所以它不会出现重复)......

但作为一种连锁效应,我现在有一个点击错误。

由于我将画布居中,当窗口宽度小于设备宽度时,X 位置将为负值,发生这种情况时画布的唯一可点击区域是在没有定位的情况下显示的区域。

这很难解释,但希望这张图片能让它更清楚

点击错误

我认为这是浏览器本身的问题,因为即使我有这段代码,警报也不会从屏幕的一半触发

canvas.addEventListener('click', function(e) { alert('click'; });


我猜 CSS 位置 top 和 left 使用 CPU 移动画布,因此 GPU 生成的画布在错误的位置,但 CSS translate 使用 GPU 移动画布,因此 GPU 生成的画布正确定位但 CPU 是在没有此偏移的情况下读取鼠标事件........AHHHHH!


编辑:在更多设备上进行测试后,我可以确认这似乎是使用低于 535 的 webkit 版本的浏览器的问题,因为此问题出现在大多数 Android 本机浏览器和 iOS5 上的 Safari 上

4

1 回答 1

0

好的,我已经解决了这个问题,但我认为它非常具体。

if(webKitVer < 535) {
     document.body.style.paddingTop = pos.top + "px";
    if(canSeeWholeOfCanvas) {
        canwrap.style.transform = 'translateX('+pos.left+'px)';
        canwrap.style.left = 'auto';
    } else {
        canwrap.style.left = pos.left + "px";
        canwrap.style.transform  = 'none';
    }
} 
else 
{
    //standard all browsers
    canwrap.style.transform = 'translate('+pos.left+'px, '+pos.top+'px)';
}

感觉很hacky,具体案例且难以解释。但它有效


在旧的 webkit 浏览器中(通常是 Android 原生浏览器和 IOS5 safari 有两个 bug

如果画布位于 css 顶部和左侧,则将呈现重复的 GPU 渲染画布(为 GPU 硬件加速而生成)而忽略它们的属性,因此它们没有正确对齐。

如果画布使用 css 变换定位,则 GPU 复制画布正确对齐,但是当画布位于负 X 位置时,只有没有 css 可见的画布部分是可点击的

因此需要根据画布的可见性在两者之间进行更改

于 2013-10-23T11:32:07.657 回答