キャンバスについて(HTMLCanvasElement)
キャンバスについて
■キャンバスについて
<CANVAS> タグを使用すると、キャンバスを表示することができます。
キャンバス内では、任意の描画が可能です。
<CANVAS> タグを使用してインラインフレームを設置する
<html>
<body>
<canvas width="640" height="480" >
対応していません。
</canvas>
</body>
</html>
■ HTMLCanvasElement インターフェースについて
<CANVAS> タグに相当します。
エレメントの一種です。
■ HTMLCanvasElement インターフェースの派生について
Object |
↓派生 |
EventTarget |
↓派生 |
Node |
↓派生 |
Element |
↓派生 |
HTMLElement |
↓派生 |
HTMLCanvasElement |
キャンバスを作成する
■キャンバスを作成する
■ HTMLCanvasElement オブジェクトを作成する
document.createElement() メソッドを使用します。
引数に、"canvas" を指定します。
動的に HTMLCanvasElement オブジェクトを作成する
// HTMLCanvasElement オブジェクトを作成する
var canvas = document.createElement("canvas");
// 出力テスト
console.log(canvas);
■キャンバスをブラウザに表示する
■ HTMLCanvasElement オブジェクトを、ブラウザに表示する
任意のノードリストに登録します。
キャンバスを動的に作成して、ノードリストに登録する
// HTMLCanvasElement オブジェクトを作成する
var canvas = document.createElement("canvas");
// BODY のノードリストに登録する
document.body.appendChild(canvas);
■HTMLCanvasElement オブジェクトを取得する
■静的な <CANVAS> タグから取得する
任意のエレメントを取得する方法は、こちらで解説しています。
静的な <CANVAS> タグから、HTMLCanvasElement オブジェクトを取得する
<html>
<body>
<canvas id="aaa" width="640" height="480" ></canvas>
<script type="text/javascript">
<!--
// "aaa" という ID 属性のエレメントを取得する
var canvas = document.getElementById("aaa");
// 出力テスト
console.log(canvas);
//-->
</script>
</body>
</html>
キャンバスのサイズを設定する
■キャンバスのサイズについて
キャンバスは、1枚のビットマップ領域を保有しています。
ビットマップ領域には、任意の描画が可能です。
キャンバスのサイズは、後から変更できます。
変更した場合、ビットマップ領域はクリアされます。
キャンバスのサイズと、スタイルシートのサイズは異なります。
<IMG> 要素のように、拡大縮小して表示する事ができます。
常に等倍で表示される訳ではありません。
■キャンバスのサイズを設定する
以下のプロパティを使用します。
プロパティ名 | 型 | 説明 |
width | Number | キャンバスの幅を設定する(単位:ピクセル) |
height | Number | キャンバスの高さを設定する(単位:ピクセル) |
■設定例
キャンバスのサイズを変更する
// ------------------------------------------------------------
// HTMLCanvasElement オブジェクトを作成する
// ------------------------------------------------------------
var canvas = document.createElement("canvas");
// BODY のノードリストに登録する
document.body.appendChild(canvas);
// ------------------------------------------------------------
// キャンバスのサイズを変更する
// ------------------------------------------------------------
canvas.width = 320;
canvas.height = 240;
// ------------------------------------------------------------
// スタイルシートのサイズを変更する
// ------------------------------------------------------------
// CSSStyleSheet オブジェクトを取得する
var style = canvas.style;
// スタイルシートのサイズを変更する
style.width = (640) + "px";
style.height = (480) + "px";
■ブラウザのリサイズを監視する
onresize イベントを使用します。
■使用例
キャンバスのサイズを等倍に補正する例です。
キャンバスのサイズを等倍に補正する
<html>
<body>
<canvas id="aaa" width="640" height="480" style="width:100%; height:100%;" ></canvas>
<script type="text/javascript">
<!--
// ------------------------------------------------------------
// キャンバスのサイズを等倍に補正する関数
// ------------------------------------------------------------
function CanvasResizeToSame(canvas){
var style = canvas.ownerDocument.defaultView.getComputedStyle(canvas,"");
canvas.width = Math.round(parseFloat(style.width ));
canvas.height = Math.round(parseFloat(style.height));
}
// ------------------------------------------------------------
// "aaa" という ID 属性のエレメントを取得する
// ------------------------------------------------------------
var canvas = document.getElementById("aaa");
// ------------------------------------------------------------
// CanvasRenderingContext2D オブジェクトを取得する
// ------------------------------------------------------------
var context = canvas.getContext("2d");
// ------------------------------------------------------------
// リサイズされるたびに実行されるイベント
// ------------------------------------------------------------
window.onresize = function (){
var x;
var y;
var w;
var h;
// ------------------------------------------------------------
// キャンバスのサイズを等倍に補正する
// ------------------------------------------------------------
CanvasResizeToSame(canvas);
// ------------------------------------------------------------
// クリア
// ------------------------------------------------------------
w = canvas.width;
h = canvas.height;
context.clearRect( 0 , 0 , w , h );
// ------------------------------------------------------------
// グリッドを描画する
// ------------------------------------------------------------
// 描画パスをクリア
context.beginPath();
for(x=0.5;x < w;x+=3){
// サブパスを開始(開始位置)
context.moveTo(x , 0);
// サブパスを追加(直線追加)
context.lineTo(x , h);
}
for(y=0.5;y < h;y+=3){
// サブパスを開始(開始位置)
context.moveTo(0 , y);
// サブパスを追加(直線追加)
context.lineTo(w , y);
}
// 累積された描画パスを使って、実際に線を描画する
context.stroke();
};
// 1回実行
window.onresize();
//-->
</script>
</body>
</html>
キャンバスに描画する
■キャンバスに描画する
キャンバスには、描画を行うための機能はありません。
別途、RenderingContext オブジェクトが必要です。
■ RenderingContext オブジェクトを取得する
getContext() メソッドを使用します。
HTMLCanvasElement.getContext ( "contextId" ) :*
第01引数 | String | contextId を指定。 |
戻り値 | * | 第01引数に該当する Context オブジェクトが得られる |
■第01引数(contextId)
以下の種類があります。
使い方については、リンク先で解説しています。
サポートしていない場合、戻り値は null となります。
第01引数 | 戻り値の型 | 説明 |
"2d" | CanvasRenderingContext2D | 2D 用の描画 API(Canvas 2D Context) |
"webgl" | WebGLRenderingContext | 3D 用の描画 API(WebGL) |
■Canvas 2D Context の取得例
CanvasRenderingContext2D オブジェクトを取得して、描画する
// ------------------------------------------------------------
// HTMLCanvasElement オブジェクトを作成する
// ------------------------------------------------------------
var canvas = document.createElement("canvas");
// BODY のノードリストに登録する
document.body.appendChild(canvas);
// ------------------------------------------------------------
// CanvasRenderingContext2D オブジェクトを取得する
// ------------------------------------------------------------
var context = canvas.getContext("2d");
// ------------------------------------------------------------
// 線の描画スタイルを設定する
// ------------------------------------------------------------
// 線の塗りを設定する(単一色)
context.strokeStyle = "#aa0000";
// 線の太さを設定する
context.lineWidth = 10.0;
// ------------------------------------------------------------
// 面の描画スタイルを設定する
// ------------------------------------------------------------
// 面の塗りを設定する(単一色)
context.fillStyle = "#ff8888";
// ------------------------------------------------------------
// 描画パスをクリア
// ------------------------------------------------------------
context.beginPath();
// ------------------------------------------------------------
// 描画パスを追加
// ------------------------------------------------------------
// 矩形追加
context.rect( 10 , 10 , 120 , 100 );
// 矩形追加
context.rect( 50 , 30 , 120 , 100 );
// ------------------------------------------------------------
// 累積された描画パスを使って、実際に描画
// ------------------------------------------------------------
// 面描画
context.fill();
// 線描画
context.stroke();
画像ファイルを出力する
■画像ファイルを出力する(Data URI Scheme 形式)
toDataURL() メソッドを使用します。
このメソッドは、同期実行です。
キャンバスが巨大であるほど、時間が掛かります。
HTMLCanvasElement.toDataURL ( "type" , ... ) :String
第01引数(略可) | String | 出力時のコンテンツタイプを指定。 |
可変引数(略可) | * | オプション情報を指定。 |
戻り値 | String | Data URI Scheme 文字列が得られる。 |
■第01引数(コンテンツタイプ)
以下の種類があります。
デフォルトは、"image/png" です。
指定したタイプをサポートしていない場合、デフォルトの PNG 形式となります。
第01引数 | 可変引数 | 説明 |
"image/png" | なし | PNG 画像フォーマット |
"image/jpeg" | 第02引数:品質(0.0 ~ 1.0) | JPEG 画像フォーマット |
■戻り値(Data URI Scheme)
■使用例
Data URI Scheme 文字列を出力する
<html>
<body>
<br>─── CANVAS ───<br>
<canvas id="my_canvas" width="400" height="200" style="border:1px solid #000;" ></canvas> <br>
<br>─── IMAGE ───<br>
<img id="my_image" width="400" height="200" style="border:1px solid #000;" > <br>
<input id="my_button" type="button" value="出力" > <br>
<script type="text/javascript">
<!--
// ------------------------------------------------------------
// 各エレメントを取得する
// ------------------------------------------------------------
var canvas = document.getElementById("my_canvas");
var image = document.getElementById("my_image");
var button = document.getElementById("my_button");
// ------------------------------------------------------------
// CanvasRenderingContext2D オブジェクトを取得する
// ------------------------------------------------------------
var context = canvas.getContext("2d");
// ------------------------------------------------------------
// 線の描画スタイルを設定する
// ------------------------------------------------------------
// 線の色を設定する
context.strokeStyle = "#0000aa";
// 線の太さを設定する
context.lineWidth = 10.0;
// ------------------------------------------------------------
// 面の描画スタイルを設定する
// ------------------------------------------------------------
// 面の色を設定する
context.fillStyle = "#8888ff";
// ------------------------------------------------------------
// 円を描画
// ------------------------------------------------------------
context.beginPath();
context.arc( 250 , 150 , 180 , 0 * (Math.PI / 180) , 360 * (Math.PI / 180) );
context.fill();
context.stroke();
context.beginPath();
context.arc( 100 , 100 , 80 , 0 * (Math.PI / 180) , 360 * (Math.PI / 180) );
context.fill();
context.stroke();
// ------------------------------------------------------------
// ボタンをクリックすると実行されるイベント
// ------------------------------------------------------------
button.onclick = function(){
// ------------------------------------------------------------
// Data URI Scheme 文字列を出力する
// ------------------------------------------------------------
var data_uri = canvas.toDataURL( "image/jpeg" , 1.0 );
// 出力テスト
console.log(data_uri);
// ------------------------------------------------------------
// イメージ要素にセットする
// ------------------------------------------------------------
image.src = data_uri;
};
//-->
</script>
</body>
</html>
■キャプチャのセキュリティについて
■生成元(オリジン)について
生成元(オリジン)とは、自身のリソースが格納されている場所です。
「プロトコル、ドメイン、ポート番号」の3つを合わせたものです。
■クロスオリジンデータについて
現在開いているページとは異なるオリジンに格納されているリソースを、クロスオリジンデータと言います。
■キャンバスの汚染について
画像やビデオなどのリソースは、テクスチャとして利用する事ができます。
クロスオリジンテータを使って描画した場合、キャンバスは汚染します。
origin-clean フラグが false に変化します。
クロスオリジンデータを、汚染を回避して利用する方法はありません。
また、汚染したキャンバスを、回復させる方法もありません。
■キャンバスが汚染した場合
キャプチャ処理を試みると、セキュリティエラーが発生して失敗します。
座標の相互変換について
■「クライアント座標」と「キャンバス座標」を相互変換する
マウスなどのクライアント座標を、キャンバスの座標系に変換します。
■「クライアント座標」から「キャンバス座標」に変換
「クライアント座標」から「キャンバス座標」に変換する関数
// ------------------------------------------------------------
// 「クライアント座標」から「キャンバス座標」に変換する関数
// ------------------------------------------------------------
function CanvasGetPositionFromClient(canvas,x,y){
var d = canvas.ownerDocument;
var w = d.defaultView;
var r = canvas.getBoundingClientRect();
var s = w.getComputedStyle(canvas,"");
var px = parseFloat(s.paddingLeft);
var py = parseFloat(s.paddingTop);
var bx = parseFloat(s.borderLeftWidth);
var by = parseFloat(s.borderTopWidth);
var sx = canvas.width / parseFloat(s.width);
var sy = canvas.height / parseFloat(s.height);
return {
x:(x - bx - px - r.left) * (sx),
y:(y - by - py - r.top ) * (sy)
};
}
■「キャンバス座標」から「クライアント座標」に変換
「キャンバス座標」から「クライアント座標」に変換する関数
// ------------------------------------------------------------
// 「キャンバス座標」から「クライアント座標」に変換する関数
// ------------------------------------------------------------
function CanvasGetPositionToClient(canvas,x,y){
var d = canvas.ownerDocument;
var w = d.defaultView;
var r = canvas.getBoundingClientRect();
var s = w.getComputedStyle(canvas,"");
var px = parseFloat(s.paddingLeft);
var py = parseFloat(s.paddingTop);
var bx = parseFloat(s.borderLeftWidth);
var by = parseFloat(s.borderTopWidth);
var sx = parseFloat(s.width) / canvas.width;
var sy = parseFloat(s.height) / canvas.height;
return {
x:(x * sx) + (bx + px + r.left),
y:(y * sy) + (by + py + r.top )
};
}
■使用例
マウス座標を「キャンバス座標」に変換する
<html>
<head>
<style type="text/css">
<!--
#aaa {
padding-left:0px;
padding-top :0px;
border:0px solid #000;
border-left-width:0px;
border-top-width :0px;
margin-left:0px;
margin-top :0px;
background-color:#eee;
width :100%;
height:100%;
}
//-->
</style>
</head>
<body>
<canvas id="aaa" width="640" height="480" ></canvas>
<script type="text/javascript">
<!--
// ------------------------------------------------------------
// 「クライアント座標」から「キャンバス座標」に変換する関数
// ------------------------------------------------------------
function CanvasGetPositionFromClient(canvas,x,y){
var d = canvas.ownerDocument;
var w = d.defaultView;
var r = canvas.getBoundingClientRect();
var s = w.getComputedStyle(canvas,"");
var px = parseFloat(s.paddingLeft);
var py = parseFloat(s.paddingTop);
var bx = parseFloat(s.borderLeftWidth);
var by = parseFloat(s.borderTopWidth);
var sx = canvas.width / parseFloat(s.width);
var sy = canvas.height / parseFloat(s.height);
return {
x:(x - bx - px - r.left) * (sx),
y:(y - by - py - r.top ) * (sy)
};
}
// ------------------------------------------------------------
// "aaa" という ID 属性のエレメントを取得する
// ------------------------------------------------------------
var canvas = document.getElementById("aaa");
// ------------------------------------------------------------
// CanvasRenderingContext2D オブジェクトを取得する
// ------------------------------------------------------------
var context = canvas.getContext("2d");
// ------------------------------------------------------------
// 線の描画スタイルを設定する
// ------------------------------------------------------------
// 線の太さを設定する
context.lineWidth = 4.0;
// ------------------------------------------------------------
// マウスを移動するたびに実行されるイベント
// ------------------------------------------------------------
window.addEventListener( "mousemove" , function (e){
// ------------------------------------------------------------
// マウス座標をキャンバス座標系に変換する
// ------------------------------------------------------------
var pos = CanvasGetPositionFromClient(canvas , e.clientX , e.clientY);
// 出力テスト
console.log("x:" + pos.x + " y:" + pos.y);
// ------------------------------------------------------------
// クリア
// ------------------------------------------------------------
context.clearRect( 0 , 0 , canvas.width , canvas.height );
// ------------------------------------------------------------
// 十字カーソルを描画する
// ------------------------------------------------------------
// 描画パスをクリア
context.beginPath();
// サブパスを開始(開始位置)
context.moveTo(pos.x - 10 , pos.y);
// サブパスを追加(直線追加)
context.lineTo(pos.x + 10 , pos.y);
// サブパスを開始(開始位置)
context.moveTo(pos.x , pos.y - 10);
// サブパスを追加(直線追加)
context.lineTo(pos.x , pos.y + 10);
// 累積された描画パスを使って、実際に線を描画する
context.stroke();
});
//-->
</script>
</body>
</html>