A-FrameをつかってWebVRをためしてみた!

#### 概要
この記事はVue.jsで作ったサイトに3Dをいれてみたいというところで手軽にWebVRを実装できるというA-Frameをさわってみました
#### できたもの
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">3Dさわってみました！表面がついてきてくれなくてホラー作品になってしまった・・・；；<a href="https://t.co/352AEXcKVe">https://t.co/352AEXcKVe</a><a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://t.co/HnRVh6VigU">pic.twitter.com/HnRVh6VigU</a></p>&mdash; 3yaka (@3yaka4) <a href="https://twitter.com/3yaka4/status/1268136089866268672?ref_src=twsrc%5Etfw">June 3, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

https://nekosagashi.tk/

色々足りず、ホラーなものができました。
２匹猫がいて、猫をクリクすると、猫が回ったり、雪が降ったりします。
猫は[こちら](https://creazilla.com/ja/nodes/3145-3d-model)からシャム猫3Dモデルとアメリカンショートヘアの3Dモデルをお借りしたのですが、なぜか表面がついてきませんでした。。。
 <img width="38%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282291/44853460-0acf-02fd-3643-e63e6d6ae1f8.png"> <img width="48%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282291/471eb196-7fde-649a-7dec-212e3b0124d8.png">


#### 環境
```
macOS Catalina 
Visual Studio Code 1.45.1
Node.js: v13.11.0
npm:6.14.5
Vue:@vue/cli 4.3.1
```

#### 大まかな流れ
 1. Vue.jsとFirebaseでログイン認証付きのページをつくる
 - A-Frameをいれる
 - 3Dモデルに動きをつける
 - ドメインをとって公開
 
という流れです

#### 1. Vue.js くみたてる

Vue.jsを勉強中のため、ちょっとむやみにセキュアなページにします。
こちらを参考に
[Vue\.jsでつくったサイトにfirebaseでユーザ認証してこっそり人の顔年齢を試して遊ぶ \- Qiita](https://qiita.com/3yaka4/items/1e10b62f778422e4d85f#vuejs%E3%81%A8firebase%E3%81%A7%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E8%AA%8D%E8%A8%BC%E3%81%82%E3%82%8A%E3%81%AE%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E3%81%A4%E3%81%8F%E3%82%8B)
Firebaseでログイン処理をつくってVue.jsで３Pほどのページをつくります。


#### 2. A-Frameをいれる
[A\-Frame – Make WebVR](https://aframe.io/)
![スクリーンショット 2020-06-03 14.48.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282291/7f3b2d35-268b-484e-ec76-64a0c971af13.png)

npmでいれたいので[aframe \- npm](https://www.npmjs.com/package/aframe)こちらからインストールしていきましょう。
サンプルをベースに猫の３Dオブジェクトを２体配置します。
猫にたいしてクリックイベントをつけます。
A-Frameのパーティクルコンポーネントを使って雪をふらしましょう
[Entity\-Component\-System – A\-Frame](https://aframe.io/docs/1.0.0/introduction/entity-component-system.html#including-the-component-js-file)
こちらもnpmでいれちゃいます[aframe\-particle\-system\-component \- npm](https://www.npmjs.com/package/aframe-particle-system-component)

#### 3.3Dモデルに動きをつける
猫をクリックすると猫がグルングルン回るものと
猫をクリックしたら雪が降るというものをつくります

```vuejs

<template>
<a-text font="kelsonsans" value="Click Me!" width="6" position="1.5 1 -1.5" rotation="0 0 0"></a-text>
        <a-assets>
          <img id="sample_img" src="/static/cat.png" />
          <a-asset-item id="sample_obj" src="/static/cat-print.obj"></a-asset-item>
          <a-asset-item id="sample_mtl" src="/static/cat-print.mtl"></a-asset-item>
        </a-assets>
        <a-obj-model scale="0.3 0.3 0.3" position="2.5 0 -1.5" src="#sample_obj" mtl="#sample_mtl" animation__star_rotation="property: rotation; startEvents:click; from: 0 0 0; to: 0 360 0; loop:5;"></a-obj-model>

        <a-entity id="snow" visible="false">
        <a-entity particle-system="preset:snow;" position="0 0 -4"></a-entity>
      </a-entity>

        <a-assets>
          <img id="neko_img" src="static/CatTexture.png" />
          <a-asset-item id="neko_obj" src="/static/neko.obj"></a-asset-item>
          <a-asset-item id="neko_stl" src="/static/neko.stl"></a-asset-item>
        </a-assets>
        <a-obj-model scale="0.2 0.2 0.2" position="-4.5 -1 -1.5" src="#neko_obj" mtl="#neko_stl" @click="handlerMouseEnter"></a-obj-model>
</template>
<script>
import firebase from 'firebase'
import 'aframe'

export default {
  name: 'Vue3d',
  el: '#aframeApp',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App',
      name: firebase.auth().currentUser.email,
      skyboxSrc: 'https://images.unsplash.com/photo-1505252772853-08ed4d526ceb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1600&q=80'
    }
  },
  methods: {
    handlerClick: function (event) {
      let boxid = event.target.id
      if (boxid === 'areabox2') {
        this.skyboxSrc = 'https://images.unsplash.com/photo-1557971370-e7298ee473fb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1600&q=80'
      }
    },
    handlerMouseEnter: function (event) {
      document.getElementById('snow').setAttribute('visible', 'true')
    }
  }
}
</script>
```
全体のコードはこちら

```vuejs
<template>
  <div class="hello">
    <div class="inf">
      <h2>猫を探してください</h2>
      <p>ここには猫が２匹います。<br>真ん中にある<span class="maru">◯</span>を動かして、猫を探してクリックしてあげてください
      </p>
    </div>
      <a-scene>
        <a-entity id="aframeApps">
          <!-- 背景設定 -->
          <a-sky ref="skybox" v-bind:src="skyboxSrc" rotation="0 -130 0"></a-sky>
          <a-box id="areabox2" position="2.5 0 1.5" rotation="45 45 45" @click="handlerClick"></a-box>
        </a-entity>
        <!-- ぐるぐる回る猫 -->
        <a-text font="kelsonsans" value="Click Me!" width="6" position="1.5 1 -1.5" rotation="0 0 0"></a-text>
        <a-assets>
          <img id="sample_img" src="/static/cat.png" />
          <a-asset-item id="sample_obj" src="/static/cat-print.obj"></a-asset-item>
          <a-asset-item id="sample_mtl" src="/static/cat-print.mtl"></a-asset-item>
        </a-assets>
        <a-obj-model scale="0.3 0.3 0.3" position="2.5 0 -1.5" src="#sample_obj" mtl="#sample_mtl" animation__star_rotation="property: rotation; startEvents:click; from: 0 0 0; to: 0 360 0; loop:5;"></a-obj-model>
        <!-- 雪を最初非表示 -->
        <a-entity id="snow" visible="false">
          <a-entity particle-system="preset:snow;" position="0 0 -4"></a-entity>
        </a-entity>
        <!-- 雪を降らす猫 -->
        <a-assets>
          <img id="neko_img" src="static/CatTexture.png" />
          <a-asset-item id="neko_obj" src="/static/neko.obj"></a-asset-item>
          <a-asset-item id="neko_stl" src="/static/neko.stl"></a-asset-item>
        </a-assets>
        <a-obj-model scale="0.2 0.2 0.2" position="-4.5 -1 -1.5" src="#neko_obj" mtl="#neko_stl" @click="handlerMouseEnter"></a-obj-model>

        <a-entity>
          <a-camera>
            <a-cursor></a-cursor>
          </a-camera>
        </a-entity>
      </a-scene>

</div>
</template>

<script>
import firebase from 'firebase'
import 'aframe'

export default {
  name: 'Vue3d',
  el: '#aframeApp',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App',
      name: firebase.auth().currentUser.email,
      skyboxSrc: 'https://images.unsplash.com/photo-1505252772853-08ed4d526ceb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1600&q=80'
    }
  },
  methods: {
    handlerClick: function (event) {
      console.log('handlerClick')
      console.log(event.target.id)
      let boxid = event.target.id
      if (boxid === 'areabox2') {
        this.skyboxSrc = 'https://images.unsplash.com/photo-1557971370-e7298ee473fb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1600&q=80'
      }
    },
    handlerMouseEnter: function (event) {
      console.log('handlerMouseEnter')
      console.log(event)
      document.getElementById('snow').setAttribute('visible', 'true')
    }
  }
}
</script>
<style scoped>
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
.inf{
    position: absolute;
    left: calc(50% - 16rem);
    top: 20%;
    z-index: 99999;
    color: #fff;
    font-size: 1rem;
    padding: 0.5rem;
    background: hsla(0,0%,100%,.18);
    width: 32rem;
}
.maru{
  font-size:80%;
  color:#000;
  font-weight:bold;
}
</style>

```
#### ドメインを取るNetlifyにDeploy
こちらを参考にfreenomでドメインをとってNetlifyにDeployします
[Vue\.jsでつくったサイトにfirebaseでユーザ認証してこっそり人の顔年齢を試して遊ぶ \- Qiita](https://qiita.com/3yaka4/items/1e10b62f778422e4d85f#freenom%E3%81%A7%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%92%E5%8F%96%E3%82%8B)


#### できなかったところ
最初のロード時にA-Frameのデフォルト？の水色とか出てきちゃうのをとめたかった。。。あれはなんだろう。
猫の表面が読み込めず、石膏像になってしまった。
Singin画面に画像を置いたのですがうまく反映されず。publicにおいたのに。。。

```vuejs

<img v-bind:src="img">
 ---略---
data: function () {
    return {
      img: '/public/img/nko3d.png'
    }
  }
```
### 参考サイト
[AframeをVue\.jsで使うよ！ : 新人SEの気まぐれ日記](http://tesao.work/archives/39887055.html)
[新しいWebVRフレームワークA\-Frame入門 \- Qiita](https://qiita.com/rootx/items/cba61f1f725bd0090307)
[A\-Frame v1\.0 で クリスマスアニメーション \- Qiita](https://qiita.com/qvtec/items/556ce01b5fb3e55595d6)

### 感想
簡単に3Dが実装できた！でもちょっとやり込もうとするとやはり難しかった・・・。