ブラウザいっぱいにCanvasを表示してあれこれやりたい
デモ, コード
スマホ用にビューポートを設定する
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
htmlのbodyにマージンが入ってしまうのを抑制する
JavaScriptでキャンバスを作成する
window.innerWidth
, window.innerHeight
でブラウザの表示領域のサイズが取得できる
- Canvasのサイズは2種類ある
canvas.style.width
が実際の表示サイズ(CSSで指定する場合と同じく、px指定)
canvas.width
が内部のサイズ
- Retinaディレスプレイの場合、
window.devicePixelRatio
が1より大きな値になっているので、
内部サイズをそれに合わせて大きくしてやるとボケずにすむ
- それらを使って、
document.createElement
で生成したキャンバスの設定をする
var canvas = document.createElement('canvas'); canvas.style.width = window.innerWidth + 'px'; canvas.style.height = window.innerHeight + 'px'; canvas.width = window.innerWidth * window.devicePixelRatio; canvas.height = window.innerHeight * window.devicePixelRatio;
|
キャンバスを配置するdiv要素を作る
ウィンドウと同じサイズのキャンバスをそのままhtmlのbodyに配置してしまうと、キャンバスの下に
勝手に謎の余白が追加されてしまい上下にスクロールできてしまう(要素がcanvasの場合だけ)。
これを防止するためにキャンバスを配置するdiv要素を作り、それをbodyに配置する。
divにはoverflow: hidden
を指定する(そうしないと同様に謎の余白が発生する)。
var container = document.createElement('div'); container.style.width = window.innerWidth + 'px'; container.style.height = window.innerHeight + 'px'; container.style.overflow = 'hidden'; container.appendChild(canvas); document.body.appendChild(container);
|
ドラッグ(スワイプ)による上下スクロール(バウンス)を防止する
iPhoneなどではスワイプで上下に動いてしまう。それを防止するために、touchstart
イベントで
event.preventDefault()
を呼び出す。それによってブラウザのデフォルト動作が抑制され、
上下スクロールしなくなる。
document.body.addEventListener('touchstart', function(event) { event.preventDefault(); });
|
デモ
問題点
- ブラウザのサイズを変更した時や、スマホでデバイスを回転させた時に追従しない
- これに関してはリサイズや
orientationchange
をハンドルすればよいでしょう
- あるAndroidでは
window.innerWidth
が公称されている解像度よりも大きな値が入っていて、
さらにdevicePixelRatio
が1.5となっているため、ロードした段階で3倍くらいで表示される。
どうしたらいいんだろう…。
Resizing the HTML5 Canvas Dynamically as the Browser Window is Resized - HTML Cheats これで動く?