A-FrameでVR空間上にテキストを表示する

このエントリーは、[GMOアドマーケティング Advent Calendar 2018](https://qiita.com/advent-calendar/2018/gmo-am) の12/20 の記事です。
GMOアドマーケティングとしては初のAdvent Calendar参戦です。

### はじめに
HTMLライクなマークアップ言語でWebVRコンテンツが作成可能な[A-Frame](https://aframe.io/)。
私がはじめてA-Frameに触れたのは2016年で、当時の最新バージョンは`0.2.0`でした。
その頃は機能もかなり少なく、細かな制御をする場合はJavaScriptで強引に機能を追加する必要がありました。
今回アドベントカレンダーを執筆するにあたって久々にA-Frameのドキュメントを読んでみると、かなり多くの機能が追加されていたので、今回は追加された機能の一つである**テキストの表示**について紹介します。

### 動作環境
|    項目    |    内容    |
|:------------------:|:------------------:
|        A-Frame        |        Ver 0.8.2        |
|       ブラウザ       |        iOS 12.1 Safari        |

### VR空間の作成
テキスト表示の前にA-FrameでVRコンテンツを作成します。
ブラウザによって正常に表示されない場合もありますが、以下の「デモページ」にアクセスすることでVR空間を表示することが可能です。
スマホの場合は横画面にすることでジャイロセンサーと連動して立体的に表示することができるので、Google CardboardなどのVRゴーグルを通してアクセスするとかなりそれっぽく見えます。
※本記事はテキストの扱いの紹介なので、以下のコードの解説は割愛します。

[デモページ](https://thomi40.github.io/aframe/082/sample-082/)

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>A-Frame</title>
    <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
  </head>
  <body>
    <a-scene background="color: #EEEEEE">
      <a-sphere position="0 1.25 -5" radius="1.25" color="gray" shadow></a-sphere>
      <a-sphere position="0 1.25 5" radius="1.25" color="black" shadow></a-sphere>
      <a-sphere position="5 1.25 0" radius="1.25" color="olive" shadow></a-sphere>
      <a-sphere position="-5 1.25 0" radius="1.25" color="maroon" shadow></a-sphere>
      <a-plane position="0 0 0" rotation="-90 0 0" width="100" height="100" color="#333333"></a-plane>
    </a-scene>
  </body>
</html>
```

### テキストの表示
テキストの表示には`a-text`を使います。
※ `a-entity` を用いて記述することも可能です。
公式のドキュメントを見る限りでは、`a-text`はバージョン`0.5.0`で追加されたそうです。
では早速`a-text`を使ってVR空間上にテキストを表示してみます。

[デモページ](https://thomi40.github.io/aframe/082/sample-text/)

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>A-Frame</title>
    <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
  </head>
  <body>
    <a-scene background="color: #EEEEEE">
      <a-text position="-1 1.25 -3" value="Hello, World!" color="black"></a-text>
    </a-scene>
  </body>
</html>
```

A-Frameらしく、非常にシンプルに書くことができます。
A-Frameのタグには属性を設定することができますが、`a-text`も同様に様々な属性が用意されています。

|    属性    |    内容    |
|:------------------:|:------------------:|
|value|テキストの内容を指定<br>「`\n`」で改行することが可能||
|color|テキストの色を指定|
|font|フォントの指定|
|width|テキストの幅を指定|
|opacity|テキストの透明度を指定<br>0〜1の間で指定でき、1で完全な透明となる|
|align|left, center, rightなどで<br>テキストをどのように揃えるのかを指定|

他にも様々な属性が用意されているので、気になる方は[公式のドキュメント](https://aframe.io/docs/0.8.0/components/text.html)をご確認ください。

なお、カーソルを使ってテキストを操作したい場合は`geometry`でテキストに図形を追加することで制御できるようになります。
テキストのサイズに関しては`width`以外にも`position`, `scale`で調整することが可能です。
では早速、動作確認も兼ねて上記の属性を使って複数のテキストを表示してみます。

[デモページ](https://thomi40.github.io/aframe/082/sample-text-animation/)

デモページにアクセスすると中央にリングが表示されますが、これがVR空間上でのカーソルです。
今回はカーソルに関する説明はしませんが、`<a-entity camera look-controls wasd-controls>`〜`</a-entity>`の部分でカーソルの設定やアニメーションを指定しています。

画面正面の下に表示されている `Hello, World 006`に数秒間視点を合わせることでテキストの大きさが変わります。
上部の`Hello, World 005` もカーソルが動作しますが、クリック後のイベントを設定していないので何も変化はありません。


```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>A-Frame</title>
    <script src="https://aframe.io/releases/0.8.2/aframe.min.js"></script>
  </head>
  <body>

    <a-scene background="color: gray">

      <a-text position="-1 1.5 -3" value="Hello, World 001 opacity" color="black" width="5" opacity="0.3"></a-text>
      <a-text position="-1 1 -3" value="Hello, World 001 small" color="black" width="3"></a-text>
      <a-text position="-1 0.5 -3" value="Hello, World 001" color="black" width="5"></a-text>

      <a-text position="-4 1 -3" value="Hello, World 002 small" color="black" font="dejavu" scale="0.5 0.5 0.5" ></a-text>
      <a-text position="-4 0.5 -3" value="Hello, World 002" color="black" font="dejavu" ></a-text>
      
      <a-text position="3 1.6 -5" value="Hello, World 003 small" color="black" font="kelsonsans" ></a-text>
      <a-text position="2 0.5 -3" value="Hello, World 003" color="black" font="kelsonsans" ></a-text>

      <a-entity
        position="0 3.5 -4"
        geometry="primitive: plane; width: 5"
        material="color: #EF2D5E"
        text="color: white; align: center; font: dejavu;
              value: Hello, World 005\nHello, World 005;">
      </a-entity>

      <a-entity
        position="0 -1 -4"
        geometry="primitive: plane; width: 5"
        material="color: #EF2D5E"
        text="color: white; align: center; font: dejavu;
              value: Hello, World 006;">
        <a-animation begin="click" attribute="scale" dur="500" easing="ease-in-sine" to="2 2 2"></a-animation>
        <a-animation begin="mouseleave" attribute="scale" delay="500" to="1 1 1"></a-animation>
      </a-entity>

      <a-entity camera look-controls wasd-controls>
        <a-entity cursor="fuse: true;"
            position="0 0 -1"
            geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03"
            material="color: black; shader: flat">
            <a-animation begin="click" easing="ease-in" attribute="scale" dur="150"
               fill="forwards" from="0.1 0.1 0.1" to="1 1 1"></a-animation>
            <a-animation begin="cursor-fusing" easing="ease-in" attribute="scale" dur="1500"
               fill="backwards" from="1 1 1" to="0.1 0.1 0.1"></a-animation>
        </a-entity>
      </a-entity>
  </a-scene>
  </body>
</html>
```

### さいごに
今回はA-Frameを使ったVR空間上でのテキスト表示について紹介しました。
昔は画像を使って強引にテキストを表示していたので、今回紹介した`a-text`を使えば開発の可能性も広がりそうですね。
Ver0.8系では他にも様々な機能が追加されているので、引き続きドキュメントを片手にいろいろと試してみます。

### 告知
明日は@zakisanbaimanさんの LINE bot構築について のお話です。
お楽しみに！

クリスマスまで続くGMOアドマーケティング Advent Calendar 2018
ぜひ今後も投稿をウォッチしてください！

■エンジニアによるテックブログ公開中！
https://techblog.gmo-ap.jp/
■Wantedlyページ　～ブログや求人を公開中！～
https://www.wantedly.com/projects/199431
■エンジニア採用ページ　～福利厚生や各種制度のご案内はこちら～
https://www.gmo-ap.jp/engineer/
■エンジニア学生インターン募集中！　～有償型インターンで開発現場を体験しよう～
https://hrmos.co/pages/gmo-ap/jobs/0000027

### 参考リンク
https://aframe.io/