月別アーカイブ: 2016年2月

アルキメデスの螺旋(らせん)

動きのある表現

渦巻きネット社会の実現で様々なことに変革がありました。生き字引とあがめられた物知りが尊敬されなくなったり、百科事典の売れ行きが低下したりしました。

紙媒体が電子媒体に移行し、静が動に変わりつつあります。かつてはスポーツの試合で結果が分かれば十分でしたが、逆転勝ちで有終の美を飾った場合はひときわ興奮します。その辺の感情の機微を時間差表示で語りました。

東京マラソン2016コース案内でコースデータを作成してロードが完了するまでの間、動きのある表現を別枠で行うために探求した一端を語ります。

アルキメデスの螺旋(らせん)

アルキメデスの言葉

アルキメデスの螺旋(らせん)関数は蚊取り線香のような渦巻き曲線を描きます。極座標表現で式に表すとr=aθ(aは正の定数、0≦θ≦7.5π)になります。式は単純ですが途中経過を表示するにはJavaScriptではsetTimeoutを使います。

描き終わって、蚊取り線香が燃え尽きるように表現するには、setTimeoutで長い間隔に変更します。線香の先端を赤くしてに見立て、ゼロに向かって曲線を短くしていきます。

渦巻き曲線だけではさみしいので一次式とステップ関数の合わせて表示しています。

実行例

 

フェードイン・フェードアウト

本業はミュージシャンでした

高度成長期のお笑いグループにクレージーキャッツがおりました。晩年はお笑い芸人が楽器を弾いていると奇異に感じる若者もいたようです。テレビが白黒だったころはテレビ界の寵児(グループ)といわれたものです。

ガチョーンリーダーはハナ肇(ハナはじめ)でしたが、他のメンバーの名も一国一城の主として轟きました。 その一人に谷啓なるトロンボーンの名手がいて、ガチョーンというギャグが一世を風靡しました。テレビでは掛け声とともに画面がフェードイン・フェードアウトを繰り返しました。

このギャグは一般人がやっても面白くなく、当人ならではの芸でした。今回、この芸をテキスト表示に使ってみました。幸いにも大きくなったり小さくなったりを繰り返すのでフェードインとフェードアウトの両方をJavaScriptで実現する方法をマスターできます。

動作の仕組み

動作の仕組みはDIVタグのなかで指定したfont-sizeを一定時間間隔に変更します。定時間後に変更するきっかけはsetTimeoutを用いdocument関数でfont-sizeを置き換えます。

大小の繰り返しは1つの80ピクセル区間を45進んだら35後退し実質10ピクセル増大するように、剰余計算と整数化を駆使してジグザク拡大を計ります。

音声はテキストーク(textalk.exe)でテキストから音声に変換しました。本人の至芸には足元にも及びません。

TokyoMarathon

記事に採用済み

この手法を東京マラソン2016コース案内に織り込みました。

ソースコード

<html>
<head>
<script type="text/javascript" charset="Shift_JIS">
var x=20;
var w=243;
var s=0;
var shout = new Audio();			//AUDIOオブジェクト,早めにロードしておく
shout.src = "http://aidesign.lolipop.jp/wp-content/uploads/2016/02/AUDIO6.mp3";

function start(){
	if(s==0)	shout.play();
	document.all.post_title.style.fontSize=x+'px';
	var v = (s++) % 80;							// 0 or 1
	var u = 1 - Math.floor(v / 45) * 2;			// 1 or -1
	w += u;										// w:243 288 253 298 263 308
	x += u;										// x:20 65 30 75 40 85
	console.log("S=%d V=%d U=%d W=%d X=%d", s, v, u, w, x);
	document.gag.width = w;
	document.gag.height = 63 * w / 243;
	if(s<205)	setTimeout("start()", 30);
}
</script>
</head>
<body>
<input type="button" value="CLICK" onClick="start()"/> 音量は控えめに!
<BR><BR>
</body>
<div id="post_title" width: 780px; height: 400px; style="filter:Alpha(opacity=30);position:absolute;left:20;font-size:5px;color:tomato; border:1px solid blue;">
<img src="http://aidesign.lolipop.jp/wp-content/uploads/2016/02/gachon.png" width="243" height="63" name="gag">
<BR>東京マラソン2016
<Font Size="6" Color="blue"><BR>2016-02-28(日)<BR></Font>
</div>
</html>

