🧊

iOSなどでアニメーションさせるとチラつく

いったい何度同じ過ちを繰り返せば気が済むんだという感じになったのでメモ。


スマートフォンで要素の拡大・縮小やら移動やらするときに気をつけたいのは以下。

  • GPUアクセラレータが効く方法を選ぶ
  • アニメーションさせる要素数を厳選する
  • Defferdなど、時と場合によっては擬似的に遅らせたりする

・・・でもメモしたいのはもっと手前の凡ミス。

2次元方向の移動だとしても

ダメな例

.moveX {
    -webkit-transform: translateX(20px);
}

.moveY {
    -webkit-transform: translateY(20px);
}

良い例

.moveX {
    -webkit-transform: translate3d(20px, 0, 0);
}
.moveY {
    -webkit-transform: translate3d(0, 20px, 0);
}

3dでのアニメーションだと無理やり指定することで、チラつきが回避できる模様。
GPUアクセラレータのスイッチが切り替わるタイミングでチラつくらしい。

で、今回のメモ本題

例えばアニメーションさせるやり方として、JavaScriptで特定のクラスを付与したらアニメーション!っていう場合に、元のアニメーション前の要素に対して、

.translate {
    -webkit-transform: translate3d(0, 0, 0);
}

としておくと、3dでアニメーション:GPUで!と指定できる・・とやってたけどそもそも。

.translate {
    -webkit-transform-style: preserve-3d;
}

コレで良いらしい。
今まで見る度に何の意味があんねやろーって思ってたけど、こういうことやったのね!
(一応この指定をしていこうとは思うものの、なんだかもやもやが残るのよね。)

参考:CSS 3D Transforms


そしてさらに、最近のiOS6はこうなってるらしい。

参考:iOS6 html hardware acceleration changes and how to fix them | indiegamr

なんだか冗長になったわね・・。

.translate {
    /*-webkit-transform-style: preserve-3d;*/
    -webkit-transform: translateZ(0);
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
}