Canvasのサイズを CSS3の「vw」「vh」で取得してみたサンプル
(サイズ取得はできるが、描画の単位が誤解釈されているよう...)
このサンプルの背景の Canvasサイズの取得には CSS3の「vw」「vh」を使いました。
「描画部分」は、サンプル2 と同じ(ほぼ。状況に合わせて微調整しました)です。
Canvasサイズの取得そのものはウマくいったのですが、せっかくの Canvasの描画がボケちゃって変です。
描画部分の「ピクセル単位」が「ビューポートの割合の単位」に解釈されているようです。とにかく描画の単位がピクセルではなくなっていました(詳細はJavaScriptソースの部分で)。
それにしても、なぜ「ボケる」んだろう。100分の1で作って拡大して描画しているのでしょうか? そこを、ウマく処理するJavaScriptもあるのかもしれませんが...。
(「vw」「vh」に関しては、このページの末尾に詳細↓ )
まずは、今回肝心の CSSです。
Canvasに「width:100vw; height:100vh;」を指定しています。
body{
width:100%;
margin: 0;
padding: 0;
color: rgba(0,0,0,0.7);}
canvas {
width:100vw;
height:100vh;
min-height:100vh;
overflow: hidden;
position: fixed;}
#container {
position: absolute;
top:0;
right:20px;
left:20px;}
次にJavaScriptソース。
サンプル2と違って div#wrapper は生成せず、Canvasのみを作って、親ノードbodyの中の、div#containerの前に挿入します。
$(function () {
Draw();
$(window).resize(function() {
Draw();
});
});
//ここからロード時・リサイズ時の処理
function Draw() {
// bodyを親とするノード内で、新しくcanvasのみ作る
var bodyNode = document.getElementsByTagName('body').item(0);
var containerNode = document.getElementById('container');
var newCanvas = document.createElement('canvas');
// 新しく作ったcanvasを#containerの前に挿入する
bodyNode.insertBefore(newCanvas, containerNode);
// canvasへの描画(ここからはサンプル2の描画を流用しています)
var ctx = newCanvas.getContext('2d');
var cW = newCanvas.width, //canvasの幅
cH = newCanvas.height; //canvasの高さ
// canvasの背景を黒に
ctx.fillStyle = "rgba(0,0,0,1)";
ctx.fillRect(0,0,cW,cH);
// ランダムな始点・終点、カラーのラインを複数描く
ctx.globalCompositeOperation = "lighter";
ctx.lineWidth = 30;
for (i=0; i<50; i++){/*線の本数がこの状態のとき*/
var lsX = Math.round(Math.random()*cW*100),
leX = Math.round(Math.random()*cW-100),
lsY = Math.round(Math.random()*cH*100),
leY = Math.round(Math.random()*cH-100),
r = Math.round(Math.random()*255),
g = Math.round(Math.random()*255),
b = Math.round(Math.random()*255);
ctx.beginPath();
ctx.strokeStyle = "rgba("+r+","+g+","+b+",0.15)";
ctx.moveTo(lsX,lsY);
ctx.lineTo(leX,leY);
ctx.stroke();
}
};
上のソースで、
26行目「ctx.lineWidth = 30;」は線の太さですが、これはサンプル2では「150(px)」でした。
(この背景は、太いラインをランダムに描画して作っています)
ですが、このサンプルでこのまま150だと、線が太すぎて背景がほとんどまっ白に(「ctx.globalCompositeOperation = "lighter";」の影響で)。
150pxを150vw (または150vh) に解釈しているようです。
「単位」が、ピクセルじゃなくなっているのかも?と思い、数値を小さくしてみたところ、今のような描画になりました。
また、28〜31行目は、線の始点・終点をランダムに決めるための変数ですが、これはサンプル2のまま「100(px)」にしています。が、これも、ピクセルではなく vw (またはvh) で反応しています。
HTMLはこちら。サンプル2 と同じで、canvas要素はHTML上に書きません。
<body>
<div id="container"> <!--ここにコンテンツ--> </div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
<!-- ↑ jQueryは、ウィンドウのリサイズで使うので必要です-->
<script><!--ここにcanvas用のスクリプト--></script>
</body>
それぞれの冒頭の「v」は「Viewport」の頭文字。
ビューポートとは、ブラウザの表示領域のこと。PC用のブラウザならウィンドウサイズ。タブレットやスマホは、液晶画面のサイズではなく、デバイスごとに決められた表示領域がある。しかも、同じデバイスでも機種やOS・ブラウザによって表示領域が違うので、「Viewport」という概念が無いとスタイルの指定が難しい(ので、できたんでしょうね。「Viewport」)
で、この「vw、vh、vmin、vmax」という単位の詳細はこちら
pxやemといった単位と違って、表示領域の幅か高さのパーセンテージの単位。
親要素に対するパーセンテージではなく、ビューポートに対してなので、モバイルでの表示領域のサイズに臨機応変に対応できるメリットがあります。
モバイルビューで、ピクセル計算する事無く「横半分を画像」などとレイアウトすることもできる、便利な単位です。
「vw」「vh」の各ブラウザの対応はこちら:Can I use...Support tables for HTML5, CSS3, etc