実行例

 音量は控えめに!


東京マラソン2016
2016-02-28(日)




























非同期処理と同期処理

記述内容

このページは非同期処理と同期処理の概要とJavaScriptの新しい機能であるジェネレータyield(イールド)について記述しています。

非同期処理と同期処理の概要

複数の処理をするとき、動作の処理完了を待って次の処理に移行する同期処理と動作完了を待たずに次の処理を実行する非同期処理があります。

どちらが優れているというものではなく、場合に応じて使い分けることが肝要です。CやCOBOLなどにおいて同期処理が多く、JavaやJavaScript等ではイベントの発生により制御する処理が通例で、非同期タイプが一般的です。

同期処理

同期処理はAPIやFunctionと呼ばれる関数に処理を依頼すると動作が完了するまで制御が戻ってきません。処理を順に上から並べれば動作することが多いです。一方、非同期処理は動作が完了しないうちに制御が戻ってきます。

非同期処理

上の例では、①の処理を非同期に処理して2秒間の時間短縮を試みていますが、厳密には③において①の動作完了を確認する処理を追加しなければなりません。

大きなファイルを読み込むにはかなりの処理時間を要します。読み込み完了までの間に、読み込みデータに関わらない処理ならば、読み込みが終わるまで他の処理をすることができます。このことを並行処理といいます。

料理する

読み込みデータを参照する処理では、読み込み完了を待たなければなりません。このとき、システムが用意した適切な関数ならばWindowsなどのOSが待ち時間を有効利用します。

自前で作ったウエイト処理ではコンピュータ資源を無駄遣いし、次の処理を待つ間にキー入力や電子メール受信を受付けられない状態になることがあります。

そのため、同期処理はシステムが準備した適切なAPIを使うことが決め手になりますが、JavaScriptではまだ多くは準備されていません。以下にジェネレータによる待機処理例を掲げます。

ジェネレータとyield

画像描画は一定時間、表示しないと認識されません。画像を切り替えるには、setTimeoutなどの時間関数を使うことが多いです。今回はジェネレータ関数を用いて同期処理に近いことをしてみます。

15行のfunction*でジェネレータ関数を定義します。そして、処理をいったん停止する箇所にyieldを定義します。12行でジェネレータ関数のオブジェクトデータを取得し、ジェネレータを作成します。console.logのメッセージでも明らかなように、ジェネレータ関数は最後まで実行されず、非同期に制御は戻ってきます。

yield

一方、ジェネレータ関数ではyield n=0;を実行して待機状態になります。待機状態はnext()関数が実行されると解除します。imageDrwa(0)が画像描画関数であり、十分な描画時間が約束されます。

次に、ジェネレータを作成する前に設定したsleep()関数が1秒経過して起動し、next()関数が実行されると次のyield n=1;までが実行し待機状態になって、2番目の画像が描画されます。

同様に、1秒経過して3番目の画像が描画され、タイマーを停止させて動作状態を表示します。表示結果からも明らかなように、実行時間は各区間でおよそ1000msであり、一応、仕様どおり動作していることが判ります。

動作結果

Async1

ソースコード

<html>
<head>
<script type="text/javascript" charset="Shift_JIS">
var n=0;
var tm = [];

var first;
var timerID;
var g;

	timerID = setInterval("sleep()", 1000);
	g = genfunc(10);			// ジェネレータを作る
	console.log("Processed.");

function* genfunc(e){			// ジェネレータ関数
	console.log("G="+g+" timeID="+timerID);
	first = new Date().getTime();

	imageDraw(0);
	yield n=0;

	imageDraw(1);
	yield n=1;

	imageDraw(2);
	yield n=2;

	clearInterval(timerID);
	for(i=0; i<=n; ++i){
		console.log( "i="+i+" 実行時間="+tm[i]+"<BR>" );
		document.write( "i="+i+" 実行時間="+tm[i]+"<BR>" );
	}
	//javascript_die();					// FINISH
}

