🪞

鏡の前にいると集中力が上がる?自分用にElectronで常時表示Webカメラミラーアプリを作ってみた

2025/02/13に公開

利用イメージ


アプリを起動すると、右側に縦横210pxで常に前面に表示されます

作成に至るまでの経緯

普段、在宅ワークで働いています

ふと集中が途切れたときや、今フォーカスすべきタスクを整理したいときに、Mac標準アプリのPhoto Boothを起動する習慣が自分にはあったりなかったりします

狙いとしては、自己認識が高まり、やらねばという気持ちになったり、シンプルに姿勢の崩れに気づけたりとかですね

個人差はあると思いますが、それなりに効果を実感できている気がしています

Photo Boothに対する2つの不満

あくまで自分の用途的にという話ではありますが

  1. ウィンドウの最小サイズが大きい
  2. 常に前面表示ができない

の2点を、よりよくできないかなと考えていました

例によって、ChatGPTに雑に聞いてみる

必要に応じては自作するのもあり、というような聞き方をしたら、Electronアプリ作ってみたらとレスポンスがあり、試しにやってみることに

実際に作ってみる

https://github.com/aokiken/webcam-mirror/

※ 普段Electronアプリを作る人ではないので、色々とツッコミどころがあるかも

まずは動くところまで

プロジェクトを作成

$ mkdir webcam-mirror
$ cd webcam-mirror
$ npm init -y
$ npm install --save-dev electron

メインプロセスを作成

main.js
const { app, BrowserWindow } = require('electron');

let mainWindow;

app.on('ready', () => {
    mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false,
        },
        alwaysOnTop: true, // ウィンドウを常に前面に表示
    });

    mainWindow.loadFile('index.html');
});

フロントエンドを作成

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Webcam Mirror</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background: black;
        }
        video {
            width: 100vw;
            height: 100vh;
            object-fit: cover;
            transform: scaleX(-1); /* ミラー効果 */
        }
    </style>
</head>
<body>
    <video autoplay></video>
    <script>
        (async () => {
            const video = document.querySelector('video');
            const stream = await navigator.mediaDevices.getUserMedia({ video: true });
            video.srcObject = stream;
        })();
    </script>
</body>
</html>

package.jsonを編集し、Electronを起動できるように

{
    "main": "main.js",
    "scripts": {
        "start": "electron ."
    }
}

無事起動 🎉

めでたい

色々と調整を加える

アプリを起動したときに、ウィンドウを画面の右端に表示できたら嬉しいなぁと思い、一部変更

main.js
const { app, BrowserWindow, screen } = require('electron');

let mainWindow;

app.on('ready', () => {
    // 画面情報を取得
    const { width, height } = screen.getPrimaryDisplay().workAreaSize; // ディスプレイの作業領域

    // ウィンドウを作成
    mainWindow = new BrowserWindow({
        width: 400, // ウィンドウの幅
        height: 600, // ウィンドウの高さ
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false,
        },
        alwaysOnTop: true, // 常に前面に表示
        frame: false,      // フレームを非表示に(必要なら)
    });

    // ウィンドウの位置を右端に設定
    const x = width - 400; // 画面の幅 - ウィンドウの幅
    const y = 0;           // 上端
    mainWindow.setBounds({ x, y, width: 400, height: 600 });

    // HTMLファイルを読み込む
    mainWindow.loadFile('index.html');
});

いい感じ

ちょっとサイズが大きいなと思ったので、最終的には縦横210pxになるよう調整

buildしてみる

しばらくの間はcliから起動して使っていました(zshにaliasを追加したり工夫しつつ)
が、やはり独立したアプリであるほうが起動や終了がしやすいよなとなり、ビルドする手順を調べはじめます

必要なパッケージをinstall

https://www.electron.build/index.html

$ npm install --save-dev electron-builder

package.jsonを編集し、Electronをbuildできるように

アイコンはいらすとやから拝借し、icnsはiconutilコマンドを使って生成
https://www.irasutoya.com/2013/05/blog-post_24.html

{
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "build": "electron-builder"
  },
  "build": {
    "appId": "your.id",
    "mac": {
      "category": "your.app.category.type",
      "icon": "assets/webcam-mirror.icns"
    }
  }
}

無事ビルド、install成功 🎉

作ってみて・使ってみての感想

まず、こういった物が欲しいなと思ったときに、自作でこのレベルのものをサクッと作れたことに感動しました(Electronすごい)

実際に使ってみると、Photo Booth を開く以外の選択肢ができたことがシンプルに嬉しいです
「作業中にふと気を抜きそうになったとき、自分の姿が視界の隅に入る」ことで、意識を戻しやすくなった気がします

ずっと右上に表示されていると、実は普通にちょっと邪魔だったりするのですが、
そのたびに 「あ、そうだ、集中しないと」 と思えるので、ある意味ではこの仕様が正解なのかもしれません

Discussion