九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、このところElectronアプリの記事をよく書いているので、いろいろと新しい発見があり、スキルも向上しているのでは??と個人的に嬉しい状況が続いています。
また、これまであまりデスクトップアプリに関わる機会がなかったため、Electron開発は初めて海外に行った時のような新鮮な気分になったりもしています。
そして、ぜひ多くの人にもそんな新鮮さを感じてもらいたいので、今回はビギナーさんたちのために、できるだけ簡単につくれるお絵かきアプリの作り方を紹介します。
最後に教材ソースコードをダウンロードできますので、ぜひ参考にしながら開発してみてくださいね。

※ 開発環境: Electron 2.0
目次
やりたいこと
- マウスを使って自由に絵を描ける
- 色を変更できる
- 画像を保存できる
の3つです。
では実際に開発していきましょう!
Electronのインストール
インストールは、初心者向き!electron で簡単なメモ帳をつくってみようの “electronのインストール” に詳しく書いてあるので、そちらを見てください。
フォルダ名はoekaki(お絵かき)です。

アプリの設定をする
アプリの設定はmain.jsで行います。ウィンドウサイズ、位置、そしてメニューバーを非表示にします。
mainWindow = new BrowserWindow({
width: 350,
height: 350,
x: 0,
y: 0,
autoHideMenuBar: true,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true
}
})
【追記:2020.3.19】Electron v5以降のためにwebPreferencesを追加しました。
そして、npm startコマンドでElectronを実行すると次のようなウィンドウが表示されます。

ではこのウィンドウ上にお絵かきアプリのレイアウトを作っていきましょう!
レイアウトをつくる
レイアウトを作るのに便利なので、bootstrapをインストールします。
npm i bootstrap --save
ではレイアウトのHTMLコードです。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>お絵かきアプリ!</title>
<link rel="stylesheet" href="./node_modules/bootstrap/dist/css/bootstrap.min.css">
<style>
body {
padding: 15px 0;
}
#canvas {
border: 5px solid #ddd;
margin-top:15px;
}
#button {
position: absolute;
right: 15px;
bottom: 15px;
}
.color-box {
width: 25px;
height: 25px;
border:1px solid #ccc;
}
</style>
</head>
<body>
<div id="app" class="container">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<button class="color-box" style="background:#f00"></button>
<button class="color-box" style="background:#00f"></button>
<button class="color-box" style="background:#ff0"></button>
<button class="color-box" style="background:#0ff"></button>
<button class="color-box" style="background:#0f0"></button>
<button class="color-box" style="background:#000"></button>
<button class="color-box" style="background:#fff"></button>
←色を選択してください
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<canvas id="canvas" width="460" height="300"></canvas>
</div>
</div>
<button id="button" class="btn btn-lg btn-dark" type="button">保存する</button>
</div>
<script>
require('./renderer.js')
</script>
</body>
</html>
まずbootstrapのCSSを読み込んで、上から色選択ボックス、キャンバス、最後に保存ボタンを配置しています。
※ ちなみに<canvas>のサイズをCSSで指定すると歪んでしまうことがありますので、サイズはHTMLのプロパティにwidthとheight追加してください。
実際の例がこちらです。

白い空白部分に絵を描けるようにします。
では、次からJavaScriptの部分をつくっていきましょう!
JavaScript部分をつくる
色選択する部分をつくる
いつもならVueを使ってサクッとコードを作っていきますが、今回は初心者向けですので、どのような環境にも適用できるネイティブなJavaScript(つまりフレームワークを使わない)でコードを書いていきます。(さらに、分かりやすいと思うので、ES6ではなく古いコードで書きます)
<script>
var color = 'rgb(0, 0, 0)'; // 初期値は黒
window.onload = function() {
var boxes = document.querySelectorAll('.color-box');
for(let i = 0; i < boxes.length; i++) {
var box = boxes[i];
box.addEventListener('click', function(e) {
color = e.target.style.backgroundColor; // 選択された色
})
}
};
</script>
まず、colorという色を保持する変数を作っておきます。
そして、ページが表示された時点で色の選択ボックス(.color-box)全てにクリック・イベントを設定し、クリックされたら背景色を取得してcolorを更新するようにしています。
キャンバスに絵を描く部分をつくる
続いてキャンバスに絵を描く部分です。
<script>
// 省略
var drawing = false; // マウスがクリックされているか判別
window.onload = function() {
// 省略
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canvas.width, canvas.height);
canvas.addEventListener('mousedown', function() {
drawing = true;
});
canvas.addEventListener('mouseup', function() {
drawing = false;
});
canvas.addEventListener('mousemove', function(e) {
if(drawing) {
// マウスの場所を計算
var rect = e.target.getBoundingClientRect();
var drawingX = e.clientX - rect.left;
var drawingY = e.clientY - rect.top;
// キャンバス色付け
ctx.beginPath();
ctx.fillStyle = color
ctx.arc(drawingX, drawingY, 5, 0, Math.PI*2);
ctx.fill();
}
});
};
</script>
まずマウスが今クリックされているかどうかを判別する変数drawingをつくり、mousedown、mouseupイベントでtrue ⇆ falseを切り替えます。
そして、mousemoveイベントで、マウスがクリックされている場合は<canvas>に絵を描くようにします。
なお、キャンバスは初期状態では背景が透過になるので、始めに白で全体を塗りつぶしています。
では、実際に絵を描いてみましょう!

うまくいきました!
キャンバスの絵を保存する
では最後にキャンバスに書いた絵を保存する部分です。
<script>
var fs = require('fs');
// 省略
window.onload = function() {
// 省略
var button = document.getElementById('button');
button.addEventListener('click', function() {
if(confirm('画像を保存します。よろしいですか?')) {
var dataURL = canvas.toDataURL();
var imageData = dataURL.replace(/^data:image\/png;base64,/, '');
var filename = 'oekaki-'+ Date.now() +'.png';
fs.writeFileSync(filename, imageData, 'base64');
alert('保存が完了しました!');
}
});
};
</script>
まず、画像を保存する必要があるのでファイル操作モジュールのfsを読み込みます。
そして、ボタンがクリックされたら、まず保存をするかどうかを確認をします。
もしOKが選択されたら、キャンバスからdataURL(画像データをbase64形式にしたもの)を取得し、不要な部分を取り除いてpng画像で保存しています。
ちなみにファイル名は過去の画像が上書きされないようにDate.now()を使っています。
テストしてみる
では、実際にテストしてみましょう!
保存するのは次の絵(字?)です

まず保存ボタンをクリックすると確認ダイアログがでます。

OKをクリック。
すると完了メッセージが表示されます。

では、フォルダを確認してみましょう。

画像が保存されました!
実際に保存された画像はこちらです。

お疲れ様でした!
教材ソースコードをダウンロードする
今回実際に開発したソースコードを以下からダウンロードできます。
※ ただし、npmパッケージはご自身でインストールしてください。





