- 投稿日:2019-04-13T23:51:00+09:00
枠付き文字がCSSとHTMLだけで作れる件
こんにちは、ブログ「学生ブロックチェーンエンジニアのブログ」を運営しているアカネヤ(@ToshioAkaneya)です。
枠付き文字がCSSとHTMLだけで作れる件
CSSのtext-shadhowを使うことで文字に様々なshadowをつけることが出来ます。
なんと、これをGUIで操作できるページを見つけました。
リンクはこちらです。
http://owumaro.github.io/text-stroke-generator/便利なので、ぜひ使ってみてください。
はてなブックマーク・Pocketはこちらから
- 投稿日:2019-04-13T18:54:21+09:00
JavaScriptと仲良くなろう
はじめに
jQueryなどJavaSriptをより扱いやすくしてくれる便利なファイルはありますが、
理解を深めるためにも今回は便利なものは使用せず、一からコードを記述することにしました。チェックボタンを押すと対応する3色のボタンが表示される機能を作ります。
HTML
code.html<div class="all_section"> <div class="color"> <p>Check-Box</p> <div class="Check_word">チェック</div> </div> <div class="list"> <!--チェック機能の作成--> <div class="section"> <input type="checkbox" id="check_one1" data-name="あか">赤</input> <input type="checkbox" id="check_one2" data-name="あお">青</input> <input type="checkbox" id="check_one3" data-name="きいろ">黄色</input> </div> </div> <!--チェック機能に対応するボタンを作成--> <div class="images"> <input type="button" class="one1" data-name="あか"/> <input type="button" class="one2" data-name="あお"/> <input type="button" class="one3" data-name="きいろ"/> </div> </div>CSS
code.css/*全体への装飾*/ .all_section { width: 100%; background-color: white; text-align: center; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } /*タイトル画面の装飾*/ .color { overflow: hidden; margin-top: -20px; height: 200px; background-color: #3c3d3d9a; color: antiquewhite; border-radius: 40px; } /*タイトル画面の文字への装飾*/ .color p { margin-top: 80px; font-size: 25px; } /*チェック機能部分の装飾*/ .list { width: 100%; margin-top: 100px; font-size: 20px; color: antiquewhite; border-radius: 20px; background-color: #9cce8b; } /*チェックの装飾*/ .list input { margin: 10px; color: #3c3d3d9a; border-radius: 20px; } /*ボタン機能の装飾*/ .images input { width: 100px; height: 100px; margin-top: 100px; margin-left: 10px; margin-right: 10px; } /*赤ボタンの装飾*/ .one1 { background-color: #fa1919; } /*青ボタンの装飾*/ .one2 { background-color: #1900ff; } /*黄色ボタンの装飾*/ .one3 { background-color: #fbff04; }JavaScript
code.js// 画面の対象の画像を全て隠す関数 function hideAllImages() { const images_off = document.querySelectorAll('.images input'); images_off.forEach(function (image) { //画像を非表示 image.style.visibility = "hidden"; }); } // 値が変更された時に呼ばれる関数 function onChangeValue() { // 全ての画像を非表示 hideAllImages(); //input(チェックボタン)のデータをすべて取得 const sec_checkboxes = document.querySelectorAll('.section input'); //imagesのデータをすべて取得 const all_images = document.querySelectorAll('.images input'); //1つずつ取得したデータのdata-nameを1つずつ取得 sec_checkboxes.forEach(function (checkbox) { const checkbox_name = checkbox.dataset.name; //その中でもしチェックされていたらimagesデータを取得 if (checkbox.checked) { all_images.forEach(function (image) { const image_name = image.dataset.name; //該当のdata-nameがあったら表示 if (image_name.indexOf(checkbox_name) >= 0) { image.style.visibility = "visible"; } }); } }); } // 画面を読み込んだときに呼ばれる関数 function onLoad() { // 全て非表示 hideAllImages(); // 値が変更された時に呼ばれる関数(イベントを登録する) document.addEventListener("change", onChangeValue); } //ウィンドウがロードした時に起動 window.addEventListener("load", onLoad);完成
左から 赤をチェック 赤と青をチェック 赤と青と黄色すべてをチェックした時です。
まとめ
基本的なことですが、コードが長くなるので自分で書いたコードにはメモをこまめに記載する。
関数を作って細かく分けてわかりやすくなるように心がけると見直した時に助かります。
今回の記事を書くために見直したときに改めて大切だと思いました。
- 投稿日:2019-04-13T18:01:01+09:00
我が家の防災サイネージを40分で作る方法(ライブカメラやサイトキャプチャをGoogleサイトに表示する)
はじめに
台風の日に、ライブカメラや気象情報などをすぐに確認できたり、大規模災害時に家族と情報共有したいと思い、クラウドサービスを利用したサイネージみたいな何かを作ってみました。
気象庁や行政機関が提供するライブ映像をもとに、Googleのサービスを利用させていただきました。
気象情報については、提供サイトの仕様上、画像のURLが日時等で毎回変わるので、自動で指定サイトをスクリーンショットによりクラウドストレージに保存することにしました。
GAS(GoogleAppsScript)で気象庁のサイトを定期的にキャプチャしてGoogleドライブに保存し、Google サイトに埋め込みました。また、ライブカメラ映像はスタイルシートで調整して埋め込んでみました。これでサーバーレスかつセキュアなクラウド型気象監視サイネージが完成しました。
クラウドなので、大規模災害時にもどこからでもアクセスできて利用できると思います。
サイネージとして利用したかったので、スクリーンショットについてはトリガーで15分ごとに自動更新し、同時にサイト側も自動更新できる仕組みをJavaScriptで実装してみました。
気象情報やTwitter情報をGoogleサイトを利用してサイネージを構築する図今回のゴール
※注 気象情報等を利用する際には、提供元の利用規約等を確認し、適切に運用してください。必要なもの
Googleアカウント
持っていない人は作成してください
https://support.google.com/accounts/answer/27441?hl=jaGoogleスプレッドシート作成
https://docs.google.com/spreadsheets/u/0/
シート作成
サイネージに埋め込む画像を、直リンクではなく、一旦Googleドライブにスクリーンショットして保存してから使用するため、まずはスクリーンショットを自動でドライブに保存する仕組みを作ります。そうすることで、画像リンクを直接埋め込まないので自動でリアルタイムの情報を反映することができ、さらに過去の画像を遡って確認することができるようになります。(Googleドライブの版管理により、過去の画像を確認できます)
スプレッドシート名は任意でOKです。
A1にキャプチャ名、B1に名称、C1にurlキャプチャサイト、D1にFILE_ID 上書きするファイル、E1にw キャプチャ幅、F1にh キャプチャ高さ、G1に画像URL(サイト埋め込み)を入力して表題部分を作成します。気象情報
気象庁のホームページから、キャプチャしたい気象情報のページを開いてURLをコピーしておく。
(参考)レーダー・ナウキャスト(降水・雷・竜巻):四国地方
https://www.jma.go.jp/jp/radnowc/index.html?areaCode=213&contentType=0データ入力
- A2にscreenshot01.png
- B2に気象庁 レーダー
- C2に先ほどコピーしたhttps://www.jma.go.jp/jp/radnowc/index.html?areaCode=213&contentType=0
- E2に590(キャプチャによって調整してください)
- F2に873(キャプチャによって調整してください)
を入力してデータを登録します。
シート名を管理に変更しておきます。GASでスクリーンショットをGoogleドライブに自動保存
GASって何?
簡単に言うと、Googleが開発した軽量アプリケーション開発用のスクリプト言語です。
Google Apps Script 入門GASを作成
すると、GASのスクリプトエディタが起動します。
次のソースコードを入力します。ソースコード
var spreadsheetId = '*****************'//←スプレッドシートのIDを入れる function screenshot() { var kanrisheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName('管理');//管理シート指定 var rowSheet=kanrisheet.getDataRange().getLastRow(); //管理シートの最終行を取得 //Range(各データの入ったセルを順に指定していく) for(var i=2;i<=rowSheet;i++){ try { var name = kanrisheet.getRange(i,1).getValue();//キャプチャ名を取得 var url = kanrisheet.getRange(i,3).getValue();//キャプチャするurlを取得 var FILE_ID = kanrisheet.getRange(i,4).getValue();//上書きするファイルIDを取得 var w = kanrisheet.getRange(i,5).getValue();//キャプチャ幅を取得 var h = kanrisheet.getRange(i,6).getValue();//キャプチャ高さを取得 var data = Charts.newDataTable()//urlデータを入れる .addColumn(Charts.ColumnType.STRING, 'dummy') .addRow(['<meta http-equiv="refresh" content="0; ' + url +'">']) .build(); //Class Chartsを利用 var chart = Charts.newTableChart() .setDataTable(data) .setOption('allowHtml', true) .setDimensions(w, h)// .build(); var file_type = { //ファイル設定 title: name, mimeType: 'image/png' }; var blob = chart.getAs('image/png').setName(name);; //スクショ画像をドライブに保存 if(!FILE_ID){ var idblob = DriveApp.createFile(blob).getId();//もし、FILE_IDが空白だったら新たにスクショファイル作成して、IDを取得 Browser.msgBox(idblob);//新たに追加したファイルのIDをポップアップ Logger.log(idblob);//デバック用 } else { var myVar = Drive.Files.update(file_type, FILE_ID, blob);//上書き保存 } } catch (e) { Logger.log(e); Logger.log(i); Logger.log(FILE_ID); //Logger.log(blob.getBytes()); } } }特定のサイトを定期的にスクショするためのコードです。
よくわかんないや!ってかたは、とにかくソースコードを貼り付けます。
貼り付ける時は最初入っているコードごと上書きしてください。
スクリプト エディタのリソースメニューから[Google の拡張サービス…] をクリックし、Drive API を有効化します。
Drive APIを有効にする
右のスクロールバーをスクロールし、Drive APIの右にあるスイッチをクリックしてONにし、OKをクリックします。
任意の名前を付ける
スプレッドシートのIDを指定する
続いて今回作成したスプレッドシートのIDをspreadsheetID = 'から後の***マーク部分に貼り付けます。
※スプレッドシートのIDって何よ!?って人は、一つ下を参考にしてください。
スプレッドシートのID確認方法
今、スクリプトエディタが開いている場合は、タブでスプレッドシートを開いてURLを確認してください。
GASを実行
ついに準備が整いました。
今、画面にスプレッドシートを開いている場合はスクリプトエディタを再度開いてください
エディタの上の方に三角の再生ボタンがありますよね。
いきなり実行してみてください
承認
すると、承認が必要です画面がポップアップされるので、許可を確認をクリックします。
このアプリは確認されていません
当然今作っているので確認されてたらおかしいのですが、とりあえず詳細を選択。
これで実行されたかと思います。
確認してみましょう。
ウェブブラウザのタブから、先ほど作成したスプレッドシートを選択すると、スクショしてGoogleドライブに保存されたファイルのIDがポップアップされていたら成功です。
D列のFILE_ID 上書きするファイルが空白であれば、新規にキャプチャファイルをドライブに保存し、ファイルIDをポップアップしますので、それをコピーして空白のD列に貼り付けます。
次回から、このファイルを上書きしていくための設定となります。
後2件分、気象庁のサイトから同様にキャプチャしたいページ情報を入力してみてください。ちなみに、私は
- 気象庁 アメダス https://www.jma.go.jp/jp/amedas/213.html?elementCode=0
- 気象庁 衛星 https://www.jma.go.jp/jp/gms/index.html?area=0&element=0
を追加してみました。キャプチャ名も任意です。
w キャプチャ幅、h キャプチャ幅って何よ?ってことですが、無理やりスクショして、後でサイネージに表示したいので、幅と高さを調整して、右端と下部をトリミングします。
めんどくさい作業ですが、ここ重要です。
そして、サイネージを作成する際に、右、下をスタイルシートで調整します。
個々の設定はもう少しおまちください。
↑サイネージ側での調整イメージ再びGoogleスプレッドシートにもどると、最初に登録したキャプチャ分は上書きされ、新たに登録したデータ分のキャプチャがGoogleドライブ内に保存されています。そして、ファイルIDがポップアップします。ここでは、1件ずつポップアップされるので、一旦メモ帳などに貼り付けておいて、FILE_ID 上書きするファイルにデータを登録してください。
GASの実行速度の関係で、タイムラグがあるかもです。
G2に
=ARRAYFORMULA("http://drive.google.com/uc?export=view&id="&D2:D)と入力します。
このARRAYFORMULA。数式を配列形式で表示します。Excelに無い概念でとても便利です。
つづいて、表を整理します。
少しでも不具合を回避するために、不要な部分を消します。5行目を選択して、最終行をShiftを押したまま選択すると5行目から1000行目(最終行)までを選択できます。
追加する場合は、必要分だけ追加するようにしましょう。
ファイルの設定
Googleドライブにアクセスします。
https://drive.google.com/drive/my-driveリンクを知っている全員が閲覧可能が選択されていれば、完了をクリックします。
全てのファイルに対して設定してください。
トリガー設定
続いて、キャプチャを自動で定期的に上書きしていくための設定をします。
スクリプトエディタに戻って編集、現在のプロジェクトのトリガーを選択。
トリガーって引き金っていうことだと思うんだけど、条件によってさっき作ったGASを実行しますよ!ってことができるんです。
トリガーの設定画面に移るので、右下のトリガーを追加を選択します。
時間の間隔を選択(分)で今回は15分おきを選択し保存します。
※気象情報の更新頻度などに合わせるといいかもですね。
スクリプトエディタに戻って保存ボタンを押して保存してスクリプトエディタを閉じます。
これで、スクリーンショットの設定は一旦完了です。
続いて、大規模災害発生時を想定した家族緊急時対応マニュアルと情報共有ファームを作成します。
後でサイネージに埋め込みます。緊急時マニュアル
Googleスライドを利用します。
https://docs.google.com/presentation/u/0/パワーポイントを使用したことがある方は直感的に使用できるとおもいます。
使い方はこちら
https://support.google.com/docs/answer/2763168?co=GENIE.Platform%3DDesktop&hl=ja複数ページ作成できるので、発災時の初動パターン、安否確認、大けが時等緊急連絡先などを作成しました。
安否確認フォーム作成
Googleフォームを利用します。
https://docs.google.com/forms/u/0/メールアドレスを収集するのチェックを外し保存をクリック
ここらは好みです。
フォームの名前を変更します。任意で結構です。
例では安否確認にしてみました。
フォームに登録するメニューを作成します。
まず名前のフィールドを作成します。
形式は記述式にします。
続いて家族の安否フィールドを作成します。
形式はラジオボタンで
- 無事
- けがあり
- 行方不明
などを設定しておきます。
続いて同じ要領で避難状況フィールド、自宅被害状況のフィールド、緊急連絡先、その他連絡事項などを作成します。
必要に応じてご自由に作成してください。
続いて、誰かがフォームに登録したときに設定したメールやグループメールに、登録内容を送信するGASを作成します。
点々をクリックし、スクリプトエディタをクリックします。
スクリプトエディタが開くので、名前を付けます。
例では安否確認にします。
ソースコード
function submitForm(e){ var itemResponses = e.response.getItemResponses(); var message = ''; for (var i = 0; i < itemResponses.length; i++) { var itemResponse = itemResponses[i]; var question = itemResponse.getItem().getTitle(); var answer = itemResponse.getResponse(); message += (i + 1).toString() + '. ' + question + ': ' + answer + '\n'; } var address = '*****************';//メールアドレス var title = '我が家の安否確認フォームが送信されました'; var content = '以下の内容でフォームが送信されました。\n\n' + message; GmailApp.sendEmail(address, title, content); }またまたよくわかんないや!ってかたは、とにかくソースコードを貼り付けます。
貼り付ける時はやっぱり最初入っているコードごと上書きしてください。
var address = '*****************';//メールアドレス
の***************部分に、フォーム入力後にお知らせメールを送りたいアドレスを入力しておきましょう。
例えば、家族のグループメールを作成して、そのアドレスを登録するなども有効です。GASを実行
ここもいきなり実行してみます。
三角ボタンをクリックします。
おっと!なにやらエラーっぽい!?
大丈夫です。フォームの送信ボタンを押したときにフォーム内容を格納するためのコードなので、読み取れなくて当然です。
メニューから編集をクリック、続いて現在のプロジェクトのトリガーをクリックします。
許可が完了すると、トリガーが追加できたのが確認できると思います。
URLをコピーして、メモ帳などに貼り付けておきましょう。
このURLを使ってフォーム投稿できるようになります。
QRコード作成サービスなどを利用して、家族に渡しておいてもいいかもしれませんね。
試しに、各情報を入力及び選択して、最後に送信ボタンを押してみましょう。
フォームの編集画面で、回答を選択すると、回答が見えます。また、緑色のスプレッドシートのアイコンをクリックすると、データがGoogleスプレッドシートに自動で収集されます。
サイネージ作成
Googleサイトというサービスを利用します。
https://sites.google.com/
右下にある+アイコンをクリックして作成します。
↑URLから作成できます。
ヘッダーを削除します。
左にカーソルを移動し、ヘッダーを削除アイコンをクリックします。
サイトの名前を任意につけます。
例ではうちの防災サイネージにしました。
ウェブからの埋め込みで埋め込みコードを選択し、次のコードをコピペします。
気象庁の台風情報の画像をもってきます。<style type="text/css">.im { width:100%; height:auto; } </style> <p><img alt="taihuu" class="im" src="https://www.jma.go.jp/jp/typh/img/no-typhoon.png" title="気象庁 台風" /></p>続いて、Googleの災害情報マップを埋め込みたいと思います。
次のURLをコピーします。
https://google.org/crisismap/japan?embedded=true&hl=ja&layers=4,6,10,11,21,22,23,24,25,29,30,1314427504921&llbox=55.72,15.27,-164.09,83.41&t=HYBRID続いて、サイネージで注意報等の情報を表示するために、RSSを埋め込みたいと思います。
まず、ライブドアの警報・注意報情報にアクセスします。
例は、徳島県の情報です。
http://weather.livedoor.com/warn/36RSS記事を作成するツールを利用して、そのコードをGoogleサイトに貼り付けたいと思います。
まず、RSSフィードを次のサービスに登録します。
https://tanganrss.com/rsstxt/regist.php特に特殊な設定はしなくても大丈夫です。
好みに合わせて設定してください。
貼付けコードが自動で作成されるので、これをコピーします。
<script type="text/javascript" src="https://tanganrss.com/rsstxt/rsstxt.php?key=d4c3c3f5de017d1ca4405267cbaffe7a"></script> <!-- 姉妹サービス、複眼RSSを宜しくお願いします。 http://fukugan.com/ --> <!-- 登録内容の復元URL https://tanganrss.com/rsstxt/regist.php?key=d4c3c3f5de017d1ca4405267cbaffe7a -->Googleサイトに戻って、先ほどと同様、埋め込むをクリックし、埋め込みコードを選択します。
貼り付けて保存し、挿入します。
デザインを整えます。
RSSを右上に持っていきたいと思いますので、選択します。
ドラッグドロップで移動できます。
ちなみに大きさの変更は、対象を選択すると対象の周りに色がついて、線上に点ができるので、それをドラッグドロップで調整できます。
サイネージ全体の色を変更します。
私の場合は、ディスプレイの消費電力量、眼球に対する負荷、の2点(実際の影響は微小または気分だけ)からダーク色を基本としています。
※ここら辺は好みに合わせて色々いじってみてくださいね。
まず、カーソルを左に持っていくと、セクションの背景という項目が出てきますので、そこをクリックします。
すると、右側に設置したRSSが見にくくなってしまいます。
こちらは、スタイルシートをで調整します。
対象を選択し、鉛筆マークをクリックします。
ウェブからの埋め込み内にあるコードを全て選択してコピーします。
ソースコードを編集するときは、テキストエディタかメモ帳が便利です。
例ではメモ帳に貼り付けてみます。
必要な部分は部分ですので、この部分を次のソースコード内に貼り付けます。
<!DOCTYPE html> <html lang="ja"> <head> <style type="text/css"> body,div,a { font-size: 90%; color:#A5A5A5; } </style> </head> <body> <div> <script type="text/javascript" src="https://tanganrss.com/rsstxt/rsstxt.php?key=d4c3c3f5de017d1ca4405267cbaffe7a"></script> </div> </body> </html>styleで囲まれた部分でスタイルシートの設定を調整します。
先ほどのscript部分を上書きします。
全体のデザイン調整時にフォントサイズ等微調整しましょう。cssの詳細ついては、参考書、またはGoogle先生に聞いてみてください。
いい感じになりました。
Googleの災害情報部分も同じように強調2(ダークカラー)に変更しておきましょう。
気象監視画面
Twitterニュースフィールドを追加します。
気象庁のTwitterを埋め込みたいと思います。
https://twitter.com/jma_kishouTwitterヘルプセンター ウェブサイトに埋め込みタイムラインを追加するにはを参考にしました。
https://publish.twitter.com/#
にアクセスします。
ここに、気象庁のTwitterニュースフィールドのURLをコピペして右のボタンをクリック。Google翻訳ですこし表現がおかしいですが、ソースコードをクリックするとコピーできます。
埋め込みコードを選択し、先ほどのソースコードを貼り付けます。
先ほど同様、次へ、保存します。
ライブ映像
家の近くの気象監視用のライブ映像を埋め込みます。
次のソースコードに近くのライブ映像のURLを入れて埋め込みます。
※各映像の視聴等については各管理団体へお問い合わせ下さい。<!DOCTYPE html> <html lang="ja"> <style> html { overflow:hidden; margin: -65px 0px 0px -45px;//上、右、下、左 } iframe { border: 1px solid black; width: 100%; //overflow:hidden; } .output { background: #eee; } </style> <body> <iframe id="inlineFrameExample" title="Inline Frame Example" width="900" height="600" src="ここに、ライブ映像のURL"> </iframe> </html>ここに、ライブ映像のURLに埋め込みたいライブ映像のURLを入力します。
スタイルシートのmarginで余分な部分をカットして調整します。
上と右あたりの数値をいじって調整してみてください。<style> html { overflow:hidden; margin: -65px 0px 0px -45px;//上、右、下、左 }次へを押すと、真っ白の場合があります。
ライブ映像提供元がssl化未対応のサイトはこのようになります。
ブラウザのアドレスバーに警告マークがでているので、ここをクリックします。
安全でないスクリプトを読み込むをクリックします。
※リスクを確認の上設定してください。
ライブ映像の大きさを変えたい場合
<!DOCTYPE html> <html lang="ja"> <style> body { overflow:hidden; margin: -25px 0px 0px -17px;//上、右、下、左 </style> <body> <div style="width:100%;-webkit-overflow-scrolling:touch;border:solid 1px;"> <iframe height="600" name="sample" src="ここに、ライブ映像のURL" style="transform:scale(0.35); -moz-transform:scale(0.35); -webkit-transform:scale(0.35); -o-transform:scale(0.35); -ms-transform:scale(0.35); transform-origin:0 0; -moz-transform-origin:0 0; -webkit-transform-origin:0 0; -o-transform-origin:0 0; -ms-transform-origin:0 0; border:solid 1px; width:230%; ">この部分はインラインフレームを使用しています。 </iframe> </div> </body>スタイルシートとiframe内で調整します。
cssの詳細ついては、参考書、またはGoogle先生に聞いてみてください。キャプチャ情報埋め込み
続いて、最初に設定した気象庁の気象情報を埋め込みます。
スプレッドシートの画像URL(サイト埋め込み)のURLデータを次のソースコード内のここに気象情報のURLを入力しますに上書きします。
<!DOCTYPE html> <html lang="ja"> <head> <style type="text/css"> /*スクロールバーを消す*/ body {overflow:hidden;} /*画像ファイルの左上調整*/ .img-box { margin: -22px 0px 0px -35px;//上、右、下、左 } /*画像ファイルの大きさ調整*/ .img-box img { width: 330px; height: 280px; object-fit: cover; } .right-bottom { object-position: 100% 100%; } </style> </head> <body> <div class="img-box"> <!-- ライブの画像をpngと認識させるために#dummy.pngを入れ、nameをscreenshotにする --> <img class="ここに気象情報のURLを入力します#dummy.png" name="screenshot"> </div> <script type="text/javascript"> kisho = new Image(); kisho.src = document.screenshot.src; screenshotTimer(); //*1 function screenshotTimer() { var now = new Date(); document.screenshot.src = kisho.src + "?" + now.getTime(); //*2; setTimeout("screenshotTimer()",60000); //*60秒ごとに更新 } </script> </body> </html>Googleドライブにある画像をトリミングします。
キャプチャ時点で右、下部分はトリミングしてありますよね。
埋め込みのスタイルシートで左、上を調整します。
スクロールバーを消したり、画像の大きさを調整したりしました。
好みに合わせて調整してみてください。
javascriptで定期的に更新するようにしました。
これは、GASのトリガーで定期的にドライブに画像を上書き保存しているので、上書き保存された画像をGoogleサイト側で更新するためです。
例では60秒ごとに更新するようにしております。
実際はGASのトリガー間隔でいいと思いますが、気象庁等の更新のタイミングにGASを合わせ、その後Googleサイトで更新なので、サイネージを開いた時間からカウントした場合、タイムラグが生じるため短めにしました。
すでにお気づきの方がいるかもしれませんが、最初に作成したホームに埋め込んだ気象庁の台風進路についても、この仕組みをいれると、定期的に自動更新できます。
試してみてください。注意が必要な部分は、Googleドライブの画像ファイルを利用する場合、
#dummy.png
が必要になることです。
グーグルドライブの仕様上、データサーバーとした使用方法を想定していないので、画像ファイルを共有で埋め込む場合にURLがIDになっているため、拡張子部分が存在しません。
そこを無理やりdummy.pngといったファイルですよ!ってことにしてます。場所や大きさを調整して、一画面に収まるように調整します。
やはりダーク色にしてみました。
また、一つの埋め込み画像の位置で、複数の画像を一定時間で入れ替えていきたい場合は次のソースコードで実装可能です。
ここらへんをどんどん組み込めばサイネージらしくなってきます。<!DOCTYPE html> <html lang="ja"> <head> <style type="text/css"> /*スクロールバーを消す*/ body {overflow:hidden;} /*画像ファイルの左上調整*/ .img-box { margin: -22px 0px 0px -35px;//上、右、下、左 } /*画像ファイルの大きさ調整*/ .img-box img { width: 500px; height: 415px; object-fit: cover; border: medium solid #ffffff; } .right-bottom { object-position: 100% 100%; border: medium solid #ffffff; } </style> </head> <body> <div class="img-box"> <img class="right-bottom" src="1つ目のURL#dummy.png" name="gazou"> </div> <script type="text/javascript"> img = new Array("1つ目のURL#dummy.png","2つ目のURL#dummy.png","3つ目のURL#dummy.png"); //*1 count = -1; //*2 imgTimer(); function imgTimer() { //画像番号 count++; //*3 //画像の枚数確認 if (count == img.length) count = 0; //*4 //画像出力 document.gazou.src = img[count]; //*5 //次のタイマー呼びだし setTimeout("imgTimer()",10000); //*6 } </script> </body> </html>緊急時用サイネージ
最後に、緊急時に家族と共有するページを作ります。
ページの+ボタンから追加します。
同じように次は挿入からスライドを選択します。
先ほど作成した緊急時マニュアルを挿入します。
その他パーツ
ブログパーツなどが使えます。
例えば、GPV 気象予報で、ブログパーツを作成できます。ここで作成したコードを埋め込むことで利用可能です。
リンク
最もシンプルなものに、リンクの作成があります。
埋め込みコードでhtmlで作成してもいいのですが、標準機能のテキストボックスから作成できます。
必要な情報にすぐにアクセスできるように設定しておくと便利です。
作成
サイトを閲覧できるユーザーを変更します。
我が家のサイネージなので、我が家のメンバー限定のサイトにしたいと思います。
管理をクリックします。
特定のユーザーのみが公開バージョンを閲覧できますのラジオボタンを選択し、保存します。
ここで、招待から家族のメールアドレス(Googleアカウント)を入れて招待して完了します。
最後にウェブアドレスを任意に定め、公開ボタンをクリックします。
画面下にサイトを公開しましたというメッセージがでるので、となりにある表示をクリックすると、完成したサイネージが表示されます。
デザイン仕上げ
デザインが崩れていたり、文字が大きくて入り切っていない場合などは、画像の大きさや配置を調整したり、埋め込みコードからスタイルシート等を修正してみてください。
お付き合いいただき、ありがとうございました。
参考
- 投稿日:2019-04-13T13:59:00+09:00
HTML要素のデータの保存方法
Abstract
HTMLドキュメントやJavaScript上で作成したHTML要素のデータ(各属性値など)をファイルやデータベースに保存する方法について覚書を記す。
方法
・WeakMapを使う
WeakMapとは、オブジェクト作成用のオブジェクトである。
普通のオブジェクトはkeyに文字列しか使えないのに対し、WeakMapで作ったオブジェクトにはオブジェクトをkeyに使える。あるHTML要素-例えばdiv要素-のデータを保存するにはkeyに以下のようなオブジェクトを作って指定すればよい:
まず、WeakMapでオブジェクトmyDivを作成する
→keyに「DOMのdiv要素オブジェクト」を設定する。
→
- 投稿日:2019-04-13T13:10:17+09:00
Rails勉強ネタ HTMLのformは本当にGETとPOSTに制限されているのか
webを支える技術を読んでいたら、p98に以下の記述がありました。
しかし、現実に一番よく利用されているのはGETとPOSTの2つです。 これはHTMLのフォームで指定できるメソッドがGETとPOSTだけという制限に起因します。これを読んで、「だとすると、updateアクションはどうやって実現されるのだろう??」
と思ったのですが、すぐ隣のページに書かれてました。
どうやらRailsは_methodパラメーターを使って実現させているみたいですね。実際に確認して見た
お知らせを投稿できるNoticeというModelがあるとします。
ルーティング
(当たり前ですが)updateアクションはPATCHメソッドかPUTメソッドで発動となっています。
$ rails routes|grep notice notices GET /notices(.:format) notices#index POST /notices(.:format) notices#create new_notice GET /notices/new(.:format) notices#new edit_notice GET /notices/:id/edit(.:format) notices#edit notice PATCH /notices/:id(.:format) notices#update PUT /notices/:id(.:format) notices#update DELETE /notices/:id(.:format) notices#destroyHTML
editページのformを
右クリック→ページのソースを表示で見てみます。<form class="edit_notice" id="edit_notice_18" action="/notices/18" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /> <input type="hidden" name="_method" value="patch" /><input type="hidden" name="authenticity_token" value="lGc0ypr/fV1WxhHZm6OS1ehZMpPj9IIgKF/8S5pm3FglyNHWxFgGLGt25AjoFb9BAINs4iRwg7VXn8eLjv9QGQ==" /> <label>お知らせ</label> <textarea name="notice[body]" id="notice_body">test</textarea> <input type="submit" name="commit" value="登録" data-disable-with="登録中…" /> </form>確かにformタグを見ると、 method="put" や method="patch"ではなく、
method="post"となっています。
そして、隠しパラメータ(hidden)に_methodパラメータを用意しているのが確認できます。↓
<input type="hidden" name="_method" value="patch" />Wiresharkでパケットキャプチャーして見た
リアルなhttpパケットが見たいのでキャプってみました。
wiresharkでインターフェイスをlocalhostに指定してあげると、localhost:3000とのパケット通信をキャプチャーできます。画像はeditページでsubmitした時のhttpパケットです。
確かに
POSTメソッドのHTTPリクエストが送信されていることが確認できます。また、
HTML Form URL Encoded: application/x-www-form-urlencoded内で
Form item: "_method" = "patch"というパラメーターが確認できる。
おそらくこのパラメーターを見て"patch"メソッドが送られたこととして処理しているんだと思われる(本当はPOSTメソッドを受け取っているが)。binding.pry
updateアクション内にbinding.pryを仕込んでデバッグ。
[1] pry(#<NoticesController>)> request => #<ActionDispatch::Request:0x00007fd6cb6156d0 @env= {"CONTENT_LENGTH"=>"210", "CONTENT_TYPE"=>"application/x-www-form-urlencoded", "GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/notices/15", "QUERY_STRING"=>"", "REMOTE_ADDR"=>"::1", "REMOTE_HOST"=>"::1", "REQUEST_METHOD"=>"PATCH", "REQUEST_URI"=>"http://localhost:3000/notices/15", "SCRIPT_NAME"=>"", "SERVER_NAME"=>"localhost", "SERVER_PORT"=>"3000",送信されるリアルなHTTPリクエストはPOSTメソッドですが、RailsはPATCHメソッドを受け取ったと認識しているようです。
("REQUEST_METHOD"=>"PATCH")疑問に思ったこと
今回の確認では_methodでpatchが当てがわれているが、putはどのような条件で出てくるのだろう??
(何かの条件でputのパターン、patchのパターンがあるのだろうか)
- 投稿日:2019-04-13T13:10:17+09:00
【Rails勉強ネタ】 HTMLのformは本当にGETとPOSTに制限されているのか
webを支える技術を読んでいたら、p98に以下の記述がありました。
しかし、現実に一番よく利用されているのはGETとPOSTの2つです。 これはHTMLのフォームで指定できるメソッドがGETとPOSTだけという制限に起因します。これを読んで、「だとすると、updateアクションはどうやって実現されるのだろう??」
と思ったのですが、すぐ隣のページに書かれてました。
どうやらRailsは_methodパラメーターを使って実現させているみたいですね。実際に確認してみる
お知らせを投稿できるNoticeというModelがあるとします。
ルーティング
(当たり前ですが)updateアクションはPATCHメソッドかPUTメソッドで発動となっています。
$ rails routes|grep notice notices GET /notices(.:format) notices#index POST /notices(.:format) notices#create new_notice GET /notices/new(.:format) notices#new edit_notice GET /notices/:id/edit(.:format) notices#edit notice PATCH /notices/:id(.:format) notices#update PUT /notices/:id(.:format) notices#update DELETE /notices/:id(.:format) notices#destroyHTML
editページのformを
右クリック→ページのソースを表示で見てみます。<form class="edit_notice" id="edit_notice_18" action="/notices/18" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /> <input type="hidden" name="_method" value="patch" /><input type="hidden" name="authenticity_token" value="lGc0ypr/fV1WxhHZm6OS1ehZMpPj9IIgKF/8S5pm3FglyNHWxFgGLGt25AjoFb9BAINs4iRwg7VXn8eLjv9QGQ==" /> <label>お知らせ</label> <textarea name="notice[body]" id="notice_body">test</textarea> <input type="submit" name="commit" value="登録" data-disable-with="登録中…" /> </form>確かにformタグを見ると、 method="put" や method="patch"ではなく、
method="post"となっています。
そして、隠しパラメータ(hidden)に_methodパラメータを用意しているのが確認できます。↓
<input type="hidden" name="_method" value="patch" />Wiresharkでパケットキャプチャーして見た
リアルなhttpパケットが見たいのでキャプってみました。
wiresharkでインターフェイスをlocalhostに指定してあげると、localhost:3000とのパケット通信をキャプチャーできます。画像はeditページでsubmitした時のhttpパケットです。
確かに
POSTメソッドのHTTPリクエストが送信されていることが確認できます。また、
HTML Form URL Encoded: application/x-www-form-urlencoded内で
Form item: "_method" = "patch"というパラメーターが確認できる。
おそらくこのパラメーターを見て"patch"メソッドが送られたこととして処理しているんだと思われる(本当はPOSTメソッドを受け取っているが)。binding.pry
updateアクション内にbinding.pryを仕込んでデバッグ。
[1] pry(#<NoticesController>)> request => #<ActionDispatch::Request:0x00007fd6cb6156d0 @env= {"CONTENT_LENGTH"=>"210", "CONTENT_TYPE"=>"application/x-www-form-urlencoded", "GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/notices/15", "QUERY_STRING"=>"", "REMOTE_ADDR"=>"::1", "REMOTE_HOST"=>"::1", "REQUEST_METHOD"=>"PATCH", "REQUEST_URI"=>"http://localhost:3000/notices/15", "SCRIPT_NAME"=>"", "SERVER_NAME"=>"localhost", "SERVER_PORT"=>"3000",送信されるリアルなHTTPリクエストはPOSTメソッドですが、RailsはPATCHメソッドを受け取ったと認識しているようです。
("REQUEST_METHOD"=>"PATCH")疑問に思ったこと
今回の確認では_methodでpatchが当てがわれているが、putはどのような条件で出てくるのだろう??
(何かの条件でputのパターン、patchのパターンがあるのだろうか)
- 投稿日:2019-04-13T12:57:22+09:00
プログラミング学習への心得
目次
- 【超重要】環境を整える
- まず、言語の概要を知ること
- とにかくコードを書くこと
- エラーを経験しまくること
- まずは一つの言語に集中すること
- 全てを覚えることは不可能
【超重要】環境を整える
何か目標を達成するには、一番大事なのが「やるしかない環境」を作ることです。
プログラミングを本気でやるなら、
Macbook AirかProを買う。プログラミングスクールに通う。
をおすすめします。金額は高額になりますが、これを道具や環境への投資と思い元を取る気持ちでやると非常に頑張れます。あのヒカキンさんも動画編集のパソコンには売れていないときからかなり投資していたそうです。
今は、とても安くで学習できたりするのですが、月数百円かけるよりも費用対効果はいいと思います。
ちなみに私は、筋トレがあまり好きではなかったのですが、パーソナルジムに高額な費用を投資したことで、スイッチが入り「食事」「運動」の改善ができて健康でとても毎日が楽しいです。
まず、言語の概要を知ること
一概にプログラミングと言っても、何ができるのかを知った上で学習を進めるというのは非常に大切なことです。
例えば、
サッカー選手になりたいのに「バットの素振りの練習」を始める人はいないですよね。
国内旅行に行きたいのに「パスポートを取る」人はいないですよね。WEBデザイナーになりたい → HTML CSS Javascript
WEBエンジニアになりたい → PHP Laravel か Ruby on Rails か Go
アップル系スマホアプリエンジニアになりたい → Swift
機械学習エンジニアになりたい → PythonHTML CSSは、どの言語の学習を始める上でも必要な知識になりますので、まずはここから始めるのが良いでしょう。
2019年4月現在では、このような言語になりますが流行り廃りがありますので、最新の情報を参考にしていきましょう。とにかくコードを書くこと
プログラミング学習は、スポーツやゲームと同じようにとにかくやること以外には、力はつきません。
スポーツの本やゲームの攻略本を読んだだけではうまくなりませんよね?
やりたいことが決まればとにかくその言語で、ポートフォリオを作ったりすることが上達への道となります。エラーを経験しまくる
まず、エラーはでて当たり前だと考えます。例えば、サッカーではシュートを打って100%決められる人はいないし、ロールプレイングゲームで一度も死なずに全てのゲームをクリアしてしまった人はいないと思います。
より多くのシュートが決まるように練習したり、ゲームでは同じステージでレベルをあげて強くなっていく、そんなイメージでやればエラーと出くわすのが楽しくなってきます。まずは一つの言語に集中する
言語はたくさんあります。ただ、なりたい方向を決めれば学習しなければいけない言語は絞られます。一つの言語とフレームワークで、ものづくりができるようになれば他の言語でも応用できるようになります。
私は、学習を始めた頃いろんな言語に手を出しまくったことがあります。その結果、、、一度やったことはほとんど忘れているなんてこともありますので、一つの言語と一つのフレームワークをまずは極めることが、重要です。
- 投稿日:2019-04-13T11:10:07+09:00
font-sizeとdivのwidthはそのままでは連動しないのでanimationするときに気をつける marquee版
まとめ
translateするのは要素なので、要素のレイアウト(ボックスモデル)が肝要。
font-sizeを大きくすると、親のwidthより文字が大きくなることがあり、見かけの文字長と親のwidthに食い違いが生じる。
その結果、想定していないアニメーション結果になることがあるので、
文字長とwidthは同一になるようにするといいかも。逆に文字より十分以上にwidthを確保していても想定以上の変化量になるので、余分にあればいいというわけでもない。
(font-sizeとdivからはみ出すことはゲンミツには直接の原因ではないですが、デフォルトのフォントサイズでははみ出るほど長く入力しないことと、私の遭遇ケースよりのタイトルです)
あらまし
あるところに改行したくないテキストがありました。
今は画面内に収まっていますがwhite-space: nowrap;をかけています。ただ、標準のフォントサイズだと小さいので大きくしようとしました。
<!DOCTYPE html> <html> <head> <style type="text/css"> html { overflow: hidden; } div { white-space: nowrap; } .big { font-size: 256px; } </style> </head> <body> <div> abcdefghijklmnopqrstuvwxyz </div> <div class="big"> abcdefghijklmnopqrstuvwxyz </div> </body> </html>あらあら、画面から飛び出して後半が見えません。
改行はしたくないですし、横スクロールも長大なので不恰好です。
ここは古のmarqueeタグで文字をスクロールして表示したいです。
しかし、marqueeはすでに廃止されているので、CSSのアニメーションで再現します。調べてみると、どうやら
transform: translate(0);
で初期状態。そこから
transform: translate(-100%);
で全体が消えるまで左方向に移動アニメーションすることで実現できそうです。<!DOCTYPE html> <html> <head> <style type="text/css"> html { overflow: hidden; } div { white-space: nowrap; } .big { font-size: 256px; } .anime { animation-duration: 5s; animation-iteration-count: infinite; animation-timing-function: linear; animation-name: marquee; } @keyframes marquee { 0% { transform: translate(0); } 100% { transform: translate(-100%); } } </style> </head> <body> <div> abcdefghijklmnopqrstuvwxyz </div> <div class="big"> abcdefghijklmnopqrstuvwxyz </div> <div class="big anime"> abcdefghijklmnopqrstuvwxyz </div> </body> </html>スクロールはしますが、mあたりでアニメーションが終了してしまいます。
末尾までアニメーションしません。開発者ツールで見た結果、アニメーションは
divのボックスモデルに働いているらしく、また文字がそのボックスよりはみ出ていることがわかりました。ボックスモデルの変化が-100%になってアニメーションが終了していることがわかります。
が、文字はまだまだwidth以上に続いているので途切れているようになります。解決方法
ここで
divをwidth: 100%にするのはおそらく解決方法になりません。100%になるのは親のサイズに対してですし、親も大きくしてもウィンドウサイズと同じぐらいでしょうか。軽く見た感じでは、手軽な解消方法は二通りありそうです。
display属性を変更する
display: inline-blockにするとwidthが調整されます。
inlineでは今度はanimationが効かなくなるので共存するならこちらで。
width属性を変更する
width: max-contentあるいはwidth: min-contentで、widthを内部で持つ要素の大きさに自動でフィットしてくれます。
これがfont-sizeの変更にも対応してくれました。
やや新しめの値で、CSS3としては草案段階のよう?ですがモダンブラウザならOK。
<!DOCTYPE html> <html> <head> <style type="text/css"> html { overflow: hidden; } div { white-space: nowrap; } .big { font-size: 256px; } .anime { animation-duration: 5s; animation-iteration-count: infinite; animation-timing-function: linear; animation-name: marquee; } @keyframes marquee { 0% { transform: translate(0); } 100% { transform: translate(-100%); } } .display { display: inline-block; } .content { width: max-content; } </style> </head> <body> <div class="big anime display"> abcdefghijklmnopqrstuvwxyz </div> <div class="big anime content"> abcdefghijklmnopqrstuvwxyz </div> </body> </html>ということで、大きい文字をmarqueeスクロールさせることができました。
font-sizeでblock要素からはみ出る原理を理解していないので鬼門かも。
- 投稿日:2019-04-13T05:58:26+09:00
#初心者のためのHTML+CSS入門(3)
こんにちは、こんばんは、かけるです。
今回は、初心者のためのHTML+CSS入門(2)の続きで
のコンテンツのほうを作っていきたいと思います。書くぜ
まず、右クリックで、検証モードというボタンを押してみてください、すると、このようにサイトがどのようなコードで構成されているか見ることができます。これから、勉強していく上でほかのサイトのこうした構造を見ることはとても勉強になるのでぜひ使ってみてください。
このスクショをみるとコンテンツとサイドバーのところが立て3つに区切られていることがわかります。
これは、cssのgridというプロパティによってこのように分けられているのですが、それは後程解説します。front.html<div class="contents"> <div class="side-bar-left"></div> <div class="main-contents"> </div> <div class="side-bar-right-u"> </div> <div class="side-bar-right-s"> </div> </div>front.css.contents{ display: grid; grid-template-columns: 80px calc(100% - 300px - 80px) 300px; grid-template-rows: minmax(270px,auto) 1fr; max-width: 1280px; width: calc(100% - 50px); margin-right: auto; margin-left: auto; padding:40px 0px 0px 0px; } .sidebar-left{ width: 80px; grid-column: 1 / 3; grid-row: 1 / 2; background-color: green; } .sidebar-right-s{ width: 300px; grid-column: 3 / 4; grid-row: 2 / 3; max-height: 100vh; background-color: red; height:200px; } .sidebar-right-u{ grid-column: 3 / 4; grid-row: 1 / 2; background-color: blue; } .main-contents{ grid-column: 2 / 3; grid-row: 1 / 3; padding: 16px; background-color: white; }
こんな感じです。わかりやすくするために色を付けました。
検証モード見ながらcssコードを持ってきて少しいじった感じなのですが、なかなかボリュームがありますね、少しずつ解説していきます。解説
クラスごとに解説していこうと思います。
contents
front.html<div class="contents"> <!--省略--> </div>front.css.contents{ display: grid; grid-template-columns: 80px calc(100% - 300px - 80px) 300px; grid-template-rows: minmax(270px,auto) 1fr; max-width: 1280px; width: calc(100% - 50px); margin-right: auto; margin-left: auto; padding:40px 0px 0px 0px; }
グリッドを使うときには通常グリッドコンテナーを作成します。
それを作成するには、要素に対して display: grid か display: inline-grid を指定します。
display: gridが指定されているdiv class="contents"で要素を囲うことでその直接の子要素がグリッド要素化し、つぎのCSSプロパティが使えるようになります。
- grid-template-columns:;
- grid-template-rows:;
columnsは縦列にどう分けるか、rowsは横列にどう分けるかを指定するもので、grid-template-columnsは、「80px」「calc(100% - 300px - 80px)」「300px」と3つ指定されており、これは縦に3つわけるという意味で、数字は3つに分けたときの横幅をしています。
grid-template-rowsは、「minmax(270px,auto)」「1fr」と2つ指定されており、これは横に2つ区切るといういみで、その値は縦幅を指定したものです。gridに関してはCSS Grid Layout を極める!(基礎編)がとても分かりやすいので参照ください。
margin-right:auto;とmargin-left:auto;で真ん中よせをしています。これが効くのは、block要素でテキストなどを真ん中にするときはtext-align:center;を使います。
paddingの意味は詰め物という意味で、topに40px見えない何かを詰めているというイメージで覚えてください。それに対してmarginは、余白という意味でもしtopに40pxとった場合その空いた40pxは何も要素がない状態になります。サイドバーとメインコンテンツ
front.html<div class="sidebar-left"></div> <div class="main-contents"> </div> <div class="sidebar-right-u"> </div> <div class="sidebar-right-s"> </div>front.css.sidebar-left{ width: 80px; grid-column: 1 / 3; grid-row: 1 / 2; background-color: green; } .sidebar-right-s{ width: 300px; grid-column: 3 / 4; grid-row: 2 / 3; max-height: 100vh; background-color: red; height:200px; } .sidebar-right-u{ grid-column: 3 / 4; grid-row: 1 / 2; background-color: blue; } .main-contents{ grid-column: 2 / 3; grid-row: 1 / 3; padding: 16px; background-color: white; }
どのクラスにもgrid-columnとgrid-rowというプロパティが指定されていますが、この二つによってグリッドコンテナーの区切られたエリアのどの場所に要素を配置するかを指定することができます。
例えば、sidebar-leftが左に位置しているのは、縦3つに区切ったときに左から、「1/3」「2/3」「3/3」となっておりそれをgrid-columnで「1/3」と指定しているからです。grid-rowも似た感じで横2つに区切ったときに上下二つに分かれるため、上から「1/2」「2/2」となっています。
max-heightやmax-widthがありますがこれは、見た通り縦幅や横幅の上限を設定することができます。その反対のmin-heightやmin-widthもしかりです。
100vhという値がありますが、viewport heightの略でウィンドウの縦幅に応じて表示する要素の縦幅を変えるもので100vhとするとウィンドウいっぱいにその要素が表示されます。1vh = 1%です。
widthで使うときは、「vw」を使います。まとめ
今回で大雑把なレイアウトができました。CSSの知識もたくさん得れたと思います。
でもまだまだ、沢山の僕も知らないCSSのプロパティーがあるので一緒に勉強していけたらなと思います。次回は、今回作ったレイアウトの中身を詰めていきたいと思います!
記事をご覧いただきありがとうございました。






























































































































































