Local Storage

演習6-1

演習5-3のスクリプトを次のように変更せよ.

  • ロードボタンとセーブボタンをつけ,セーブボタンをクリックしたら,その時描かれている矩形の情報を(x, y, w, h)をローカルストレージにセーブし,ロードボタンをクリックしたら,セーブされている矩形の情報をロードして表示する.

解答例

別ウィンドウで表示

ソース

  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, // 描画領域中のマウスの位置(mouseup)
  18. draw_flag, // 描画中か否か(ドラッグ中か否か)
  19. loadButton, saveButton;
  20. canvas = document.getElementById("canvas1");
  21. context = canvas.getContext("2d");
  22. draw_flag = false;
  23. // マウスダウンの処理
  24. canvas.addEventListener("mousedown", function (e) {
  25. var bcr;
  26. console.log("mousedown start");
  27. // ドラッグ中
  28. draw_flag = true;
  29. // イベントのターゲット(キャンバス)の座標を取得
  30. bcr = e.target.getBoundingClientRect();
  31. // マウスダウンの座標を記憶
  32. x1 = x2 = e.clientX - bcr.left;
  33. y1 = y2 = e.clientY - bcr.top;
  34. console.log("mousedown end", x1, y1);
  35. }, false);
  36. // マウスアップの処理
  37. canvas.addEventListener("mouseup", function (e) {
  38. console.log("mouseup start");
  39. var bcr;
  40. // ドラッグ中でなければ何もしない.
  41. if (draw_flag === false) {
  42. return;
  43. }
  44. // イベントのターゲット(キャンバス)の座標を取得
  45. bcr = e.target.getBoundingClientRect();
  46. // マウスアップの座標
  47. x2 = e.clientX - bcr.left;
  48. y2 = e.clientY - bcr.top;
  49. // 矩形を描画
  50. context.clearRect(0, 0, bcr.right, bcr.bottom);
  51. context.strokeStyle = "#000000";
  52. context.beginPath();
  53. context.strokeRect(x1, y1, x2 - x1, y2 - y1);
  54. // ドラッグ中ではない
  55. draw_flag = false;
  56. console.log("mouseup end", x2, y2);
  57. }, false);
  58. loadButton = document.getElementById("loadbutton");
  59. loadButton.addEventListener('click', function () {
  60. var x, y, w, h;
  61. console.log("loadfile start");
  62. x = localStorage.getItem("t-tanaka-x");
  63. y = localStorage.getItem("t-tanaka-y");
  64. w = localStorage.getItem("t-tanaka-w");
  65. h = localStorage.getItem("t-tanaka-h");
  66. context.clearRect(0, 0, canvas.width, canvas.height);
  67. context.strokeStyle = "#000000";
  68. context.beginPath();
  69. context.strokeRect(x, y, w, h);
  70. console.log("loadfile end", x, y, w, h);
  71. });
  72. saveButton = document.getElementById("savebutton");
  73. saveButton.addEventListener('click', function () {
  74. console.log("save start");
  75. localStorage.setItem("t-tanaka-x", x1);
  76. localStorage.setItem("t-tanaka-y", y1);
  77. localStorage.setItem("t-tanaka-w", x2 - x1);
  78. localStorage.setItem("t-tanaka-h", y2 - y1);
  79. console.log("save end", x1, y1, x2 - x1, y2 - y1);
  80. });
  81. });
  82. </script>
  83. </head>
  84. <body>
  85. <canvas id="canvas1" width="300" height="200"></canvas>
  86. <p><button id = "loadbutton" >ロード</button>
  87. <button id = "savebutton">セーブ</button></p>
  88. </body>
  89. </html>

解説

  • 63行目から76行目
    • 「ロード」ボタンがクリックされたら,ローカルストレージからデータをロードするため,ロードボタンにクリックイベントリスナーを追加
  • 67行目から70行目
    • localStorage.getItemメソッドでデータをロード.
    • localStorateは組み込みのグローバル変数,getItemはそのメソッド.引数でデータの名前を指定してデータを取得する.
  • 78行目から87行目
    • 「セーブ」ボタンがクリックされたら,ローカルストレージにデータをセーブするため,セーブボタンにクリックイ弁をリスナーを追加
  • 81行目から84行目
    • localStorate.setItemメソッドでデータをセーブ.
    • setItemはlocalStorageのメソッド.第1引数で指定した名前で,第2引数でデータをセーブする.
  • 29行目,37行目,42行目,60行目,66行目,75行目,80行目,85行目
    • デバッグしやすいように,各関数の開始時と終了時にconsole.logでブラウザのコンソールにログを出力している.

