Im just start learning three.js and try combine it with react.
Problem is:
texture has loaded (on debug I can check it on const texture = this.state.texture
string), but my rendered on canvas object is still black.
source code:
import './game.scss';
import MainBar from '../MainBar/MainBar.jsx';
import Slide from '@material-ui/core/Slide';
import AsideLinks from '../AsideLinks/AsideLinks.jsx';
import Footer from '../Footer/Footer.jsx';
import { withStyles } from '@material-ui/core/styles';
import * as THREE from 'three';
const onWindowResize = () => {
camera.aspect = container.clientWidth / container.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize( container.clientWidth, container.clientHeight );
}
const styles = theme => ({
page: theme.aside.page,
aside: theme.aside.aside,
body: {
...theme.aside.body,
minHeight: 'initial',
height: 'calc(100% - 81px)',
},
canvas: {
height: '100%',
width: '100%',
}
});
window.addEventListener( 'resize', onWindowResize );
let container, scene, camera, mesh, renderer;
const update = () => {
mesh.rotation.z += 0.01;
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
}
const render3 = () => {
renderer.render( scene, camera );
}
class Game extends React.Component {
constructor(props) {
super(props);
this.state = {
isAsideOpen: false,
mesh: mesh,
texture: null,
}
this.toggleAside = this.toggleAside.bind(this);
}
componentDidMount = () => {
this.setState({mesh: mesh});
this.getTexture().then(
t => this.setState({texture: t})
);
}
componentDidUpdate = () => {
if (this.state.texture !== null) {
this.init();
}
}
getTexture = () => {
return new Promise(async (s, r) => {
const textureLoader = new THREE.TextureLoader();
let t = await textureLoader.load( 'textures/uv_test_bw.png' );
s(t)
})
}
toggleAside = () => {
this.setState({isAsideOpen: !this.state.isAsideOpen});
}
init = () => {
container = document.querySelector( '#scene-container' );
scene = new THREE.Scene();
scene.background = new THREE.Color(0x333333);
const fov = 35;
const aspect = container.clientWidth / container.clientHeight;
const near = 0.1;
const far = 100;
camera = new THREE.PerspectiveCamera( fov, aspect, near, far );
camera.position.set( 4, 2, 20 );
camera.lookAt(new THREE.Vector3(0,0,0));
const geometry = new THREE.BoxBufferGeometry( 2, 2, 2 );
const texture = this.state.texture;
texture.encoding = THREE.sRGBEncoding;
texture.anisotropy = 16;
const material = new THREE.MeshStandardMaterial( {
map: texture,
} );
mesh = new THREE.Mesh( geometry, material );
const light = new THREE.DirectionalLight( 0xffffff, 5.0 );
light.position.set( 10, 10, 10 );
scene.add( light );
scene.add( mesh );
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize( container.clientWidth, container.clientHeight );
renderer.setPixelRatio( window.devicePixelRatio );
container.appendChild( renderer.domElement );
renderer.setAnimationLoop( ()=>{
update();
render3();
})
}
render = () => {
const {classes} = this.props;
return <div className={classes.page}>
<MainBar toggleAside={this.toggleAside}></MainBar>
<Slide className={classes.aside} direction="right" in={this.state.isAsideOpen} mountOnEnter unmountOnExit>
<AsideLinks/>
</Slide>
<div id="scene-container" className={classes.body}>
</div>
<Footer/>
</div>;
}
}
export default withStyles(styles)(Game);