Canvas

演習5-1

  • キャンバスに矩形を表示するスクリプトを作成せよ

解答例

別ウィンドウで表示

ソース

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <title>簡単なCanvas</title>
  6. <script type="text/javascript">
  7. "use strict";
  8. window.addEventListener("load", function () {
  9. var context;
  10. // コンテキストを取得
  11. context = document.getElementById("canvas0").getContext("2d");
  12. // 描画 その1
  13. context.beginPath();
  14. context.strokeStyle = "#FF0000"; // 塗りつぶす色(赤)を指定
  15. context.strokeRect(30, 30, 100, 100); // 矩形を描画
  16. // 描画 その2
  17. context.beginPath();
  18. context.fillStyle = "rgba(0, 0, 255, 0.3)";// 塗りつぶす色(青)を指定,透過(0.3)
  19. context.fillRect(70, 70, 200, 100); // 矩形を描画
  20. });
  21. </script>
  22. <style>
  23. canvas {
  24. border : 1px solid #0000FF;
  25. }
  26. </style>
  27. </head>
  28. <body>
  29. <canvas id="canvas0" width="300" height="200"></canvas>
  30. </body>
  31. </html>

解説

  • Canvasはブラウザ上に図を描くために策定された仕様で,これを利用するとFlashやJavaのようなプラグインを使わずにJavaScriptベースで図を描くことができる.
  • HTMLドキュメントに,Canvas要素をおき(29行目),その要素をgetElementByIdなどのメソッドで取り出して(11行目),操作する(10行目から19行目).
  • 11行目
    • Canvasに図を描くには,getContextメソッドでコンテキストオブジェクトを取り出し,そのオブジェクトの描画メソッドを実行することによって描画する.
  • 13行目から15行目
    • 矩形を描画するには,線を描くと宣言し(beginPath),線のスタイルを指定し(strokeStyle),描画する(strokeRect).
  • 17行目から19行目
    • 矩形を塗りつぶすには,線を描くと宣言し(beginPath),塗りつぶしのスタイルを指定し(fillStyle),描画する(fillRect).

演習5-2

  • キャンバスをクリックしたら矩形を表示するスクリプトを作成せよ.

解答例

別ウィンドウで表示

マウスアップで,その位置に正方形を表示する.

ソース

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <title>Canvas マウスアップで正方形を表示</title>
  6. <script type="text/javascript">
  7. "use strict";
  8. window.addEventListener("load", function () {
  9. var canvas, context;
  10. // Canvasを取得
  11. canvas = document.getElementById("canvas1");
  12. // コンテキストを取得
  13. context = canvas.getContext("2d");
  14. // cavasにイベントを設定
  15. canvas.addEventListener("mouseup", function (e) {
  16. var rect, x, y, l;
  17. // イベントのターゲット(キャンバス)の座標を取得
  18. rect = e.target.getBoundingClientRect();
  19. // マウスダウンの座標を取得
  20. x = e.clientX - rect.left;
  21. y = e.clientY - rect.top;
  22. l = Math.random() * 20 + 20;
  23. // 矩形の描画
  24. context.beginPath();
  25. context.fillStyle = "rgba(0,255,0,0.2)";
  26. context.fillRect(x, y, l, l);
  27. });
  28. });
  29. </script>
  30. <style>
  31. canvas {
  32. border : 1px solid #0000FF;
  33. }
  34. </style>
  35. </head>
  36. <body>
  37. <canvas id="canvas1" width="300" height="200"></canvas>
  38. </body>
  39. </html>

解説

  • 13行目から26行目
    • キャンバス要素を取得し,そのキャンバス要素に「マウスアップで正方形を描画する」イベントリスナーを追加する.
  • 18行目から20行目
    • マウスアップの座標はmouseupイベントから得られる.イベントをeとすると,ウィンドウ上のマウスの座標は(e.clientX, e.clientY),マウスがのっている要素はe.getBoundingClientRect()である.この要素をrectとすると(18行目),マウスがのっている要素(この場合がキャンバス)内での座標は(e.clientX - rect.left, e.clientY - rect.top)となる.
  • 21行目
    • 正方形の1辺の長さを20pxから40pxの間のランダムな値とする.
  • 22行目から25行目
    • 矩形の描画は演習5-1と同様.

演習5-3

  • マウスで大きさを指定して矩形を描画するスクリプトを作成せよ.
    • マウスダウンで矩形の左上を指定し,マウスアップで矩形の右下を指定

解答例

別ウィンドウで表示

マウスで大きさを指定してCanvasに矩形を描画する.

