Electron Fiddle + p5js で半透明アプリをつくる

# はじめに

![スクリーンショット 2021-12-01 15.06.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/5a99dfd6-9282-7d4a-1b4c-7d6d2ee9c112.png)
「<a href="https://adventar.org/calendars/6163">Processing Advent Calendar 2021</a>」5日目の記事です。初めての参加なのでドキドキしつつ、何を書こうかなぁと考えていたのですが、p5jsでつくったものを「半透明なアプリにできるといいなぁ」と思ったので、この内容に決めました☺️

今回はElectronとp5jsを使います。ElectronはWEBの技術（HTMLやJavaScriptなど）を使ってクロスプラットフォームなPCアプリをつくることができるものです。p5jsもJavaScriptなので、アプリがつくれるというわけです。そして今回はElectronの導入を簡単にするために、画像や動画などのファイルは扱わないことにします。この場合、Electron Fiddleという開発環境をダウンロード＆インストールして使えるので気軽にトライできると思います。もっといろいろやってみたい場合は、VS-CodeなどでElectron開発環境を整えれば（その準備がいろいろ面倒ですが）、画像や動画も扱うことができたり、アプリのアイコンも自由に変更できたりします。

また、アプリ画面全体を半透明にするのはとてもシンプルで、Electron Fiddleでの透明設定だけでよいのですが、均一な半透明ではない（不透明と半透明を混在させたい）場合は、さらにElectron Fiddleでウィンドウのカスタマイズ（フレームなし等）や、p5jsでの透明設定、フレームなしでは画面をマウスで移動できなくなるので、cssでドラッグできる設定を組み合わせたりと、少し複雑になってきます。どこに何をする設定を書いたか混乱しないように意識しておくとよいかなと思います。

なお、この記事の画面キャプチャはmacOSのみですが、Windowsでもほぼ同じように動作すると思います。以下はmacOSの仮想PC（Windows10 Home）で実行したものです。

![スクリーンショット 2021-12-02 20.29.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/ffed3758-bfe8-b2ea-633d-a4dff1817ee0.png)

ソースはこちらです。4タイプの半透明バリエーションのデータが、4つのフォルダに分かれています。

https://github.com/mathrax-s/electron-transparent


---

# 前半：Electron Fiddle

Electronは、WEBの技術（HTMLやJavaScriptなど）でクロスプラットフォームのアプリをつくることができるものです。ただ、その開発環境を整えるまでに、コマンドでインストールする作業があったりして、慣れてないと難しく感じるかもしれません。でも大丈夫です。「Electron Fiddle」というツールを作ってくれていて、一般的なソフトのインストーラのように、ダウンロードしてインストールすれば、Elecronの開発環境が整います。ちなみに「Fiddle」は「いじる・いじくる」という意味だそうで、Electronの中身をすぐに「いじる・いじくる」ことを意識して作られたツールなのかなと思います。

## Electron Fiddleをインストール

![スクリーンショット 2021-11-30 11.21.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/f6f0c9e9-c0b7-bd64-6b4e-f09a404e1b89.png)

ここからダウンロードしてインストールします。
https://www.electronjs.org/fiddle

![スクリーンショット 2021-11-30 12.34.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/3df8e4c4-69d3-5458-1b75-7695c7925553.png)
![スクリーンショット 2021-11-30 12.36.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/09b3d35e-68e6-ca4a-cfe8-5d928fd5f361.png)

macOSとWindowsだけでも複数あるので、自分の環境にあったものを選びましょう。ダウンロードできたらインストールしてください。



## Electron Fiddleを起動する

![スクリーンショット 2021-11-30 12.47.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/17bfcadb-65f2-dc1a-6bbb-40c5a308d88e.png)
Electron Fiddleを起動すると、画面が4分割されたエディタが開き、4種類のファイルが自動的に作られます。

- main.js
- preload.js
- renderer.js
- index.html

最低限必要なファイルは上の4つです。他には、アプリに書き出す「パッケージ化」を実行すると「package.json」が自動で追加されます。さらにp5jsやcssを使う場合は、「p5.js（またはp5.min.js）」「styles.css」などを手動で追加できます。Electron Fiddleから手動で追加することもできますが、空のファイルを作るだけなので、そこに手打ちしたりコピペしたりすることになります。なので、p5jsやcssを使える状態で保存したデータを、Electron Fiddleから「File > Open」したほうが、関連ファイルを読み込んでくれるので楽です。

