LoginSignup
7
9

More than 5 years have passed since last update.

VRのカメラ制御をReactとA-FRAMEで実装

Last updated at Posted at 2017-08-23

React VRでカメラを自分で制御しようとしたところ、出来なかったのでA-FRAMEを利用しました。
実装にはReactを利用したかったので、aframe-reactでA-FRAMEとReactを連携しています。

Reactの導入

create-react-appコマンドを利用しました。
「Facebook公式のcreate-react-appコマンドを使ってReact.jsアプリを爆速で作成する」が参考になりました。
http://qiita.com/chibicode/items/8533dd72f1ebaeb4b614

A-FRAMEとa-frame-reactの導入

  1. 「Reactの導入」で作られたAppのディレクトリに移動
  2. npm install --save aframe aframe-react を実行

実装

VRは「Appのディレクトリ/src/App.js」を編集して実装しました。
カメラのポジションや向き(rotation)を変更してぐりぐり画面が動きます。(3Dオブジェクトを2種類オマケで表示)
本当は360度画像内を自由に動きたかったのですが、360度画像はあくまで背景なので、仕様上無理なのがよく分かりましたw

App.js
import React, { Component } from 'react'
import logo from './logo.svg'
import './App.css'
import 'aframe'
import { Animation, Entity, Scene, } from 'aframe-react'

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      degree: 90,
      position: "0 10 30",
      rotation: "0 90 0",
      rotationY: 90,
    }

    this.rotate = this.rotate.bind(this)
  }

  componentDidMount() {
    this.rotate()
  }

  componentWillUnmount() {
    if (this.frameHandle) {
      cancelAnimationFrame(this.frameHandle)
      this.frameHandle = null
    }
  }

  rotate() {
    let newDegree = this.state.degree + 0.1
    if (newDegree >= 360) {
      newDegree -= 360
    }

    const afterX = 50 * Math.cos(newDegree * (Math.PI / 180));
    const afterZ = 50 * Math.sin(newDegree * (Math.PI / 180));

    let newRotationY = this.state.rotationY - 0.1
    if (newRotationY <= -360) {
      newRotationY += 360
    }

    this.setState({
      degree: newDegree,
      position: `${afterX} 0 ${afterZ}`,
      rotation: `${afterZ} ${newRotationY} ${afterX}`,
      rotationY: newRotationY,
    });
    this.frameHandle = requestAnimationFrame(this.rotate)
  }

  render() {
    return (
      <Scene>
        <Entity primitive='a-sky' src='[360度画像]'/>
        <Entity primitive='a-sphere' color="green" position="-2 10 -3"/>
        <Entity geometry={{primitive: 'box', width: 5}} position="0 0 -5"/>
        <Entity rotation={this.state.rotation}>
          <Entity primitive='a-camera' position={this.state.position}/>
        </Entity>
      </Scene>
    )
  }
}

export default App

公開用のファイル出力

「Reactの導入」で紹介したページに記載されていますが、とても簡単でした。
1. 「Reactの導入」で作られたAppのディレクトリに移動
2. npm run build を実行
3. buildディレクトリに出力される

その他参照

A-FrameとReact.jsでWebサイトのVR化を試みた話
https://developers.cyberagent.co.jp/blog/archives/6717/

A-FRAME
https://aframe.io

ngokevin/aframe-react
https://github.com/ngokevin/aframe-react

7
9
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
7
9