演習6-2

演習6-1のスクリプトを次のように変更せよ.

  • ロードしたときと,マウスアップのときに同じ描画処理をするので,描画の関数drawを定義し前記箇所で呼び出すようにする.
  • HTMLを表示したときはセーブボタンをdisableとし(クリックできないようにし),マウスアップのイベントのあとdisableを解除する.
    • ボタン要素にdisable属性をつけるとdisableになる.
      • <button id = "savebutton" disabled>セーブ</button>
    • disable属性を削除するには,removeAttribute("disabled")を用いる.

解答例

別ウィンドウで表示

ソース

  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, // 描画領域中のマウスの位置(mouseup)
  18. draw_flag, // 描画中か否か(ドラッグ中か否か)
  19. loadButton, saveButton;
  20. function draw(x, y, w, h) {
  21. console.log("draw start");
  22. context.clearRect(0, 0, canvas.width, canvas.height);
  23. context.strokeStyle = "#000000";
  24. context.beginPath();
  25. context.strokeRect(x, y, w, h);
  26. console.log("draw end", x, y, w, h);
  27. }
  28. canvas = document.getElementById("canvas1");
  29. context = canvas.getContext("2d");
  30. draw_flag = false;
  31. // マウスダウンの処理
  32. canvas.addEventListener("mousedown", function (e) {
  33. var bcr;
  34. console.log("mousedown start");
  35. // ドラッグ中
  36. draw_flag = true;
  37. // イベントのターゲット(キャンバス)の座標を取得
  38. bcr = e.target.getBoundingClientRect();
  39. // マウスダウンの座標を記憶
  40. x1 = x2 = e.clientX - bcr.left;
  41. y1 = y2 = e.clientY - bcr.top;
  42. console.log("mousedown end", x1, y1);
  43. }, false);
  44. // マウスアップの処理
  45. canvas.addEventListener("mouseup", function (e) {
  46. console.log("mouseup start");
  47. var bcr;
  48. // ドラッグ中でなければ何もしない.
  49. if (draw_flag === false) {
  50. return;
  51. }
  52. // イベントのターゲット(キャンバス)の座標を取得
  53. bcr = e.target.getBoundingClientRect();
  54. // マウスアップの座標
  55. x2 = e.clientX - bcr.left;
  56. y2 = e.clientY - bcr.top;
  57. // 矩形を描画
  58. draw(x1, y1, x2 - x1, y2 - y1);
  59. // ドラッグ中ではない
  60. draw_flag = false;
  61. saveButton.removeAttribute("disabled");
  62. console.log("mouseup end", x2, y2);
  63. }, false);
  64. loadButton = document.getElementById("loadbutton");
  65. loadButton.addEventListener('click', function () {
  66. var x, y, w, h;
  67. console.log("loadfile start");
  68. x = localStorage.getItem("t-tanaka-x");
  69. y = localStorage.getItem("t-tanaka-y");
  70. w = localStorage.getItem("t-tanaka-w");
  71. h = localStorage.getItem("t-tanaka-h");
  72. draw(x, y, w, h);
  73. console.log("loadfile end", x, y, w, h);
  74. });
  75. saveButton = document.getElementById("savebutton");
  76. saveButton.addEventListener('click', function () {
  77. console.log("save start");
  78. localStorage.setItem("t-tanaka-x", x1);
  79. localStorage.setItem("t-tanaka-y", y1);
  80. localStorage.setItem("t-tanaka-w", x2 - x1);
  81. localStorage.setItem("t-tanaka-h", y2 - y1);
  82. console.log("save end", x1, y1, x2 - x1, y2 - y1);
  83. });
  84. });
  85. </script>
  86. </head>
  87. <body>
  88. <canvas id="canvas1" width="300" height="200"></canvas>
  89. <p><button id = "loadbutton" >ロード</button>
  90. <button id = "savebutton" disabled>セーブ</button></p>
  91. </body>
  92. </html>

解説

  • 演習6-1の54行目から57行目と71行目から74行目の処理をdrawという関数にまとめ(22行目から29行目),呼び出している(63行目,78行目).
  • 66行目
    • disable属性の削除
  • 99行目
    • disable属性を追加

演習6-3

