Help us understand the problem. What is going on with this article?

本当は怖い HTML5 Canvas の Retina対応

More than 5 years have passed since last update.

モバイル向けに、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だけとか)の場合は気にする必要なしッ

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした