Electron, JavaScriptでアナログ時計ウィジェットを作る【Electron入門】

Electron,JavaScriptでアナログ時計ウィジェットを作る【Electron入門】:watch:

なぜ時計ウィジェットを?

先輩「コーディングとか集中してると時間忘れてやっちゃうよね〜」
ぼく「そうですね〜、気づいたらもうこんな時間ってなりますよね〜」
先輩「ツールバーも基本隠してるから時間わからんよね〜」
ぼく「じゃあウィジェットで時計とか置いたらいいんじゃないですか?」
先輩「Win10ってウィジェットとかあるんだっけ?」
ぼく「どうですかね〜あれだったら作りますよ」

というわけでElectron入門としてアナログ時計を作ってみよう!と思いたった私のメモ書きです。
ElectronというよりはJavaScriptでアナログ時計作ってるという感じですが・・・

Electronの環境準備

ここは思い切って割愛させていただく。
こちらの記事が大変参考になりました。

Electronでアプリケーションを作ってみよう - Qiita

準備を整えていざコーディング!

まずはデジタル時計を作ってみよう

デジタル時計なら時間を画面に出力するだけなのでとっても楽ちん。
まずはデジタル時計を作ってみる。
ソースはこちらにあります。

HTMLはこんな感じ

index.html
<body>
    <div class="clock_wrap">
        <p class="clock">
            <span class="hour"></span>:<span class="minute"></span>:<span class="second"></span>
        </p>
    </div>
</body>

スクリプトはこんな感じ 使い慣れているのでjQueryに頼ってしまう・・・

    $(document).ready(function(){
        $(function(){
            setInterval(function(){
                updateTime();
            },1000); //1秒ごとに関数を実行
        });
    });

    /*
     * 時間更新用関数
     */
    function updateTime(){
        //Dataオブジェクト作成
        var time = new Date();
    //時、分、秒を取得
        var hour = $(".hour");
        var minute = $(".minute");
        var second = $(".second");

    //全ての頭0埋め
        var H = ('00' + time.getHours()).slice(-2);
        var M = ('00' + time.getMinutes()).slice(-2);
        var S = ('00' + time.getSeconds()).slice(-2);

    //HTMLに反映
        hour.html(H);
        minute.html(M);
        second.html(S);
    }

おそまつな作りですが、1秒に一回更新用の関数を実行し、HTMLに反映しているだけです。
動作はこんな感じ

画面録画してGif化したら時が加速した・・・実際はちゃんと1秒おきなのでOK

これでデジタル版は出来ました。
ただ今回はアナログ時計が最終目標なので、これをベースにアナログ時計を作っていきます。

アナログ時計を作る

ソースはこっちにあります。

ウィンドウを丸くしたい

デジタル時計のときは気にしていませんでしたが、アナログ時計にするならウィンドウが丸くならないとカッコ悪い!
ということで、ElectronのWindowにtransparentの設定を加えます。

main.js
mainWindow = new BrowserWindow({width: 302, height: 302, frame:false,resizable:false,transparent: true});

ロジックの考え方

考え方としては、背景、長針、短針、秒針の4つのレイヤーを用意し、それぞれを時間に応じて回すことでアナログ時計を表現しようと思います。
イメージとしてはこんな感じ

HTML,CSSに落とし込む

まずHTMLは単純にこうしました。
針の画像を作成するのが面倒なので、とりあえず文字を置いてます。

index.html
<body>
    <div class="clock_wrap">
        <div class="clock_parts clock_back_ground"></div>
        <div class="hour clock_parts"><br><br><br>H<br>H<br>H<br>H<br>H</div>
        <div class="minute clock_parts">M<br>M<br>M<br>M<br>M<br>M<br>M<br>M</div>
        <div class="second clock_parts">S<br>S<br>S<br>S<br>S<br>S<br>S<br>S</div>
    </div>
</body>

CSSはこんなかんじ

clock.css
.clock_back_ground{
    border: 1px solid;
    border-radius: 200px;
    border-color: #aa00aa;
    background-color: #fff;
}

.clock_wrap{
    text-align: center;
    width: 100%;
}

body{
    margin: 0;
    -webkit-app-region: drag;
    height: 300px;
    overflow: hidden;
    -webkit-user-select: none;
}

.clock_parts{
    position: absolute;
    width: 300px;
    height: 300px;
}

.hour{
    z-index: 1;
}
.minute{
    z-index: 2;
}
.second{
    z-index: 3;
}

これでとりあえずこうなります。

スクリーンショット 2018-05-12 16.12.26.png

そこ、ダサいとか言わない。
あとは、針のレイヤーを時間に合わせて回転させれば、基本的な動作は完成します。

針のレイヤーを回転させる

時間の取得まではデジタルと同じです。

    function updateTime(){
        var time = new Date();
        var H = time.getHours();
        var M = time.getMinutes();
        var S = time.getSeconds();

取得した時間の値を元に、回転角度を割り出します。

  • 短針の回転角度
    • 360 / 12 * 時
  • 長針の回転角度
    • 360 / 60 * 分
  • 秒針の回転角度
    • 360 / 60 * 秒

これをソースに落とし込むとこうなります。

        var HRotate = 360/12*H;//短針
        var MRotate = 360/60*M;//長針
        var SRotate = 360/60*S;//秒針

        rotateClock(HRotate,MRotate,SRotate);//回転角度を反映する関数

反映する際は以下のようになります。
ElectronはChromiumで動いているので、単純にtransformではなく、-webkit-transformで回転角度を設定します。

    function rotateClock(HRotate,MRotate,SRotate){
        var hourDOM = $('.hour')
        var minDOM = $('.minute')
        var secDOM = $('.second')

        hourDOM.css("-webkit-transform", "rotate("+HRotate+"deg)");
        minDOM.css("-webkit-transform", "rotate("+MRotate+"deg)");
        secDOM.css("-webkit-transform", "rotate("+SRotate+"deg)");
  }

これで基本的な実装は完成です。
実際の動作がこんな感じになっています。

analog.mov.gif
それなりに時計っぽくなりました。

課題

  • 短針が1時間に一回しか動かない:alarm_clock:
    よりリアルなアナログ時計にするには少しずつ短針を動かす必要がある。
    1時間ごとの角度は30度なので、30/60 * 分を短針の角度に足してあげればいいかも。

  • 背景の表示がないので、何時かすぐにわからない:open_mouth:
    そこは普通に画像か何かで準備して背景に当ててやればいいかと思います。画像作るのがめんどい:stuck_out_tongue:

  • 大きさがでかい、というか自由に変えれるようにしろ:japanese_goblin:
    300px * 300pxで固定されているので、レスポンシブにする改良が必要…
    CSSはあんまり得意じゃないので誰か助けて…:dizzy_face:

まとめ

なんだかElectronというよりはJavaScriptでどうやってアナログ時計作るか、みたいな話になってしまいました・・・
アナログ時計をWebで表示したいときにも普通に使えるので良しとします。
レスポンシブの課題は致命的ですね。誰か手伝って:cry:

カスタマイズの機能をもたせてもっと使いやすいシンプルな時計にしていきたいです。
その時はまた記事を上げます。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.