演習6-2のスクリプトを次のように変更せよ.

  • x, y, w, hを個別にセーブする代わりにx, y, w, hの4つのプロパティもつオブジェクトをセーブするようにする.
    • オブジェクトをセーブするにはJSON(JavaScript Object Notation)文字列に変換するのが便利.
    • localStorage.setItem(“オブジェクト”, JSON.stringify(obj))でobjを文字列に変換して”オブジェクト”という名前でローカルストレージにセーブする.
    • JSON.stringify(obj)でオブジェクトobjが文字列に変換される.
    • 逆にJSON.parse(obj_str)で文字列obj_strがJavascriptのオブジェクトに変換される.
    • obj = JSON.parse(localStorage.getItem(“オブジェクト”))でオブジェクトという名前でセーブされているJSON文字列を取り出し,Javascriptオブジェクトに変換してobjに代入する.
  • drawの引数もx, y, w, hの代わりに,x, y, w, hの4つのプロパティをもつオブジェクトとする.

解答例

別ウィンドウで表示

ソース

  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. draw_flag, // 描画中か否か(ドラッグ中か否か)
  17. loadButton, saveButton,
  18. rect; // セーブするオブジェクト(x, y, w, h)
  19. function draw(rect) {
  20. console.log("draw start");
  21. context.clearRect(0, 0, canvas.width, canvas.height);
  22. context.strokeStyle = "#000000";
  23. context.beginPath();
  24. context.strokeRect(rect.x, rect.y, rect.w, rect.h);
  25. console.log("draw end", rect);
  26. }
  27. rect = {};
  28. canvas = document.getElementById("canvas1");
  29. context = canvas.getContext("2d");
  30. draw_flag = false;
  31. // マウスダウンの処理
  32. canvas.addEventListener("mousedown", function (e) {
  33. var bcr;
  34. console.log("mousedown start");
  35. // ドラッグ中
  36. draw_flag = true;
  37. // イベントのターゲット(キャンバス)の座標を取得
  38. bcr = e.target.getBoundingClientRect();
  39. // マウスダウンの座標を記憶
  40. rect.x = e.clientX - bcr.left;
  41. rect.y = e.clientY - bcr.top;
  42. rect.w = rect.h = 0;
  43. console.log("mousedown end", rect);
  44. }, false);
  45. // マウスアップの処理
  46. canvas.addEventListener("mouseup", function (e) {
  47. console.log("mouseup start");
  48. var bcr;
  49. // ドラッグ中でなければ何もしない.
  50. if (draw_flag === false) {
  51. return;
  52. }
  53. // イベントのターゲット(キャンバス)の座標を取得
  54. bcr = e.target.getBoundingClientRect();
  55. // マウスアップの座標
  56. rect.w = e.clientX - bcr.left - rect.x;
  57. rect.h = e.clientY - bcr.top - rect.y;
  58. // 矩形を描画
  59. draw(rect);
  60. // ドラッグ中ではない
  61. draw_flag = false;
  62. saveButton.removeAttribute("disabled");
  63. console.log("mouseup end", rect);
  64. }, false);
  65. loadButton = document.getElementById("loadbutton");
  66. loadButton.addEventListener('click', function () {
  67. console.log("loadfile start");
  68. rect = JSON.parse(localStorage.getItem("t-tanaka-rect"));
  69. draw(rect);
  70. console.log("loadfile end", rect);
  71. });
  72. saveButton = document.getElementById("savebutton");
  73. saveButton.addEventListener('click', function () {
  74. console.log("save start");
  75. localStorage.setItem("t-tanaka-rect", JSON.stringify(rect));
  76. console.log("save end", rect);
  77. });
  78. });
  79. </script>
  80. </head>
  81. <body>
  82. <canvas id="canvas1" width="300" height="200"></canvas>
  83. <p><button id = "loadbutton" >ロード</button>
  84. <button id = "savebutton" disabled>セーブ</button></p>
  85. </body>
  86. </html>

解説

  • 21行目
    • drawの引数をx,y,w,hのかわりにそれら4つの値をプロパティとしてもつオブジェクトrectとする.
  • 30行目,44行目から46行目,61行目から62行目
    • x,y,w,hの4つのプロパティをもつrectというオブジェクトを導入し,マウスダウン,マウスアップの度に値を設定.
  • 74行目
    • JSON.parseで,JSON形式の文字列をオブジェクトに変換
  • 82行目
    • JSON.stringifyで,オブジェクトをJSON文字列に変換

参考

Canvasを使ったドローツールの拡張