LoginSignup
0
0

More than 3 years have passed since last update.

【入門者向け】Canvas入門講座#18 canvasに描いた内容を保存、復元してみよう【JavaScript】

Posted at

問題18

クリックした座標を中心に四角形を描画しなさい。
四角形は赤色(#ff0000)で塗りつぶすこと。
四角形は1辺の長さが30の正方形とする。
saveボタン押下で描画内容をlocalStorageへ保存すること
loadボタン押下でlocalStorageから復元すること

以下のHTMLを使用すること。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>問題18</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
    $('#my-canvas').click(e => {
    });

    $('#save-button').click(e => {
    });

    $('#load-button').click(e => {
    });    
});
</script>
</head>
<body>
<canvas id="my-canvas" width="500" height="300"></canvas>
<br>
<button id="save-button">save</button>
<button id="load-button">load</button>
</body>
</html>

解答

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>問題18</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
    // ローカルストレージのキー
    const LOCAL_STORAGE_KEY = 'q18';

    // 四角形の中心座標群
    let rectArray = [];

    $('#my-canvas').click(e => {
        const cursorX = e.offsetX,
            cursorY = e.offsetY;
        // 配列に追加
        rectArray.push({
            x: cursorX,
            y: cursorY
        });
        // 四角形群を描画
        drawRectArray(rectArray);
    });

    $('#save-button').click(e => {
        const item = JSON.stringify(rectArray);
        localStorage.setItem(LOCAL_STORAGE_KEY, item); 
    });

    $('#load-button').click(e => {
        const item = localStorage.getItem(LOCAL_STORAGE_KEY);
        if(!item) {
            return;
        }
        rectArray = JSON.parse(item);
        drawRectArray(rectArray);
    });    

    function drawRectArray(array) {
         // コンテキストを取得
        const ctx = $('#my-canvas')[0].getContext('2d');

        // 現在の描画状態を保存する
        ctx.save(); 

        // canvasをクリアする
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

        // 塗りつぶしの色を赤(#ff0000)にする
        ctx.fillStyle = '#ff0000';

        // 四角形をすべて描画する
        array.forEach(elm => {
            // (elm.x, elm.y) を中心に1辺が30の正方形を塗りつぶす
            ctx.fillRect(elm.x - 15, elm.y - 15, 30, 30);
        });

        // 描画状態を保存した時点のものに戻す
        ctx.restore();
    }
});
</script>
</head>
<body>
<canvas id="my-canvas" width="500" height="300"></canvas>
<br>
<button id="save-button">save</button>
<button id="load-button">load</button>
</body>
</html>

解説

ローカルストレージへ保存するためには固定のキー(適当な文字列)を決める必要があります。
四角形の中心座標を配列で持つことにします。

// ローカルストレージのキー
const LOCAL_STORAGE_KEY = 'q18';

// 四角形の中心座標群
let rectArray = [];

canvasクリック時にカーソルの座標を配列へ追加し、canvasをクリアして全て描画します。

$('#my-canvas').click(e => {
    const cursorX = e.offsetX,
        cursorY = e.offsetY;
    // 配列に追加
    rectArray.push({
        x: cursorX,
        y: cursorY
    });
    // 四角形群を描画
    drawRectArray(rectArray);
});

function drawRectArray(array) {
     // コンテキストを取得
    const ctx = $('#my-canvas')[0].getContext('2d');

    // 現在の描画状態を保存する
    ctx.save(); 

    // canvasをクリアする
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

    // 塗りつぶしの色を赤(#ff0000)にする
    ctx.fillStyle = '#ff0000';

    // 四角形をすべて描画する
    array.forEach(elm => {
        // (elm.x, elm.y) を中心に1辺が30の正方形を塗りつぶす
        ctx.fillRect(elm.x - 15, elm.y - 15, 30, 30);
    });

    // 描画状態を保存した時点のものに戻す
    ctx.restore();
}

saveボタン押下時に四角形の中心座標配列をJSON.stringifyメソッドでJSON文字列変換して
ローカルストレージへ保存します。
localStorage.setItem(keyName, keyValue);
keyNameはキー(今回は'q18')で、keyValueが今回はJSON文字列です。

$('#save-button').click(e => {
    const item = JSON.stringify(rectArray);
    localStorage.setItem(LOCAL_STORAGE_KEY, item); 
});

saveボタン押下時にローカルストレージへ保存されているJSON文字列を取得し
JSON.parseメソッドで復元します。
ローカルストレージへ何も保存されていない場合は、
localStorage.getItemがnullを返すのでその時は何も処理を行わないようにします。

$('#load-button').click(e => {
    const item = localStorage.getItem(LOCAL_STORAGE_KEY);
    if(!item) {
        return;
    }
    rectArray = JSON.parse(item);
    drawRectArray(rectArray);
});    
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0