react-three-rendererを使うことで、Three.jsのオブジェクトをJSXの中でコンポーネントとして記述することができます。
Example (w/redux)
scene
, camera
, mesh
などThree.jsのオブジェクトがcomponentとして提供されていて、通常のReactComponent同様にsetStateで描画が更新されます。アニメーション処理はonAnimate
内に記述します。
example.jsx
import React from 'react';
import React3 from 'react-three-renderer';
import { connect } from 'react-redux'
import * as THREE from 'three';
import { fetchTexture } from '../actions/texture';
const pi = Math.PI;
const rad = pi / 180;
const width = window.innerWidth;
const height = window.innerHeight;
class Example extends React.Component {
state = {
dirZ: -1,
dirRad: rad,
planePosition: new THREE.Vector3(0, 0, 500),
planeRotation: new THREE.Euler(0, 0, 0)
};
cameraPosition = new THREE.Vector3(0, 100, 500);
lightPosition = new THREE.Vector3(0, 100, 30);
componentDidMount() {
this.props.fetchPhotosWithTexture();
}
onAnimate() {
this.setState({
planePosition: new THREE.Vector3(
this.state.planePosition.x,
this.state.planePosition.y,
this.state.planePosition.z + this.state.dirZ
),
planeRotation: new THREE.Euler(
this.state.planeRotation.x + this.state.dirRad,
this.state.planeRotation.y,
this.state.planeRotation.z + this.state.dirRad
)
});
}
render() {
return (
<React3
mainCamera="camera"
width={width}
height={height}
clearColor={0x000000}
pixelRatio={window.devicePixelRatio}
onAnimate={this.onAnimate.bind(this)}
>
<scene>
<directionalLight position={this.lightPosition} />
<ambientLight color={0xaaaaaa} />
<perspectiveCamera
name="camera"
fov={45}
aspect={width / height}
near={1}
far={2000}
position={this.cameraPosition}
/>
<gridHelper size={200} step={50} />
<axisHelper size={1000} />
{this.props.texture ?
<mesh
position={this.state.planePosition}
rotation={this.state.planeRotation}
>
<planeGeometry
width={this.props.texture.image.width / 2}
height={this.props.texture.image.height / 2}
/>
<meshLambertMaterial
map={this.props.texture}
side={THREE.DoubleSide}
/>
</mesh>
: null}
</scene>
</React3>
);
}
}
export default connect(
state => ({ texture: state.texture }),
{ fetchTexture }
)(Example)
Debug
便利なことにReact Developer Toolsも通常のReact.jsと同じように使うことができます。
(さすがにprops, stateはReadOnlyになっていてこちらから動的に変えることはできないようですが)
所感
私はReact.js製のアプリケーション内にThree.jsのコンテンツを表示するために使いましたが、Three.jsのオブジェクトの構造をより明示的に記述できるのは良いですね。React.js, Three.jsどちらも触ったことがあればAPI Documentationを見ればすぐに書けるかと思います。