また、Electron Fiddleは保存されたデータを直接参照するのではなく、いったんハードディスクにコピーして使います。「File > Open」で保存したフォルダを開くと、そこにある上記4種類以外のファイルを、追加でコピーできます。ただし、コピーできるのはhtml,js,css形式のみで、画像や動画はコピーできません。つまりElectron Fiddleではローカルの画像や動画ファイルを使うことができないということになります（今のところ）。

この記事後半のp5jsを使う場面では、p5jsやcssを使えるようにしたデータをElectron Fiddleから「File > Open」することにします。

## 「Hello World!」アプリを実行する

![スクリーンショット 2021-11-30 12.56.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/5287c59f-53eb-7c96-5e1b-de4b1206e913.png)

Electron Fiddleを起動しただけの状態で、まだなにもプログラムしなくても「Hello World!」アプリを実行することができます。実行する手順だけ確認しておきましょう。

![スクリーンショット 2021-11-30 12.56.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/2d795fc9-900d-69c6-1e70-2132ecb116ba.png)

開発中ですぐに試したいときは、「RUN」ボタンを押せば、Electronアプリが実行されます。

![スクリーンショット 2021-11-30 12.58.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/8f1dee5c-acad-67b8-7690-04a061adb1fe.png)

プログラムが完成したら、パッケージ化して、ダブルクリックで開くアプリに書き出すこともできます。少し時間がかかりますが、パッケージ化が終わると書き出されたフォルダが開きます。


## 画面全体を半透明にする

Electron Fiddleだけで全画面を半透明にできます。main.jsの5行目あたり、「createWindow」関数に、opacityというパラメータを追加します。とてもシンプルです。opacityの「0.5」の部分は、「0.0〜1.0」まで変えられます。

~~~main.js
function createWindow () {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    opacity: 0.5, // ←　これを追加　0.5は、50％の透過度になる
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })
...省略
}
~~~

## 実行してみる

### macOS（Catalina 10.15.7）

![スクリーンショット 2021-11-03 11.49.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/d3603d74-f2de-fc40-eb46-b484a7453046.png)


### Windows（macOSの仮想PC・Windows10 Home）

![スクリーンショット 2021-11-03 11.51.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/96d3656a-d4e0-189f-4d9e-4a59b190d104.png)

---

# 後半：p5js

では次にp5jsにうつります。p5js側からも透明度を変えることで、前述のmain.jsだけではできない半透明を実現することができます。

Electron Fiddleでは、p5jsはインスタンスモードで書きます。インスタンスモードとは、JavaScriptのなかでグローバルに展開しているp5jsの関数たちを、ローカルなインスタンスを作ってその中で完結させるための書き方です。そうすることで、いろんなライブラリや自作関数と一緒に使ったとき、もしもそれらの名前がp5jsで予約された関数名や変数名と重複してしまっても、エラーが起きないようにすることができます。

## もとのp5jsコード

テストとして、自分のつくったOpenProcessingのコードを使ってみます。マルがゆらゆらするコードです。OpenProcessingでもインスタンスモードで書けました。

https://openprocessing.org/sketch/1373500

## Electron Fiddleでp5jsを実行

Electron Fiddleでp5jsを使うための準備は<a href="https://qiita.com/mathrax-s/items/af6e3e4cdb4fe9622783">こちら</a>にも書かせていただきました。簡潔に説明すると、いくつか方法がありますが「index.htmlでp5.js（またはp5.min.js）を読み込んでおく」という方法に落ち着きました。Electron v11までは<a href="https://qiita.com/mathrax-s/items/79c1170301a5faa08867">こちらの記事</a>のようにとてもわかりやすかったのですが、Electron v12以降にセキュリティ面に大きな変更があったのでそれに対応したものです。

この準備が省略できるよう、Electron Fiddleでp5jsが使える状態にした今回のサンプルを、Githubにアップしていますので、記事とあわせて見てみてください。半透明のバリエーションが少しずつ異なる4つのフォルダがあります。Electron Fiddleから「File > Open」で各フォルダを開いて使ってください。

https://github.com/mathrax-s/electron-transparent


各フォルダ内のファイルは、以下のように中身を整えています。

- 「p5.min.js」「styles.css」ファイルを追加
- 「index.html」で、「p5.min.js」「syles.css」を読み込み
- 「renderer.js」に、p5jsインスタンスモードのコードを書く

※ p5jsコードを変えたい場合は、「renderer.js」だけを変更するとよいです。


そしてフォルダを開く際、以下のように、「p5.min.js」ファイルを追加するか聞いてきますので「add」を押してください。
![スクリーンショット 2021-12-02 12.01.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/7657fcf9-faed-770b-405a-2bd9ac9a0c8f.png)


## 全画面を半透明に（transparent_01）

