IT系おじさんのチラシの裏
2018年10月~
当サイトの記事にはアフィリエイト広告のリンクが含まれる場合があります

JavaScriptで画像を連続表示してコマ撮りムービー風の表示をしてみる

前回の記事「JavaScriptでスライドショーみたいな画像切替え(jQueryなし)」ではスライドショー的なモノを作りましたが、ふとこれを速度調整できるようにすればクレイアニメーションというか、コマ撮りムービーのようなものが出来るのではないか、と思ったので早速作ってみました。

用意した写真

以下のような13枚の写真を用意してみました。

コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像

特に枚数に意味はなく、なんとなくテーブルの端から端まで移動する感じにパシャパシャ撮っていたらこの枚数になっただけです。

HTMLの例

■HTML

<div class="anime">
<img src="[画像01]" />
<img src="[画像02]" />
<img src="[画像03]" />
<img src="[画像04]" />
<img src="[画像05]" />
<img src="[画像06]" />
<img src="[画像07]" />
<img src="[画像08]" />
<img src="[画像09]" />
<img src="[画像10]" />
<img src="[画像11]" />
<img src="[画像12]" />
<img src="[画像13]" />
</div>

<p>速度:<input type="range" id="anime_speed" value="500" min="100" max="500"></p>

解説

前回のようなスライドショーではないため、画像をクリックして拡大する必要もないだろうということで、Aタグすらも書かず、ひたすらimgタグを並べただけです。

ただ、JavaScriptで画像一覧を取得するときにクラス名を指定したいため、divタグにクラス名"anime"を付けて囲んでいます。

また、コマ撮りアニメの速度も調整できたほうが便利かなということで、inputタグのrangeも入れました。

CSSの例

<style>
.anime img {
	display:none;
	width:600px;
}
#anime_speed {
	transform: rotateY(180deg);
}
</style>

解説

divタグで囲んだ中にあるimgタグのサイズ指定と、非表示化をしています。

また、inputタグのtype=rangeはスライダー形式のボリュームバーみたいなものを表示するHTMLタグですが、左側が小さく、右側が大きいのが普通です。

今回の例ではmin=100 max=500という指定をしているため、そのままでは左端が100、右端が500となります。

しかし、この数値はsetTimeoutに渡すミリ秒であるため、実際には数値が小さいほどアニメーションが早く、大きいほど遅くなり、感覚的に違和感があります。

というわけで、transform:rotateY(180deg)というスタイル指定で、スライダーを180度回転させるというトリッキーなことをしています。

つまり、システム上は左が最小、右が最大、というのは変わらず、見た目だけが反転しているため、ユーザー側には左が最大(遅く)、右が最小(早く)なるわけです。

…うーん、ややこしいかな?w

こういうややこしいのが好みでない場合はCSS指定はやめて、JavaScript側で「500 - anime_speed.value」みたいな計算式を入れて逆になるようにするのも良いと思います。

JavaScriptの例

<script>
var frames = document.getElementsByClassName('anime')[0].getElementsByTagName('img');
viewFrame();

function viewFrame(frame_no = -1)
{
	if (frames[frame_no]) {
		frames[frame_no].style.display = 'none';
	}
	frame_no++;
	if (frames[frame_no]) {
		frames[frame_no].style.display = 'block';
	} else {
		frames[0].style.display = 'block';
		frame_no = 0;
	}
	var msec = document.getElementById('anime_speed').value;
	setTimeout(function(){viewFrame(frame_no);}, msec);
}
</script>

解説

前回はslidesだったのがimagesになっていたり、slide_noだったのがframe_noになっているだけで中身はほぼ変わりません。

動作的に違うとすればsetTimeoutに渡すミリ秒、つまり自分自身を再呼び出しする時間を anime_speed という要素から取得するようになった点ですかね。

デフォルトでは anime_speed には500が入っているため、500ミリ秒ごとに1つのフレーム(画像)が切り替えられます。

フレームを表示するたびにanime_speedを確認しているため、ユーザーが速度スライダーを操作するたびにアニメーションの速度が変わることを実感できるハズです。

実行結果

コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像 コマ撮り用の画像

速度:

やっていることは前回の「JavaScriptでスライドショーみたいな画像切替え(jQueryなし)」とほぼ変わらないのに、使う画像を変えて、速度調節用のスライダーを入れただけで、コマ撮りムービーっぽいです。

いまどきはスマホアプリやデジカメのタイムラプス機能でこんなコマ撮りムービーはすぐに作れるようですが、あえてWeb上で完結させるのもちょっと面白いかなと思いました。

関連記事

JavaScriptのcanvasで縦書きを行う際の備忘録

canvas上に縦書きの文章を出力して画像化しようと考えてちょっとハマったので忘れないうちにメモしておきます。 結論から先に書くと、基本的にcanvasにはwriting-modeの設定が効くの

JavaScriptのWebAudioAPIで楽曲の口パクをしてみる

以前、ソフトウェアの解説動画を作った際、おっさんの声だけ流れてるのもアレだし、最近流行りのアバターにしゃべらせるやつやってみよう、と思ったことがあります。 vtuberとかおじさんよくわからない

コメント

新しいコメントを投稿する

[新規投稿]
 
TOP