0

数週間前にAndroidでバグに遭遇しました.cssを使用してネイティブAndroidブラウザー(WebKit 534.4)にキャンバス要素を配置position:absolute; top:10px; left:100px;すると、複製されたキャンバス(明らかにAndroidはGPUアクセラレーションに1つを使用します)を無視してブラウザーにレンダリングされます.ポジショニング。

したがって、位置top:100px; left:100px;にキャンバスがある場合、キャンバスは完全に配置されますが、GPU アクセラレーション キャンバスはそれを無視し、左上隅に配置されます (前の質問の画像を参照してください)。

HTML5 キャンバスを複製する Android ネイティブ ブラウザ (Chrome では問題ありません)

代わりにCSS変換を使用する解決策を見つけました。このようにtransform: translate(100px, 100px);、GPUアクセラレーションキャンバスが同じ場所にレンダリングされるため、問題が修正されます(重複しているようには見えません)...

しかし、ノックオン効果として、クリックバグが発生しました。

キャンバスを中央に配置すると、ウィンドウの幅がデバイスの幅よりも小さい場合、X 位置は負の値になります。これが発生したときにキャンバスの唯一のクリック可能な領域は、配置なしで表示されるものです。

これを説明するのは難しいですが、うまくいけば、この画像がより明確になります

クリックバグ

このコードを使用しても、画面の半分からアラートが発生しないため、ブラウザ自体の問題だと思います

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


私はCSSの位置が上と左でCPUを使用してキャンバスを移動するため、GPUで生成されたものは間違った場所にあると推測していますが、CSS変換はGPUを使用してキャンバスを移動するため、GPUで生成されたものは正しく配置されますが、CPUはこのオフセットなしでマウス イベントを読み取る.........ああああああ!


編集: より多くのデバイスでテストした後、この問題はほとんどの Android ネイティブ ブラウザーと iOS5 の Safari で発生するため、535 未満の webkit のバージョンを使用するブラウザーで問題であるように見えることを確認できます。

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)';
}

ハックで、ケース固有で、説明が難しいと感じます。しかし、それは動作します


古い W​​ebkit ブラウザ (一般に Android ネイティブ ブラウザと IOS5 サファリには 2 つのバグがあります)

キャンバスが css の上と左に配置されている場合、複製された GPU でレンダリングされたキャンバス (GPU ハードウェア アクセラレーション用に生成されたもの) がそれらのプロパティを無視してレンダリングされるため、正しく配置されません。

キャンバスが css 変換で配置されている場合、GPU 複製キャンバスは正しく配置されていますが、キャンバスがマイナス X 位置に配置されている場合、css なしで表示されるキャンバスの部分のみがクリック可能です。

そのため、キャンバスの可視性に応じて 2 つの間で変更する必要があります

于 2013-10-23T11:32:07.657 に答える