LoginSignup
172
168

More than 5 years have passed since last update.

本当は怖い HTML5 Canvas の Retina対応

Last updated at Posted at 2013-04-23

モバイル向けに、Canvasでつくったゲームを
Retinaディスプレイ対応をしたときにハマったこと。

CanvasのRetina対応は一筋縄にはいかないッ

基本的にCanvasのRetina対応は以下のように、
実際のサイズの2倍のサイズでつくったCanvas要素を、CSSで実際のサイズに縮める。

HTML
<canvas id="sample_canvas" width="640" height="800" style="width: 320px; height: 400px"></canvas>

これで、Retinaディスプレイできれいに表示できる。
しかし、このままでは以下のような問題が起きちゃう。

  • 2倍のサイズのCanvasに描画を行うため、処理が重くなる
  • そのため 一部のAndroid端末にて、ブラウザが落ちる、端末が発熱する
  • 一部のAndroid端末にて、Canvas要素のstyle属性を動的に変更するとブラウザが落ちる

そこで、Retina以外の端末向けに、処理の切り分けが必要になる。
Canvas要素は実際のサイズ。Canvas上の座標系をあわせるために、
Canvasのscaleを0.5にする。

HTML
<canvas id="sample_canvas" width="320" height="400"></canvas>
JavaScript
var canvas  = document.getElementById("sample_canvas");
var context = canvas.getContext("2d");

context.scale(0.5,0.5);

これで、Canvas内の座標は同じ数値を指定できるようになる。

window.devicePixelRatioの値に応じてCanvasサイズを決める方法もあるが、
上記のstyle属性をいじると落ちるバグがあるため、
iOSのRetinaディスプレイとそれ以外で切り分けるのがおすすめ。


その他 注意すること

widthとheightは変更しない

一部のAndroid端末では、Canvas要素のwidthとheightを変更すると、
Canvasの描画が2重になり、clearRect してもクリアされないというバグがある。

一度設定したwidthとheightは変更しないッ(再代入はOK

drawImage での縮小だと画像がボケる

Canvas APIのdrawImageでも、2倍の大きさの画像を実際のサイズに縮小して表示できる。

JavaScript
var image = new Image();

image.src = "sample.png"; // 実際のsample.pngのサイズ 200x200

image.addEventListener("load", function() {

    context.drawImage(image,0,0,100,100); // 半分のサイズを指定

}, false);

しかし、これだとCanvas上のピクセルは2倍にならないため
Retinaディスプレイでは画像がボケる。


まとめ

今回は、Android端末にも広く対応を考えた場合に必要な話なので、
対応端末が限られる場合(iOSだけとか)の場合は気にする必要なしッ

とはいえ、結構シェアの高い端末でも発生する問題だったりします...!

172
168
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
172
168