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上で完結させるのもちょっと面白いかなと思いました。