Permalink
Browse files

react + three js boilerplate

  • Loading branch information...
asjad-anis committed Jan 16, 2019
1 parent 04b9143 commit fbbf80d09c20b4e2afa75d9bcef0af463cec22b3

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -5,7 +5,9 @@
"dependencies": {
"react": "^16.7.0",
"react-dom": "^16.7.0",
"react-scripts": "2.1.3"
"react-scripts": "2.1.3",
"three": "^0.100.0",
"three-orbitcontrols": "^2.99.1"
},
"scripts": {
"start": "react-scripts start",
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,25 +1,10 @@
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

import Scene from './Scene';
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<div>
<Scene />
</div>
);
}
@@ -0,0 +1,172 @@
import React, {Component} from 'react';
import * as THREE from 'three';
import OrbitControls from 'three-orbitcontrols';

class Scene extends Component{
constructor(props){
super(props);
this.state={
}
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
this.animate = this.animate.bind(this);
this.renderScene = this.renderScene.bind(this);
this.computeBoundingBox = this.computeBoundingBox.bind(this);
this.setupScene = this.setupScene.bind(this);
this.destroyContext = this.destroyContext.bind(this);
this.handleWindowResize = this.handleWindowResize.bind(this);
}

componentWillMount(){
window.addEventListener('resize', this.handleWindowResize)
}

componentDidMount(){
this.setupScene();
}

setupScene(){
this.width = this.container.clientWidth;
this.height = this.container.clientHeight;

const renderer = new THREE.WebGLRenderer({antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.shadowMap.enabled = true;
renderer.gammaOutput = true;
renderer.gammaFactor = 2.2
renderer.shadowMap.type = THREE.PCFSoftShadowMap;

let scene = new THREE.Scene();
scene.background = new THREE.Color('black');

let camera = new THREE.PerspectiveCamera(60, this.width/this.height, 0.25, 1000);
scene.add(camera);

let sphere = new THREE.SphereGeometry(50, 300, 300);
let material = new THREE.MeshPhongMaterial({
map: new THREE.TextureLoader().load('/Assets/2_no_clouds_4k.jpg'),
bumpMap: new THREE.TextureLoader().load('/Assets/elev_bump_4k.jpg'),
bumpScale: 0.005,
specularMap: THREE.ImageUtils.loadTexture('/Assets/water_4k.png'),
specular: new THREE.Color('grey'),
});
let mesh = new THREE.Mesh(sphere, material);
scene.add(mesh);
sphere = new THREE.SphereGeometry(50.1, 300, 300)
material = new THREE.MeshPhongMaterial({
map: new THREE.TextureLoader().load('/Assets/fair_clouds_4k.png'),
transparent: true
})
mesh = new THREE.Mesh(sphere, material);
scene.add(mesh)
this.renderer = renderer;
this.scene = scene;
this.camera = camera;
this.object = mesh;

let spotLight = new THREE.SpotLight(0xffffff, 0.25)
spotLight.position.set(45, 50, 15);
camera.add(spotLight);
this.spotLight = spotLight;

let ambLight = new THREE.AmbientLight(0x333333);
ambLight.position.set(5, 3, 5);
this.camera.add(ambLight);

this.computeBoundingBox();
}

computeBoundingBox(){
let offset = 1.60;
const boundingBox = new THREE.Box3();
boundingBox.setFromObject(this.object);
const center = boundingBox.getCenter();
const size = boundingBox.getSize();
const maxDim = Math.max( size.x, size.y, size.z );
const fov = this.camera.fov * ( Math.PI / 180 );
let cameraZ = maxDim / 2 / Math.tan( fov / 2 );
cameraZ *= offset;
this.camera.position.z = center.z + cameraZ;
const minZ = boundingBox.min.z;
const cameraToFarEdge = ( minZ < 0 ) ? -minZ + cameraZ : cameraZ - minZ;

this.camera.far = cameraToFarEdge * 3;
this.camera.lookAt(center);
this.camera.updateProjectionMatrix();

let controls = new OrbitControls( this.camera, this.renderer.domElement );
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = true;
controls.zoomSpeed = 0.1;
controls.enableKeys = false;
controls.screenSpacePanning = false;
controls.enableRotate = true;
controls.autoRotate = true;
controls.dampingFactor = 1;
controls.autoRotateSpeed = 1.2;
controls.enablePan = false;
controls.target.set(center.x, center.y, center.z);
controls.update();
this.controls = controls;
this.renderer.setSize(this.width, this.height);
this.container.appendChild(this.renderer.domElement);
this.start();
}

start(){
if (!this.frameId) {
this.frameId = requestAnimationFrame(this.animate)
}
}

renderScene(){
this.renderer.render(this.scene, this.camera)
}

animate() {
this.frameId = requestAnimationFrame(this.animate);
this.controls.update();
this.renderScene();
}

stop() {
cancelAnimationFrame(this.frameId);
}

handleWindowResize(){
let width = window.innerWidth;
let height = window.innerHeight;
this.camera.aspect = width/height;
this.camera.updateProjectionMatrix();
}

componentWillUnmount(){
this.stop();
this.destroyContext();
}

destroyContext(){
this.container.removeChild(this.renderer.domElement);
this.renderer.forceContextLoss();
this.renderer.context = null;
this.renderer.domElement = null;
this.renderer = null;
}


render(){
const width = '100%';
const height = '100%';
return(
<div
ref={(container) => {this.container = container}}
style={{width: width, height: height, position: 'absolute', overflow: 'hidden'}}
>
</div>
)
}

}

export default Scene;

0 comments on commit fbbf80d

Please sign in to comment.