function sleep(){						// 1000ms
	g.next();							// "png 0~2"
}
function imageDraw(l) {			//画像表示
	var g="<img style='border: 1px solid red;' src='img/SightSeen"
          +l+".png'"+" width='600' height='250';/>";
	document.getElementById("expl").innerHTML = g;
	tm[l]=new Date().getTime() - first;	// 実行時間を計測
}
</script>
</head>
<div id="expl"></div>
</html>

参照資料

generatorとJavaScriptの非同期処理
ES6 Generatorを使ってasync/awaitを実装するメモ

最後に

JavaScriptにおける同期処理を試してみました。ここで示したコードは画像ファイル(SightSeen0.png~SightSeen2.png)をきちんと用意すれば、ブラウザChromeを使ってローカル環境でも動作しました。待機関数、同期処理は奥が深いです。

東京マラソン2016コース案内

今の段階では最終版ともいうべき動画で42.195kmのマラソンコースを案内する《東京マラソン2016コース案内》が完成しました。沿道のストリート風景をゆっくり眺める機能はまだ、織り込まれていませんが、下図のようにマーカーサイズを大きくした上、折返し点でマーカーの色を変えました。

吾妻橋からの復路はマーカーが寸分、違わず上書きされるので色を変えることにより、進行状況がわかり易くなりました。

StartGoal

ゆっくり楽しみながら閲覧するには、たぶん、FPSを設定しなおすことでできると思われますが、制御アプリケーションから呼び出されるライブラリの本丸に迫る必要がありそうです。

それは楽しみな宿題としておきましょう。それでは観やすく改良された動画による東京マラソンコース案内をどうぞご覧ください。(2016-02-23に改訂)

動画でやってみたいこと

人気動画は一世を風靡します。『百聞は一見にしかず』の諺(ことわざ)があるように、連続的な映像で、時には音声も織り交ぜながら人の五感に訴えます。

動画広告

ユーモラスな動画は閲覧数が百万回を超えるものもあり、これを利用して広告収入で生計を立てるクリエーターも存在するようです。

こちらでは別の視点を持っています。動画に物足りなく感じていることは、一度、投稿すると改訂ができないことです。字幕を追加することができるのでまったく編集不可というわけではありませんが、季節、天候、曜日によって描画内容を自動的に微妙に変えるという仕様は実現できていません。

公共の利器を用いて想いを寄せる相手にメッセージを届ける方法を考えましたが、難しいです。公共の利器が足かせになります。そこでパスワードのようなものを設ければよいのですが、これはYoutubeの限定公開機能で、限られた人にのみ閲覧用URLアドレスを知らせるということで実現できます。

動画で情報発信

やってみたいことは、動画の起動時にCTRL+ALT+DELのように特殊な操作をした場合のみ、「○○ちゃん、誕生日おめでとう!」というメッセージが表示される動画です。

JavaScriptなどで現在時刻を取得し、プレゼント人の誕生日に反応しつつ、パスワード代わりのキー入力を制御するプログラムコードを入れれば実現できますが、動画投稿では難しいのではないでしょうか。

現実的には運営しているブログにJavaScriptで記述した記事を公開して実現できます。ひょっとしてすでに利用されているのかも知れません。新しがりやの独り言でした。

東京マラソン2016コース全貌

概要

googlemapsGoogle maps JavaScript API v3の習得が徐々に進み、マラソンコースを一筆書きにたどることが可能になりました。2点間を検索するにあたり、無料のAPIを使っているため8箇所の中継点しか指定できず、42.195kmほどの長距離を探索するには大きな分岐点目印よりも少し先を設定しました。

グーグルストリートビューは必ずしも最短距離を選択するとは限りません。ストリート作成者は日本の皇室に敬意を払い、DitectionsRequest皇居前広場をことさらに一巡したがっています。