![スクリーンショット 2021-12-02 12.15.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/45aacc22-591d-6ef9-38b0-d3ba39ab9ff1.png)
Githubのデータの「transparent_01」というフォルダを、Electron Fiddleで開いて、「RUN」ボタンで実行してみてください。

まずは最もシンプルな半透明を試してみましょう。main.jsの「opacity」で全画面を半透明にしたものです。opacityの「0.5」の部分を「0.0〜1.0」の間で変えて、ふたたびRUNして実際の透明感を確認してみてください。

# 応用：組み合わせ

ここからは、Electron Fiddle、p5js、cssを組み合わせて、半透明のバリエーションを見ていきます。

## ウィンドウのカスタマイズ（Electron Fiddle）

画面全体を透明にするのは、main.jsに「opacity」を1行書くだけでしたが、ほかにも「フレームなしにする」とか、「画面の背景を透明にする」とか、「フルスクリーンにする」とかできます。これらを組み合わせると、おもしろい効果が生まれそうです。また、画面のすべてのマウスイベントを無視させる「クリックスルーウィンドウ」もつくることができるので、p5jsのコンテンツを表示させながら、透けて見える後ろの画面の操作を行うこともできます。ソフトウェアで実験的な作品を作ったりする場合はおもしろそうです。

ただし注意点としては、「フレームなし」にするとウィンドウをマウスでつかむ場所がなくなり、ドラッグできなくなるのでウィンドウを移動させることができません。回避策としてCSSでドラッグできる設定を加えるなど、組み合わせによっては、細かいポイントがあるようです。他にどんなパラメータが設定できるのか知りたい場合は、Electron公式ドキュメントをみるとよいでしょう。

https://www.electronjs.org/ja/docs/latest/api/browser-window

https://www.electronjs.org/ja/docs/latest/tutorial/window-customization#create-frameless-windows

### フレームなしとCSS（transparent_02）

![スクリーンショット 2021-12-02 12.57.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/3fb73d22-dc6c-69ce-e9c1-75509fd4f7dd.png)
Githubのデータの「transparent_02」というフォルダを、Electron Fiddleで開いて、「RUN」ボタンで実行してみてください。

以下のように「frame: false」と書くと「フレームなし」にできます。「フレームなし」では、ウィンドウのタイトルバーや枠などが消えます。ですが、マウスでつかむ場所がなくなってしまい、画面を動かすことができなくなります。画面を動かしたい場合は、cssを組みわせて対応できます。

「さっきの全画面を半透明にする（transparent_01）とどこがちがうの？」と思った人もいるかもしれないので、違う部分を拡大しておきました。ウィンドウのバーが消えています。これが「フレームなし」状態です。微妙ですが大きな違いです。
![noframe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/2ea09888-522e-55e2-dd7e-96b7fee7a72b.png)

~~~main.js
function createWindow () {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    opacity: 0.5,                // ←画面全体の透明度
    // 'titleBarStyle': 'hidden',   // ←macOSのみ
    // transparent: true,           // ←画面の背景を透明にする
    frame: false,                // ←フレームなしにする
    width: 600,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })
...省略
}
~~~

~~~style.css
html, body {
  margin: 0;
  padding: 0;
  -webkit-app-region: drag;  // ←画面をドラッグできるようにする
}

canvas {
  display: block;
}
~~~


## 画面の背景を透明にして残像を消す（p5js）

完全な透明でない背景色の場合は、draw関数のなかで「background(0)」のようにして、背景を塗りつぶしてから、マルを描くことを繰り返すことで、直前に描いたマルを背景色で塗り消し、新しいマルを1つだけ画面に表示することができます。ですが、完全な透明にしたい場合は「background(0,0）」のように塗りつぶしても、透明なので塗り消すことができませんでした。「clear()」を使うことで塗り消すことができました。

### background(0,0)の場合（transparent_03）

![スクリーンショット 2021-12-02 13.02.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/8a551dec-b5ef-bfc5-a0c5-12a68248ce92.png)
Githubのデータの「transparent_03」というフォルダを、Electron Fiddleで開いて、「RUN」ボタンで実行してみてください。

「background(0,0)」で背景を完全な透明で塗りつぶすと、当たり前ですが、、透明なのでマルを消すことができず、ずっと残像が残ってしまいます。でも、これはこれでおもしろいです。

### clear()の場合（transparent_04）

![スクリーンショット 2021-12-02 13.04.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/8771c2e8-f9b1-5286-05d7-9a218d015121.png)
Githubのデータの「transparent_04」というフォルダを、Electron Fiddleで開いて、「RUN」ボタンで実行してみてください。今回の記事の最終形態です。

透明で塗りつぶしたいなぁとtwitterでつぶやいたところに、<a href="https://twitter.com/takawo/status/1465972930043539458">takawoさんからアドバイスいただき</a>「clear()」でできました！！

「clear(）」の代わりに、画面の色情報の「pixels」配列で、全ピクセルのアルファチャンネルを0で埋めることでも透明化できたのですが、処理が重くなりすぎて実用的ではないかなぁという感じでした。ですが「clear()」なら処理も軽く、フルスクリーンでもいけそうです。ありがとうございました！


この状態にするには、以下の3つを組み合わせています。

- main.jsで、背景を透明にする設定と、フレームなしの設定をする
- styles.cssで、ウィンドウをドラッグできる設定を追加する
- p5jsのdraw関数で「clear()」しながら描く

~~~main.js
function createWindow () {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    // opacity: 0.5,                // ←画面全体の透明度
    // 'titleBarStyle': 'hidden',   // ←macOSのみ
    transparent: true,           // ←画面の背景を透明にする
    frame: false,                // ←フレームなしにする
    width: 600,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })
...省略
}
~~~

