HAVRMの空空活動誌

「空空」は「うつらうつら」と読むらしいです.まぁ常に寝不足なもんで...

Windyのスクリーンセイバーの製作 -2/4-

こんにちは,HAVRMです.

久々にスクリーンセイバーの製作について更新しようと思います.

さて,前回ではWindyのAPIを使ってスクリーンセイバーで表示する画面まで作りました.
havrm.hatenablog.com

つぎはオフライン時の処理を書きます.

はじめに

もう一度スクリーンセイバーの製作について流れを確認しましょう.

  1. Windyを表示できるHTMLを作成する
  2. インターネットに接続していないときの処理を行う ←今ここ
  3. HTMLをEXE化する.この際全画面表示できるようにする
  4. スクリーンセイバーを設定する

ということでオフライン時の処理を考えます.今回作るスクリーンセイバーはインターネットに接続してないと当然のことながら気象状況が表示されません.実際にやってみるとわかるのですが,今のソースの場合では背景の黒色のみ表示されます.当然オフライン時にPCを使い,スクリーンセイバーが起動するほど放置することもあると思います.その時に黒一色だと味気ないのでその時の処理を書いていきます.

作りたいスクリーンセイバー

とりあえず,スクリーンセイバーのデザインです.
今回作るスクリーンセイバーは次のような機能を持つとしていました.

  • 画面いっぱいにWindyの画面を出す
  • 中心は東京あたりに設定し現在の状況を表示する
  • 表示するのは「雨・雷」「風」「気温」「湿度」「気圧」「海流」「波」の7つとし,表示は5秒ごとに自動で切り替わるようにする
  • どのAPIを使っているのかわかるようにする
  • Windyを動かせるようにスクリーンセイバーはボタンを押すことで終了する
  • オフラインの時はWindyが表示できないのでデモンストレーションの動画を再生する
  • 当然スクリーンセイバーなので全画面に表示する

今回は赤文字の実装を行います.

実際にプログラミング

オフラインの認識方法

ということでオフライン時に上にあるように動画を流すとすると,まず何よりもオフラインかどうか認識する必要があります.JavaScriptにはオフラインかどうかを認識できる方法がありますが,もっと簡単にいきましょう.
あらためて現在のコードの最初を見てみましょう

<html>
  <head>
    <script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"></script>
    <script src="https://api4.windy.com/assets/libBoot.js"></script>
      <style>
        <!--省略-->
      </style>
   </head>
   <!--省略-->
</html>

scriptタブでJavaScriptを読み込んでいます.これのソースはインターネットなのでオフラインの場合このインポートから失敗します.ではこのインポートが成功するかどうかでオフラインかどうか認識しましょう.

オフラインを認識するためのコーディング

オフラインの際はそれ専用のページに移動するということにして(というのもその方が楽なので),コーディングをしましょう.
インポートに失敗した場合にある関数を実行する場合には次のように書けます.

<script onerror="hogehoge()" sec="url"></script>

ここでのhogehoge()は関数です.この関数は用意しておく必要があります.
ということでこれを適応しましょう.適応するのはWindyのAPIにしておきましょう.

<html>
  <head>
    <script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"></script>
    <script onerror="offline()" src="https://api4.windy.com/assets/libBoot.js"></script>
      <style>
        <!--省略-->
      </style>
   </head>
   <!--省略-->
</html>

これでオフライン時の認識はできるようになりました.

オフライン時の動作を規定する

上でオフライン時にoffline()という関数を動かすようにできました.しかし,この関数自体が今ないので作る必要があります.この関数では動画を再生可能なoffline.htmlを呼び出します.
ということでコーディングです.新たにscriptタブを作り目的のページに移動するコードを書きます.

    <script>
      function offline() {
        window.location.href = 'offline.html';
      };
    </script>

オフライン用ページの作成

ここまででオフラインを認識し,オフライン用のサイトに跳ぶまでできました.これから跳ぶ先のページを作ります.オフライン用のページではデモンストレーションを表示します.デモンストレーショといってもただの動画なので好きなものにしても問題ないです.
のちにこのHTMLをEXE化する際のソフトの影響で動画の拡張子は.oggとします.他でも大丈夫だった気もしますがちょっと覚えてないです...
実際の写真はこれです.

f:id:HAVRM:20190906144853p:plain
デモンストレーション画像
もとはUbuntuのブラウザ上で表示してそれをrecordmydesktopで保存したものになります.これにWindows Media Makerで文字を埋め込みました.異臭分の動画でこれをひたすら無限ループで再生します.また念のため,動画が再生されない場合のためにこの動画の静止画も用意します.
まぁ,説明はここまでにしてとりあえずソースを見ましょう.

<!DOCTYPE html>

  <body bgcolor="black">
    <video autoplay loop poster="SR_Windy.png" width="100%">
      <source src="SR_Windy.ogg">
    </video>
    <p align="right"><font color="white"><input type="button" value="END" onClick="window.close()"></font></p>
  </body>
</html>

videoタブでは自動スタートを示すautoplay,繰り返しを示すloop,表示されないときの画像を指定するposterで構成します.その中のsourceタブで再生する動画を指定します.あとはこの画面を閉じるためのボタンを作って終わりです.

まとめ

ということでここまで書いてきたコードをまとめましょう.
~本体~

<html>
  <head>
    <script>
	  function offline() {
	    window.location.href = 'offline.html';
	  };
	</script>
    <script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"></script>
    <script onerror="offline()" src="https://api4.windy.com/assets/libBoot.js"></script>
  	<style>
  		#windy {
  			width: 100%;
  			height: 94%;
  		}
  	</style>
  </head>
  <body bgcolor="black">
    <div id="windy"></div>
    <script>
    const options = {
                key: 'your_key',
                verbose: true,
                lat: 38,
                lon: 139.6,
                zoom: 4,
                timestamp: Date.now(),
        }
    windyInit( options, windyAPI => {
        const { store, map } = windyAPI

        var overlays = ['rain','wind','temp','rh','pressure','currents','waves']
        , i = 0
        setInterval( ()=> {
                i = ( i === 6 ? 0 : i + 1)
                store.set('overlay', overlays[ i ])
                store.set('timestamp', Date.now());
        }, 5000)
    })
    </script>
	<p align="right">
	<font color="white"><strong id="lays"></strong>We are using Windy API v4, Leaflet v1.4.0. <input type="button" value="END" onClick="window.close()">
	</font></p>
  </body>
</html>

~オフライン用~

<!DOCTYPE html>

  <body bgcolor="black">
    <video autoplay loop poster="SR_Windy.png" width="100%">
      <source src="SR_Windy.ogg">
    </video>
    <p align="right"><font color="white"><input type="button" value="END" onClick="window.close()"></font></p>
  </body>
</html>

実際に実行するとこうなります.










We are using Windy API v4, Leaflet v1.4.0.