ソース

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <style>
  5. canvas {
  6. border: solid 1px #000066;
  7. }
  8. </style>
  9. <meta charset="utf-8" />
  10. <title>Canvas マウスで矩形を描画</title>
  11. <script type="text/javascript">
  12. "use strict";
  13. window.addEventListener("load", function () {
  14. var
  15. canvas, context, // カンバスとコンテクスト
  16. x1, y1, // 描画領域中のマウスの位置(mousedown)
  17. x2, y2, // 描画領域中のマウスの位置(mousemove, mouseup)
  18. draw_flag; // 描画中か否か(ドラッグ中か否か)
  19. canvas = document.getElementById("canvas1");
  20. context = canvas.getContext("2d");
  21. draw_flag = false;
  22. // マウスダウンの処理
  23. canvas.addEventListener("mousedown", function (e) {
  24. var rect;
  25. // ドラッグ中
  26. draw_flag = true;
  27. // イベントのターゲット(キャンバス)の座標を取得
  28. rect = e.target.getBoundingClientRect();
  29. // マウスダウンの座標を記憶
  30. x1 = x2 = e.clientX - rect.left;
  31. y1 = y2 = e.clientY - rect.top;
  32. }, false);
  33. // マウスアップの処理
  34. canvas.addEventListener("mouseup", function (e) {
  35. var bcr;
  36. // ドラッグ中でなければ何もしない.
  37. if (draw_flag === false) {
  38. return;
  39. }
  40. // イベントのターゲット(キャンバス)の座標を取得
  41. bcr = e.target.getBoundingClientRect();
  42. // canvasをクリア
  43. context.clearRect(0, 0, bcr.right, bcr.bottom);
  44. // マウスアップの座標
  45. x2 = e.clientX - bcr.left;
  46. y2 = e.clientY - bcr.top;
  47. // 矩形を描画
  48. context.strokeStyle = "#000000";
  49. context.beginPath();
  50. context.strokeRect(x1, y1, x2 - x1, y2 - y1);
  51. // ドラッグ中ではない
  52. draw_flag = false;
  53. }, false);
  54. });
  55. </script>
  56. </head>
  57. <body>
  58. <canvas id="canvas1" width="300" height="200"></canvas>
  59. </body>
  60. </html>

解説

  • マウスダウンで矩形の左上の座標を取得・記憶し,マウスアップで矩形の右下の座標を取得して描画すればよい.
  • ドラッグ中のみマウスアップのイベントの処理を行うようにするために,draw_flagを導入する.
    • マウスダウンでドラッグ開始(draw_flagをtrueに):27行目
    • マウスアップでドラッグ終了(draw_flagをfalseに):54行目
    • マウスアップのとき,draw_flagがfalseなら何もしない:38行目から41行目

演習5-4

  • マウスで大きさを指定して矩形を描画するスクリプトを作成せよ.
  • ただし,ドラッグ中にその時点の大きさの矩形を赤で表示し,マウスアップしたときの最終的な矩形を黒で表示することとする.

解答例

別ウィンドウで表示

マウスで大きさを指定してCanvasに矩形を描画する.

ソース

  1. // マウスムーブの処理
  2. canvas.addEventListener("mousemove", function (e) {
  3. var bcr;
  4. // ドラッグ中でなければ何もしない.
  5. if (draw_flag === false) {
  6. return;
  7. }
  8. // イベントのターゲット(キャンバス)の座標を取得
  9. bcr = e.target.getBoundingClientRect();
  10. // canvasをクリア
  11. context.clearRect(0, 0, bcr.right, bcr.bottom);
  12. // マウスアップの座標
  13. x2 = e.clientX - bcr.left;
  14. y2 = e.clientY - bcr.top;
  15. // 矩形を描画
  16. context.strokeStyle = "#FF0000";
  17. context.beginPath();
  18. context.strokeRect(x1, y1, x2 - x1, y2 - y1);
  19. }, false);

解説

  • マウスムーブの処理を追加すればよい.
  • マウスムーブの処理はマウスアップの処理と同様に,イベントから矩形の右下の座標を取得し,その座標とマウスダウンの処理で記憶した左上の座標を使って矩形を描画する.
    • その際,1回前のマウスムーブで書いた矩形を消去するために,clearRect(11行目)を使ってキャンバスをクリアする.
    • そうしないと,ドラッグで矩形内が塗りつぶされてしまう.

演習5-5

  • マウスで大きさを指定して矩形を描画するスクリプトを作成せよ.このとき,一度描画した矩形を,表示したままにせよ.

