LoginSignup
30
29

More than 5 years have passed since last update.

A-Frame+AR.jsでマーカー検出と同時にアニメーションを再生する方法

Last updated at Posted at 2018-11-21

概要

A-FrameとAR.jsによるWebARにおいて、マーカーの検出と同時にアニメーションを再生する必要があったため、その備忘録です。
AFRAME.registerComponentでマーカの検出/非検出をイベントとして登録し、そのイベントが呼ばれたタイミングでアニメーションを再生/停止します。
動画はワイヤーフレームのboxがHiroマーカーから5秒かけて上昇するアニメーションの繰り返しですが、マーカーを検出したタイミングでアニメーションが初期位置から再生されています。
animation_with_marker.gif

環境

A-Frame -> 0.8.0
AR.js -> 1.6.2

a-animation

回転や移動等の簡単なアニメーションは、A-frameのa-animationタグで実現できます。
下記の例では、ワイヤーフレームのboxがHiroマーカーから5秒かけて上昇するアニメーションが繰り返し再生されます。

box_up.html
<!doctype HTML>
<html>
<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
<script src="https://cdn.rawgit.com/jeromeetienne/AR.js/1.6.2/aframe/build/aframe-ar.js"> </script>

<body style="margin : 0px; overflow: hidden;">
    <a-scene embedded arjs>
        <a-marker preset="hiro">
            <a-box position="0 0.5 0" wireframe="true">
                <a-animation attribute="position" from="0 0.5 0" to="0 2.5 0" dur="5000" repeat="indefinite">
                </a-animation>
            </a-box>
        </a-marker>
        <a-entity camera></a-entity>
    </a-scene>
</body>

</html>

しかし、アニメーションはページの読み込みと同時に再生が開始されるため、boxが表示されていない状態でも位置は移動しています。
そのため、Hiroマーカーを検出したタイミングによって、最初にboxが表示される位置が異なってしまいます。
ループするアニメーションの場合はさほど問題にはなりませんが、アニメーションを最初から再生して表示したい場合などには適していません。

アニメーションを任意のタイミングで再生する方法として、a-animationbegin及びend属性があります。
下記に示す公式の例では、アニメーションを開始するイベントとして、begin属性に'fade'というイベント名を指定しています。
再生にはアニメーションが設定されている親要素(ここではid="fading-cube"を持つa-entity)を取得し、emit('fade')と指定されたイベントを発火することでアニメーションを開始することができます。

begin.html
<a-entity id="fading-cube" geometry="primitive: box" material="opacity: 1">
  <a-animation attribute="material.opacity" begin="fade" to="0"></a-animation>
</a-entity>
begin.js
document.querySelector('#fading-cube').emit('fade');

したがって、「マーカーを検出したタイミング」を取得してイベントを発火する事で、マーカーの検出と同時にアニメーションを再生する事ができます。

マーカーを検出してアニメーションを再生

マーカーの検出/非検出をイベントとしてトリガーする方法はAR.jsに用意されており、こちらに実装例があります。

これらを組み合わせて、マーカーの検出と同時にアニメーションを再生し、マーカーを見失うとアニメーションを停止する機能を実装しました。
マーカーを再検出した場合には、アニメーションは再度頭から再生されます。

marker_trigger_animation.html
<!doctype HTML>
<html>
<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
<script src="https://cdn.rawgit.com/jeromeetienne/AR.js/1.6.2/aframe/build/aframe-ar.js"> </script>
<script>
    AFRAME.registerComponent('registerevents', {
        init: function () {
            var marker = this.el;

            // マーカーを検出したイベントの登録
            marker.addEventListener('markerFound', function () {
                var markerId = marker.id;
                console.log('markerFound', markerId);

                // アニメーションの開始
                document.querySelector('#box').emit('markerfound');
            });

            // マーカーを見失ったイベントの登録
            marker.addEventListener('markerLost', function () {
                var markerId = marker.id;
                console.log('markerLost', markerId);

                // アニメーションの停止
                document.querySelector('#box').emit('markerlost');
            });
        }
    });
</script>

<body style="margin : 0px; overflow: hidden;">
    <a-scene embedded arjs>
        <a-marker preset="hiro" id="marker-hiro" registerevents>
            <a-box id="box" position="0 0.5 0" wireframe="true">
                <a-animation attribute="position" from="0 0.5 0" to="0 2.5 0" dur="5000" repeat="indefinite" begin="markerfound" end="markerlost">
                </a-animation>
            </a-box>
        </a-marker>
        <a-entity camera></a-entity>
    </a-scene>
</body>

</html>

こちらから実行する事ができます。

対象のマーカーのa-markerタグにregisterevents属性を追加する事で、マーカーの検出/非検出のタイミングをイベントとして登録する事ができます。
今回はマーカーを検出したイベントmarkerFoundをトリガーに、アニメーションを再生するイベント'markerFound'を、マーカーを見失ったイベントmarkerLostをトリガーに、アニメーションを停止するイベント'markerlost'を発火する事で、マーカーの検出/非検出に応じてアニメーションを再生/停止しています。

まとめ

AR.jsのマーカーの検出イベントと、a-animationbegin/end属性を組み合わせる事で、マーカーの検出/非検出をトリガーにアニメーションの再生/停止を制御する事ができました。
この他にも、マーカーを検出して音声を再生したり、javascriptの実行結果によって特定のアニメーションを再生するなどの応用ができると思います。

参考

https://github.com/jeromeetienne/AR.js/blob/master/aframe/examples/marker-events.html
https://aframe.io/docs/0.8.0/core/animations.html
https://jsfiddle.net/donmccurdy/tzm4q9n7/

30
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
29