~~~style.css
html, body {
  margin: 0;
  padding: 0;
  -webkit-app-region: drag;  // ←画面をドラッグできるようにする
}

canvas {
  display: block;
}
~~~

~~~renderer.js
const s = (p) => {

...省略

	p.draw = () => {
		p.clear(); // ←「background（0,0）」の代わり
		for (let i = 0; i < 6; i++) {
			p.fill(30 * i, 255 - 30 * i, 200, 100);
			p.ellipse(p.width / 2 + p.param(500 * i, 5000) * 200, 50 + 100 * i, 200, 200);
		}
	}

...省略

}
~~~

# 補足：パッケージ化してアプリに

![スクリーンショット 2021-11-30 12.58.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/8f1dee5c-acad-67b8-7690-04a061adb1fe.png)

念のためパッケージ化してアプリとして書き出し、動作確認しておきます。少し時間がかかると思いますが、パッケージ化が終わるとフォルダが開きます。

![スクリーンショット 2021-12-02 15.02.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/884e7dcf-8c94-b224-4b5a-d977c4cfa77b.png)
「out」フォルダにさらにフォルダがあり、その中のElectronアイコンのアプリが、パッケージ化されたものです。ダブルクリックで開くことができると思います。

## アプリ名が違う場合

自分で確認するとアプリ名が違うことがありました。アプリ名の設定は、Electron Fiddleがパッケージ化で自動的につくる「package.json」を確認します。たとえば、以前にパッケージ化したことがある場合は、保存してあるフォルダのなかに「package.json」が作られています。そこでアプリ名などを設定しますが、自分の場合は以前の情報がそのまま残っていました。しかし「package.json」はElectron Fiddleでは編集できず、表示もされません。なので、別途テキストエディタやVS-Codeなどで編集・上書き保存し、もう一度Electron Fiddleで「File > Open」してください。もう一度開くときに更新されるのがポイントです。
![スクリーンショット 2021-12-02 15.13.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/c5d544fd-d56e-25a3-c60f-18bdbbe10e92.png)
![スクリーンショット 2021-12-02 15.14.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668579/6aa144a9-c57d-f284-0d6c-a68a38e9dc45.png)


# おわりに

Electron Fiddleとp5jsで書いたコードで、半透明なアプリを作ることができました。単純に画面全体を半透明にするだけでなく、フレームをなくして透明な背景に不透明なマルを描くことができて、それだけでもなぜかうれしい気分になりました。

Electronをはじめようと思うと、その開発環境を整えるのに一苦労するかもしれません。でも、Electron Fiddleを使えばその手間が省けて、すぐにElectronアプリを作ることができます。ただし、html、js、css形式以外の画像や動画などのローカルファイルを使いたい場合は、VS-CodeなどでElectron開発環境を整える必要があります。いずれも、p5jsはインスタンスモードで書くので、日頃からインスタンスモードで書いているとよいかもしれません。

そして、半透明アプリを作る場合は、Electronのウィンドウカスタマイズと、p5js、cssなど、複数の方向から組み合わせました。少し強引な裏技的な印象もあって、今後も同じように対応できるかどうかわからないので、注意しておきたいところです。

半透明なアプリってゼリーみたいでいいですね🤗


# 参考にしたサイト

https://imfly.gitbooks.io/electron-docs-gitbook/content/jp/api/frameless-window.html

https://www.electronjs.org/ja/docs/latest/api/browser-window

https://www.electronjs.org/ja/docs/latest/tutorial/window-customization#create-frameless-windows