Canvas 2D は下記の文書で公開されています。
<!DOCTYPE html> <html> <head> <title>CANVAS TEST</title> <!--[if lt IE 9]> // Explorer Canvasを読み込む <script src="js/excanvas.js"></script> <![endif]--> <script> window.addEventListener('load', function() { var cv = document.getElementById('cv1'); // 要素を得る if (!cv) { return; } var ct = cv.getContext('2d'); // 2D(平面)コンテキストを得る if (!ct) { return; } ct.fillStyle = '#ffcccc'; ct.fillRect(0, 0, cv.width, cv.height); // 矩形を塗りつぶす ct.strokeStyle = '#ff0000'; ct.strokeRect(0, 0, cv.width, cv.height); // 矩形を描画する ct.beginPath(); ct.strokeStyle = '#ff0000'; ct.arc(70, 50, 40, 0, Math.PI * 2, false); // 円を描画する ct.stroke(); ct.beginPath(); ct.strokeStyle = '#0000ff'; ct.moveTo(0, 0); ct.lineTo(140, 100); // 線を描画する ct.stroke(); }); </script> </head> <body> <canvas id="cv1" width="140" height="100"></canvas> </body> </html>
キャンバス要素から Canbas 2D コンテキストを得ます。
var cv = document.getElementById('cv1'); if (!cv) { return; } var ct = cv.getContext('2d'); if (!ct) { return; }
キャンバス要素を返します。
ct.canvas.style.height = "300px";
コンテキストのアトリビュートオブジェクトを取得します。
var attributes = ct.getContextAttributes();
現在の状態をスタックに格納します。状態は lineWidth, lineCap, lineJoin, miterLimit, lineDashOffset, shadowOffsetX, shadowOffsetY, shadowBlur, font, textAlign, textBaseline, direction, fontKerning, fontStretch, fontVariantCaps, textRendering, imageSmoothingEnabled, imageSmoothingQuality を含みます。
ct.strokeStyle = '#ff0000';
ct.lineWidth = 3;
ct.save(); // strokeStyle, lineWidth等の状態をスタックに格納
ct.strokeStyle = '#0000ff';
ct.lineWidth = 10;
save() で保存したキャンバス状態をスタックから取り出しリストアします。
ct.restore(); // strokeStyle, lineWidth等の状態を復元
コンテキストをリセットして描画をクリアします。下記の例では四角を描画後クリアし、円を描いています。
ct.strokeRect(10, 10, 80, 80); ct.reset(); ct.arc(50, 50, 40, 0, Math.PI * 2); ct.stroke();
コンテキストがすでに失われていれば true を返します。
if (isContextLost()) { console.log("Context is lost.") }
線の幅を返却します。設定も可能です。初期値は 1.0 です。
ct.lineWidth = 8; ct.beginPath(); ct.moveTo(20, 20); ct.lineTo(280, 20); ct.stroke();
線の両端の形状を返却します。設定も可能です。切れ端(butt), 角丸(round), 矩形(square) のいずれかを指定します。初期値は butt です。
線の結合スタイルを返却します。設定も可能です。面取り(bevel), 角丸(round), 留め継ぎ(miter) のいずれかを指定します。初期値は miter です。
線の中心が交わるポイントと、線の外側が交わるポイントとの距離をマイター長と呼びますが、liineJoin = "miter" で線を鋭角で結合すると、結合部(マイター長)が妙に長くなりすぎることがあります。このマイター長が、線の太さの miterLimit 倍を超えてしまう場合、線は miter ではなく、bevel で描画することでこの問題を防ぎます。miterLimit の初期値は 10.0 です。下記の例では、上の線には miterLimit = 100.0 を、下の線には miterLimit = 10.0 を指定しています。
点線の描画方法を指定します。segments に [ 20, 5, 10, 5 ] を指定すると、長さ 20 の実線、長さ 5 の空白、長さ 10 の実線、長さ 5 の空白を繰り返して点線を描画します。
setLineDash() で設定した点線描画のリストを配列で返却します。
点線を描画する際の、始点のオフセットの長さを参照(指定)します。[ 20, 5, 10, 5 ] の点線で lineDashOffset = 15 を指定すると、最初の線の長さ 20 の内、15 のオフセットを引いた長さ 5 の位置から最初の線を描画します。
文字を描画する際のフォントを参照(設定)します。詳細は CSS の font を参照してください。
ct.font = 'italic 9pt Arial';
文字の表示位置を参照(指定)します。start, end, left, right, center のいずれかを指定します。初期値は start です。
ct.textAlign = 'center';
文字のベースラインを参照(指定)します。top, hanging, middle, alphabetic, ideographic, bottom のいずれかを指定します。初期値は alphabetic です。
ct.textBaseline = 'bottom';
文字を表示する方向を ltr(左から右)、rtl(右から左)、inherit(継承) のいずれかで指定します。Hi! の逆方向は !iH ではなく !Hi となります。
ct.direction = 'rtl';
フォントの文字間隔を参照(設定)します。詳細は CSS の letter-spacing を参照してください。
ct.letterSpacing = '20px';
フォントのカーニングを参照(設定)します。詳細は CSS の font-kerning を参照してください。
ct.fontKerning = 'normal';
フォントのストレッチを参照(設定)します。詳細は CSS の font-stretch を参照してください。
ct.fontStretch = 'ultra-condensed';
フォントのストレッチを参照(設定)します。詳細は CSS の font-variant-caps を参照してください。
ct.fontVariantCaps = 'small-caps';
フォントのレンダリングアルゴリズムを参照(設定)します。詳細は CSS の text-rendering を参照してください。
ct.textRendering = 'optimizeSpeed';
単語間の隙間を参照(設定)します。詳細は CSS の word-spacing を参照してください。
ct.wordSpacing = '10px';
新しいサブパスの始点を x, y で指定します。
ct.moveTo(40, 40);
現在の位置から x, y の位置まで線を描画します。
ct.beginPath(); // パス描画を開始 ct.moveTo(40, 40); // 40, 40の位置にペンを置く ct.lineTo(200, 40); // 200, 40の位置に動かす ct.stroke(); // 描画する
現在のサブパスを閉じて、始点と終点を線で結びます。
ct.beginPath(); // パス描画を開始 ct.moveTo(10, 10); // 10, 10の位置にペンを置く ct.lineTo(10, 90); // 10, 90の位置に動かす ct.lineTo(90, 90); // 90, 90の位置に動かす ct.closePath(); // 始点と終点を結ぶ ct.stroke(); // 描画する
現在の位置から、cpx, cpy を制御点、x, y を終点とする二次ベジェ曲線を描画します。
ct.beginPath(); ct.moveTo(50, 90); ct.quadraticCurveTo(100, 10, 150, 90); ct.stroke();
現在の位置から、(cp1x, cp1y), (cp2x, cp2y) を制御点、x, y を終点とする三次ベジェ曲線を描画します。
ct.beginPath(); ct.moveTo(50, 90); ct.bezierCurveTo(90, 10, 110, 10, 150, 90); ct.stroke();
現在の位置から(x1, y1)を経由して(x2, y2) に向かう線を描画します。ただし、角を半径 radius の円弧とし、円弧の終点で終了します。
ct.beginPath(); ct.moveTo(50, 90); ct.arcTo(50, 10, 130, 10, 30); ct.stroke();
x, y を中心、radius を半径、startAngle を開始角、endAngle を終了角とする円弧を描画します。角度には 0 から Math.PI * 2 までの値を指定します。x 軸の方向が角度 0 となります。counterclockwise に true を指定すると反時計周りとなります。
ct.beginPath(); ct.arc(50, 50, 40, 0, (Math.PI * 2) * (3 / 4)); ct.stroke();
x, y を中心とし、radiusX, radiusY を半径とする楕円を描きます。rotaion は傾き角度、startAngle, endAngle は開始角度、終了角度、anticlockwise に true を指定すると半時計周りに描画します。
ct.beginPath(); ct.ellipse(100, 50, 60, 30, 0, 0, Math.PI * 2); ct.stroke();
x, y を左上端とする、横幅 width、高さ height の矩形を描きます。
ct.beginPath(); ct.rect(20, 20, 100, 60); ct.stroke();
角丸の矩形を描画します。radii には 全角の丸め長さ、または [左上, 右上, 右下, 左下]、[左上, 右上と左下, 右下]、[左上と右下, 右上と左下]、[全角] の配列で指定します。
ct.lineWidth = 2; ct.roundRect(15, 15, 70, 70, 8); ct.roundRect(120, 15, 70, 70, [5, 10, 20, 40]); ct.stroke();
現在の座標を、横に x 倍、縦に y 倍にスケール変更します。
ct.beginPath(); ct.rect(20, 20, 30, 30); ct.stroke(); ct.scale(2.0, 2.0); ct.beginPath(); ct.rect(50, 10, 30, 30); ct.stroke();
現在の座標を、angle 度回転させます。
ct.beginPath(); ct.rect(40, 5, 60, 20); ct.stroke(); ct.rotate(45 * Math.PI / 180); ct.beginPath(); ct.rect(40, 5, 60, 20); ct.stroke();
現在の座標を、右方向に x、下方向に y 分移動させます。
ct.beginPath(); ct.rect(20, 20, 60, 20); ct.stroke(); ct.translate(100, 0); ct.beginPath(); ct.rect(20, 20, 60, 20); ct.stroke();
スケール変更、回転、座標シフトの座標変換をまとめて行います。現在の座標を、x1, y1 倍にスケール変更し、x2, y2 だけ回転し、x3, y3 分移動させます。transform() や setTransform() を複数回呼び出した場合、transform() の場合は現在の座標に対してさらに座標変換を行います。setTransform() は初期座標に対して変換を行います。getTransform() は設定した座標変換情報を取得します。
ct.beginPath(); ct.rect(20, 20, 60, 20); ct.stroke(); ct.transform(1.3, 10 * Math.PI / 180, 10 * Math.PI / 180, 1.3, 100, 0); ct.beginPath(); ct.rect(20, 20, 60, 20); ct.stroke();
rotate() などで指定したトランスフォームをリセットします。下記の例では1つ目の矩形は rotate() に従いますが、2つ目の矩形はリセット後に描画されています。
ct.rotate(Math.PI * 10 / 180); ct.rect(80, 30, 30, 30); ct.resetTransform(); ct.rect(80, 30, 30, 30); ct.stroke();
塗りつぶしの色を参照(設定)します。CSS の color に指定する値、または createLinearGradient() などで生成する gradient を指定します。
ct.beginPath(); ct.fillStyle = "rgb(255, 120, 120)"; ct.arc(50, 50, 30, 0, Math.PI * 2, 40); ct.fill(); ct.beginPath(); ct.fillStyle = "rgba(120, 120, 255, 0.4)"; ct.arc(90, 50, 30, 0, Math.PI * 2, 40); ct.fill();
線の色を参照(設定)します。CSS の color に指定する色、createLinearGradient() などで作成する gradient、または createPattern() が返却する pattern を指定することができます。
ct.lineWidth = 10; ct.beginPath(); ct.strokeStyle = "rgb(255, 120, 120)"; ct.arc(50, 50, 30, 0, Math.PI * 2, 40); ct.stroke(); ct.beginPath(); ct.strokeStyle = "rgba(120, 120, 255, 0.4)"; ct.arc(90, 50, 30, 0, Math.PI * 2, 40); ct.stroke();
createLinearGradient(), createRadialGradient(), createConicGradient() で作成したグラデーションの色を設定します。offset にはグラデーションの開始 を 0.0、終了を 1.0 とする距離を示します。color には CSS の color で指定可能な色を指定します。
var gradient = ct.createLinearGradient(10, 10, 90, 90); gradient.addColorStop(0.0, 'rgb(255, 90, 90)'); gradient.addColorStop(0.5, 'rgb(90, 255, 90)'); gradient.addColorStop(1.0, 'rgb(90, 90, 255)');
線形グラデーションを指定します。createLinearGradient() で (x0, y0) から (x1, y1) への線形の仮想線を引き、開始点を 0.0、終了点を 1.0 とし、addColorStop() でそれぞれのポイントの色を指定します。
var gradient = ct.createLinearGradient(10, 10, 90, 90); gradient.addColorStop(0.0, 'rgb(255, 90, 90)'); gradient.addColorStop(0.5, 'rgb(90, 255, 90)'); gradient.addColorStop(1.0, 'rgb(90, 90, 255)'); ct.beginPath(); ct.fillStyle = gradient; ct.rect(10, 10, 80, 80); ct.fill();
円形グラデーションを指定します。createRadialGradient() で中心 (x0, y0)、半径 r0 の開始円、中心 (x1, y1)、半径 r1 の終了円を作成し、開始円を 0.0、終了円を 1.0 とし、addColorStop() でそれぞれのポイントの色を指定します。作成したグラデーションは fillStyle や strokeStyle に設定します。
var gradient = ct.createRadialGradient(40, 40, 0, 50, 50, 50); gradient.addColorStop(0.0, 'rgb(90, 90, 255)'); gradient.addColorStop(0.5, 'rgb(90, 255, 90)'); gradient.addColorStop(1.0, 'rgb(255, 90, 90)'); ct.beginPath(); ct.fillStyle = gradient; ct.arc(50, 50, 40, 0, Math.PI * 2); ct.fill();
円形のグラデーションを作成します。startAngle は開始角度、x, y には中心座標を指定します。
var gradient = ct.createConicGradient(0, 50, 50); gradient.addColorStop(0.0, "red"); gradient.addColorStop(0.5, "blue"); gradient.addColorStop(1.0, "yellow"); ct.beginPath(); ct.fillStyle = gradient; ct.arc(50, 50, 40, 0, Math.PI * 2); ct.fill();
塗りつぶしに使用する画像を指定します。repetition には、繰り返し(repeat)、X方向のみ繰り返し(repeat-x)、Y方向のみ繰り返し(repeat-y)、繰り返さない(no-repeat) のいずれかを指定します。fillRecv() などの描画関数は、イメージの onload ハンドラの中に記述します。
var img = new Image(); img.src = './image/back.png'; img.onload = function() { var pattern = ct.createPattern(img, 'repeat'); ct.fillStyle = pattern; ct.fillRect(10, 10, 80, 80); };
左上端を (x, y)、横幅 width、高さ height とする矩形を strokeStyle で指定した色で描画します。
ct.strokeStyle = 'rgb(0, 0, 255)'; ct.strokeRect(10, 20, 80, 40);
左上端を (x, y)、横幅 width、高さ height とする矩形領域を fillStyle で指定した色で塗りつぶします。
ct.fillStyle = 'rgb(160, 160, 255)'; ct.fillRect(10, 20, 80, 40);
左上端を (x, y)、横幅 width、高さ height とする矩形領域をクリアします。
ct.fillRect(10, 10, 80, 80); ct.clearRect(30, 30, 40, 40);
ベースラインの左端を (x, y) として、テキスト text を描画します。maxWidth は、最大の横幅を指定します。横幅を超える場合、テキストは横方向に圧縮されます。
ct.font = "20pt Arial"; ct.fillText("Hello world!!", 20, 60);
ベースラインの左端を (x, y) として、テキスト text を白抜きで描画します。maxWidth は、最大の横幅を指定します。横幅を超える場合、テキストは横方向に圧縮されます。
ct.font = "20pt Arial"; ct.strokeText("Hello world!!", 20, 60);
measureText() は text のメトリック情報 metrics を返します。metrics.width はテキストの横幅を参照します。下記の例では、文字幅を計算し、矩形の中央に文字が表示されるように調整しています。メトリックには下記の情報が含まれます。
ct.font = '12pt Arial'; ct.strokeRect(10, 10, 220, 80); var text = "HTML5 Canvas Reference"; var metrics = ct.measureText(text); ct.fillText(text, 120 - metrics.width / 2, 50);
新しいパスを始めるために、現在のパスをリセットします。
ct.beginPath();
現在の塗りつぶしスタイルで、現在のサブパスを塗りつぶします。
ct.beginPath(); ct.moveTo(30, 30); ct.lineTo(30, 70); ct.lineTo(70, 70); ct.moveTo(130, 30); ct.lineTo(130, 70); ct.lineTo(170, 70); ct.fill();
現在の線引きスタイルで、現在のサブパスを描画します。
ct.beginPath(); ct.moveTo(30, 30); ct.lineTo(30, 70); ct.lineTo(70, 70); ct.moveTo(130, 30); ct.lineTo(130, 70); ct.lineTo(170, 70); ct.stroke();
clip(), clip(path), clip(filRule), clip(path, fillRule) のいずれかで指定します。Path2D で作成する path を指定した場合は指定したパス、指定しない場合は現在のパスの内側をクリッピング領域とします。fillRule には ノンゼロワインディングルール(参考↗)(nonzero) または 偶数奇数ワインディングルール(参考↗)(evenodd) のいずれかを指定します。クリッピングを解除するには、save() と restore() を使用します。
ct.beginPath(); ct.arc(80, 50, 40, 0, Math.PI * 2); ct.clip(); var img = new Image(); img.src = './image/neko.jpg'; img.onload = function() { ct.fillStyle = ct.createPattern(img, 'repeat'); ct.fillRect(10, 10, 110, 80); };
指定した座標が、現在のパスの内側にあるか否かを true, false で返します。
ct.rect(10, 10, 100, 80); ct.stroke(); ct.fillText(ct.isPointInPath(50, 50), 50, 50); // true ct.fillText(ct.isPointInPath(150, 50), 150, 50); // false
指定した座標が、ストローク(線)上にあるか否かを true, false で返します。
const box = new Path2D(); box.rect(20, 20, 100, 40); ct.lineWidth = 20; ct.stroke(box); ct.fillText(ct.isPointInStroke(box, 70, 45), 70, 45)
element にフォーカスが当たっていれば、現在のパスの周りにフォーカスリングを描画します。
<canvas id="cv1" width="300" height="100"> <button id="btn1">Button1</button> </canvas>
var btn1 = document.getElementById('btn1'); btn1.focus(); ct.beginPath(); ct.rect(30, 30, 100, 30); ct.fillText(btn1.textContent, 68, 48); ct.drawFocusIfNeeded(btn1);
イメージを描画します。(dx, dy) は画像を描画する座標を示します。dw, dh は画像の横幅、高さを指定します。3番目の形式は、表示する画像の (sx, sy) から横幅 sw、高さ sh の領域をクリッピングして表示します。
var img = new Image(); img.src = '../../image/ki2.gif'; img.onload = function() { ct.drawImage(img, 40, 40); ct.drawImage(img, 100, 40, 15, 15); ct.drawImage(img, 4, 4, 16, 16, 160, 40, 30, 30); };
createImageData() はイメージデータを作成します。width, height はイメージデータの幅と高さを示します。data は height * width * 4 個の数値配列で、R値、G値、B値、透明度(0~255) の 4個の値が、横幅分 × 高さ分並びます。settings は省略可能で色空間を sRGB色空間(srgb) または display-p3色空間(display-p3)を指定します。下記の例では、80 × 80 のイメージデータを作成し、RGBA値を指定し、putImageData() で描画しています。
var img = ct.createImageData(80, 80); for (var y = 0; y < img.height; y++) { for (var x = 0; x < img.width; x++) { img.data[(y * img.width + x) * 4 + 0] = (y / img.height) * 255; // R img.data[(y * img.width + x) * 4 + 1] = (x / img.width) * 255; // G img.data[(y * img.width + x) * 4 + 2] = 255; // B img.data[(y * img.width + x) * 4 + 3] = 255; // Alpha } } ct.putImageData(img, 10, 10);
下記の例では、画像 img1 を表示し、その画像を getImageData() で img2 に読み取り、左右を逆転させながら img3 に複製し、描画しています。Chrome や Firefox ではセキュリティ制約により、ローカル環境では動作しません。
var img1 = new Image(); img1.src = '../../image/ki2.gif'; img1.onload = function() { ct.drawImage(img1, 10, 10, 30, 30); try { var img2 = ct.getImageData(10, 10, 30, 30); } catch (e) { console.log(e); return; } var img3 = ct.createImageData(30, 30); for (var y = 0; y < img2.height; y++) { for (var x = 0; x < img2.width; x++) { img3.data[(y * img2.width + x) * 4 + 0] = img2.data[(y * img2.width + (img2.width - x - 1)) * 4 + 0]; img3.data[(y * img2.width + x) * 4 + 1] = img2.data[(y * img2.width + (img2.width - x - 1)) * 4 + 1]; img3.data[(y * img2.width + x) * 4 + 2] = img2.data[(y * img2.width + (img2.width - x - 1)) * 4 + 2]; img3.data[(y * img2.width + x) * 4 + 3] = img2.data[(y * img2.width + (img2.width - x - 1)) * 4 + 3]; } } ct.putImageData(img3, 50, 10); };
下記の例では、RGB値の平均値を複製することにより、モノトーン画像に変換しています。Chrome や Firefox ではセキュリティ制約により、ローカル環境では動作しません。
var img1 = new Image(); img1.src = '../../image/ki2.gif'; img1.onload = function() { ct.drawImage(img1, 10, 10, 30, 30); try { var img2 = ct.getImageData(10, 10, 30, 30); } catch (e) { console.log(e); return; } var img3 = ct.createImageData(30, 30); for (var y = 0; y < img2.height; y++) { for (var x = 0; x < img2.width; x++) { var r = img2.data[(y * img2.width + x) * 4 + 0]; var g = img2.data[(y * img2.width + x) * 4 + 1]; var b = img2.data[(y * img2.width + x) * 4 + 2]; img3.data[(y * img2.width + x) * 4 + 0] = (r + g + b) / 3; img3.data[(y * img2.width + x) * 4 + 1] = (r + g + b) / 3; img3.data[(y * img2.width + x) * 4 + 2] = (r + g + b) / 3; img3.data[(y * img2.width + x) * 4 + 3] = img2.data[(y * img2.width + x) * 4 + 3]; } } ct.putImageData(img3, 50, 10); };
透明度を参照(設定)します。透明度は、0.0~1.0 の数値で指定します。
// 青い矩形 ct.fillStyle = 'rgb(160, 160, 255)'; ct.fillRect(10, 40, 160, 20); // 赤い矩形 ct.fillStyle = 'rgb(255, 160, 160)'; ct.fillRect(20, 20, 60, 60); // 赤い矩形(半透明) ct.globalAlpha = 0.5; ct.fillRect(100, 20, 60, 60);
globalCompositeOperation は、複数の画像が重なった場合の動作を参照(設定)します。
ct.fillStyle = 'rgb(160, 160, 255)'; ct.fillRect(10, 10, 40, 40); ct.globalCompositeOperation = 'xor'; ct.fillStyle = 'rgb(255, 160, 160)'; ct.fillRect(30, 30, 40, 40);
拡大・縮小された画像を平滑化する(true)か否か(false)を指定します。デフォルトは true です。
var img = new Image(); img.src = '../../image/ki2.gif'; img.onload = function() { ct.imageSmoothingEnabled = true; ct.drawImage(img, 40, 20, 60, 60); ct.imageSmoothingEnabled = false; ct.drawImage(img, 120, 20, 60, 60); };
画像の平滑化の品質を高品質(high)、中品質(medium)、低品質(low)のいずれかで指定します。デフォルトは low です。
var img = new Image(); img.src = '../../image/ki2.gif'; img.onload = function() { ct.imageSmoothingQuality = "high"; ct.drawImage(img, 10, 10, 80, 80); ct.imageSmoothingQuality = "medium"; ct.drawImage(img, 100, 10, 80, 80); ct.imageSmoothingQuality = "low"; ct.drawImage(img, 190, 10, 80, 80); };
影を指定します。shadowColor は影の色、shadowOffsetX, shadowOffsetY は影の位置、shadowBlur はぼかしレベルを参照(設定)します。
ct.shadowColor = 'rgb(90, 90, 90)'; ct.shadowOffsetX = 5; ct.shadowOffsetY = 5; ct.shadowBlur = 5; ct.fillRect(10, 10, 60, 60);
フィルタ効果を与えます。フィルタには blur() や brightness() など、CSS の filter に指定可能な値を設定することができます。
ct.filter = "blur(1.5px)"; ct.font = "20pt Arial"; ct.fillText("Hello!", 20, 60);
キャンバス上のオブジェクトをマウスでクリックしたことを検出する機能です。Chrome と Firefox で試験的にサポートされていましたが、現在は破棄されています。
ヒットリージョンを追加します。options には下記を指定します。
cv.addEventListener("click", function(event) { if (event.region) { alert(event.region); } }); ct.beginPath(); ct.rect(30, 30, 40, 40); ct.stroke(); try { ct.addHitRegion({id:'Reagion#1'}); } catch (e) { console.log("Not supported"); }
ヒットリージョンを削除します。
ヒットリージョンをすべてクリアします。