ルートの選択で他に選びようがない区間では長めに、込み入った箇所では小刻みに経由地点を設定して、実態のマラソンコースに近い42.195kmを指定することができました。8箇所の中継点はいかにも少なく、プレミアム有料版の23箇所ならば楽に精密なコースが得られることでしょう。

コマ落とし画像の作成処理に平行(並行)してマラソン、東京都の歴史、都内観光について語っています。甘茶の音楽工房のDark_Blade.mp3のバックグラウンドミュージックにて臨場感を盛り上げています。

StreetViewHyperlapseサーバーにアップロードしての動作はネットの込み具合やPCのパワーに依存し、遅延が起きることがあります。表示データの作成にはかなりの処理時間を要します。そのため、表示画面を分割して並行表示をしています。

改訂の変遷

東京マラソン2016記事は何度も改訂を加えました。大きな狙いは一度に42.195kmの探索をすることでした。その希望はこのたび、かなえられました。2016-02-12の加筆では折返し点でマーカーの色を変えたことと、吹き出しを表示したことです。

折返しの復路では、マーカーが重ね表示されると進行状況がわかりにくくなるが、色を変えることによって見にくさが少し解消されています。

実際のマラソンでは、プラカードやポスターにメッセージを書いて応援しますが、それに似た吹き出しを入れてみました。この機能を応用して、特別な思いを抱くアスリートに日ごろの気持ちを伝えることができます。

コース全貌

導入編はこれぐらいにして42.195kmを走りましょう。

東京マラソン2016コース動画

先般、ストリートビューハイパーラプスを用いて東京マラソン2016コースを一巡する動画を発表しました。今回は、文字を大きくしたり、BGMをつけて観光案内的な気分を織り込みました。

Google Maps JavaScript API v3も少しずつ理解が深まりつつあります。コマ落とし動画を作成しロードするための時間をかなり必要とします。42.195kmを3分割する処理は前回と変わりません。

ビデオキャプチャーを使わずに直接、ディスクへの書き込みが可能なように思われるが、まだ解明できません。動画をダウンロードしてかっこよく編集すれば要望に近づくでしょう。

ここでの動画作成の試みにおいて、思いがけない利用法が見つかることを願っています。

進化版東京マラソン2016

53EDO東京マラソン2016にて切れ切れに表示する動画をちょっと前に発表しました。Google Maps JavaScript API v3の使い方がマスターできてなく、他の方のサイトを利用させていただく方式でした。

APIのドキュメントの正式版は英語で公開されています。 サンプルコードも同梱されていて、その体験談(Hyperlapse で環状八号線を南下する動画を Google ストリートビューからつくってみた)を参考にしながら独自で連続方式ハイパーラプス動画を作成してみました。

体験談ではsimple.htmlを拡張されているようですが、今回はhyperlapse.js-master─examples─viewer.htmlを参考にしました。一回の関数呼び出しで、8箇所の経由rakuda地点を指定できることが判り、開始地点、終了地点を含めて総計10箇所でビューイング可能です。

切れ切れ動画では27箇所をつないでストリートビュー表示していましたので、42.195kmを3分割して表示しています。

ブラウザによっては動作ソフトが停止することがあり、原因はまだ、はっきりしていません。

そのため、問題なく動作した例を、デスクトップキャプチャーソフトによりダウンロードしたものをユーチューブに投稿しました。

動画には説明文もあり、全画面表示にすると見やすいです。

ルートデータを作成しロード中の待ち時間がかったるい感じを受けますが、将来の改良課題と考えています。ストリートビューでは、好まざる動きになっている部分がありますが誤差のうちとお許しください。

先の環八サイトの閲覧者もコメントで質問されていますが、ビューイングの繰り返しを止める制御コードに苦心しました。hyperlapse.onFrame位置情報の抽出関数で、hyperlapse.length()の一つ前で動作する処理コードを追加して解決に至っています。

音楽やキャプションなどを入れると魅力ある動画になると思われ、研究中です。