解答例

別ウィンドウで表示

マウスで大きさを指定してCanvasに矩形を描画する.ただし,一度描画した矩形を消さない.

ソース

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <style>
  5. canvas {
  6. border: solid 1px #000066;
  7. }
  8. </style>
  9. <meta charset="utf-8" />
  10. <title>Canvas マウスで矩形を描画</title>
  11. <script type="text/javascript">
  12. "use strict";
  13. window.addEventListener("load", function () {
  14. var
  15. canvas, context, // カンバスとコンテクスト
  16. x1, y1, // 描画領域中のマウスの位置(mousedown)
  17. x2, y2, // 描画領域中のマウスの位置(mousemove, mouseup)
  18. draw_flag, // 描画中か否か(ドラッグ中か否か)
  19. rects; // 描画済みの矩形群
  20. canvas = document.getElementById("canvas1");
  21. context = canvas.getContext("2d");
  22. draw_flag = false;
  23. rects = [];
  24. // マウスダウンの処理
  25. canvas.addEventListener("mousedown", function (e) {
  26. var rect;
  27. // ドラッグ中
  28. draw_flag = true;
  29. // イベントのターゲット(キャンバス)の座標を取得
  30. rect = e.target.getBoundingClientRect();
  31. // マウスダウンの座標を記憶
  32. x1 = x2 = e.clientX - rect.left;
  33. y1 = y2 = e.clientY - rect.top;
  34. }, false);
  35. // マウスムーブの処理
  36. canvas.addEventListener("mousemove", function (e) {
  37. var bcr, i;
  38. // ドラッグ中でなければ何もしない.
  39. if (draw_flag === false) {
  40. return;
  41. }
  42. // イベントのターゲット(キャンバス)の座標を取得
  43. bcr = e.target.getBoundingClientRect();
  44. // canvasをクリア
  45. context.clearRect(0, 0, bcr.right, bcr.bottom);
  46. // 描画済みの矩形群を再描画
  47. context.strokeStyle = "#000000";
  48. for (i = 0; i < rects.length; i += 1) {
  49. context.strokeRect(rects[i].x, rects[i].y, rects[i].w, rects[i].h);
  50. }
  51. // マウスアップの座標
  52. x2 = e.clientX - bcr.left;
  53. y2 = e.clientY - bcr.top;
  54. // 矩形を描画
  55. context.strokeStyle = "#FF0000";
  56. context.beginPath();
  57. context.strokeRect(x1, y1, x2 - x1, y2 - y1);
  58. }, false);
  59. // マウスアップの処理
  60. canvas.addEventListener("mouseup", function (e) {
  61. var bcr, i;
  62. // ドラッグ中でなければ何もしない.
  63. if (draw_flag === false) {
  64. return;
  65. }
  66. // イベントのターゲット(キャンバス)の座標を取得
  67. bcr = e.target.getBoundingClientRect();
  68. // canvasをクリア
  69. context.clearRect(0, 0, bcr.right, bcr.bottom);
  70. // マウスアップの座標
  71. x2 = e.clientX - bcr.left;
  72. y2 = e.clientY - bcr.top;
  73. // 新たに描画された矩形を矩形群rectsに追加
  74. rects.push({x: x1, y: y1, w: x2 - x1, h: y2 - y1});
  75. // 矩形群を描画
  76. context.strokeStyle = "#000000";
  77. context.beginPath();
  78. for (i = 0; i < rects.length; i += 1) {
  79. context.strokeRect(rects[i].x, rects[i].y, rects[i].w, rects[i].h);
  80. }
  81. // ドラッグ中ではない
  82. draw_flag = false;
  83. }, false);
  84. });
  85. </script>
  86. </head>
  87. <body>
  88. <canvas id="canvas1" width="300" height="200"></canvas>
  89. </body>
  90. </html>

解説

  • マウスムーブの処理とマウスアップの処理で,キャンバスをクリアする代わりに,それまでに描画された全ての矩形を再描画するようにすればよい.
  • 再描画するには,描画された全ての矩形群の位置と大きさを保持する必要があるので,そのための変数rects(配列)を導入し(20行目),マウスアップの度に新たな矩形(の位置と大きさ)をrectsに追加する.
  • マウスムーブの処理
    • 矩形群の再描画は黒で(51行目から55行目).
    • 新たな矩形の描画は赤で(60行目から602行目).
  • マウスアップの処理
    • 新たな矩形を矩形群rectsに追加(79行目から80行目).配列への追加メソッドはpush.
    • 矩形群の描画は黒で(81行目から86行目).