概要
この記事はVue.jsで作ったサイトに3Dをいれてみたいというところで手軽にWebVRを実装できるというA-Frameをさわってみました
できたもの
3Dさわってみました!表面がついてきてくれなくてホラー作品になってしまった・・・;;https://t.co/352AEXcKVe#protoout pic.twitter.com/HnRVh6VigU
— 3yaka (@3yaka4) June 3, 2020
色々足りず、ホラーなものができました。
2匹猫がいて、猫をクリクすると、猫が回ったり、雪が降ったりします。
猫はこちらからシャム猫3Dモデルとアメリカンショートヘアの3Dモデルをお借りしたのですが、なぜか表面がついてきませんでした。。。
環境
macOS Catalina
Visual Studio Code 1.45.1
Node.js: v13.11.0
npm:6.14.5
Vue:@vue/cli 4.3.1
大まかな流れ
- Vue.jsとFirebaseでログイン認証付きのページをつくる
- A-Frameをいれる
- 3Dモデルに動きをつける
- ドメインをとって公開
という流れです
1. Vue.js くみたてる
Vue.jsを勉強中のため、ちょっとむやみにセキュアなページにします。
こちらを参考に
Vue.jsでつくったサイトにfirebaseでユーザ認証してこっそり人の顔年齢を試して遊ぶ - Qiita
Firebaseでログイン処理をつくってVue.jsで3Pほどのページをつくります。
2. A-Frameをいれる
npmでいれたいのでaframe - npmこちらからインストールしていきましょう。
サンプルをベースに猫の3Dオブジェクトを2体配置します。
猫にたいしてクリックイベントをつけます。
A-Frameのパーティクルコンポーネントを使って雪をふらしましょう
Entity-Component-System – A-Frame
こちらもnpmでいれちゃいますaframe-particle-system-component - npm
3.3Dモデルに動きをつける
猫をクリックすると猫がグルングルン回るものと
猫をクリックしたら雪が降るというものをつくります
<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>
全体のコードはこちら
<template>
<div class="hello">
<div class="inf">
<h2>猫を探してください</h2>
<p>ここには猫が2匹います。<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
できなかったところ
最初のロード時にA-Frameのデフォルト?の水色とか出てきちゃうのをとめたかった。。。あれはなんだろう。
猫の表面が読み込めず、石膏像になってしまった。
Singin画面に画像を置いたのですがうまく反映されず。publicにおいたのに。。。
<img v-bind:src="img">
---略---
data: function () {
return {
img: '/public/img/nko3d.png'
}
}
参考サイト
AframeをVue.jsで使うよ! : 新人SEの気まぐれ日記
新しいWebVRフレームワークA-Frame入門 - Qiita
A-Frame v1.0 で クリスマスアニメーション - Qiita
感想
簡単に3Dが実装できた!でもちょっとやり込もうとするとやはり難しかった・・・。