more fixes

This commit is contained in:
btzr-io 2018-06-12 16:40:55 -06:00 committed by Sean Yesmunt
parent e1c1096458
commit 064e28a02e
6 changed files with 79 additions and 112 deletions

View file

@ -1,12 +1,10 @@
// @flow // @flow
import React from 'react'; import React from 'react';
import Spinner from 'component/spinner'; import Spinner from 'component/spinner';
import ProgressBar from 'component/common/progress-bar';
type Props = { type Props = {
status: string, status: string,
spinner: boolean, spinner: boolean,
progress?: number,
}; };
class LoadingScreen extends React.PureComponent<Props> { class LoadingScreen extends React.PureComponent<Props> {
@ -19,7 +17,6 @@ class LoadingScreen extends React.PureComponent<Props> {
return ( return (
<div className="content__loading"> <div className="content__loading">
{spinner && <Spinner light />} {spinner && <Spinner light />}
{progress && <ProgressBar progress={progress}/>}
{status && <span className="content__loading-text">{status}</span>} {status && <span className="content__loading-text">{status}</span>}
</div> </div>
); );

View file

@ -1,23 +0,0 @@
// @flow
import React from 'react';
type Props = {
progress: number,
};
class progressBar extends React.PureComponent<Props> {
static defaultProps = {
progress: 0,
};
render() {
const { progress } = this.props;
return (
<div className="progress-bar">
<div className="progress-bar__progress" style={{width: progress}}/>
</div>
);
}
}
export default LoadingScreen;

View file

@ -1,11 +1,12 @@
// @flow // @flow
import * as React from 'react'; import * as React from 'react';
import * as THREE from './internal/three.js';
import detectWebGL from './internal/detector.js';
import ThreeScene from './internal/scene.js';
import ThreeLoader from './internal/loader.js';
import ThreeRenderer from './internal/renderer.js';
import LoadingScreen from 'component/common/loading-screen'; import LoadingScreen from 'component/common/loading-screen';
// ThreeJS
import * as THREE from './internal/three';
import detectWebGL from './internal/detector';
import ThreeScene from './internal/scene';
import ThreeLoader from './internal/loader';
import ThreeRenderer from './internal/renderer';
type Props = { type Props = {
theme: string, theme: string,
@ -22,7 +23,7 @@ class ThreeViewer extends React.PureComponent<Props> {
const { theme } = this.props; const { theme } = this.props;
//Main container // Main container
this.viewer = React.createRef(); this.viewer = React.createRef();
// Object colors // Object colors
@ -60,6 +61,22 @@ class ThreeViewer extends React.PureComponent<Props> {
}; };
} }
componentDidMount() {
if (detectWebGL()) {
this.renderScene();
// Update render on resize window
window.addEventListener('resize', this.handleResize, false);
} else {
// No webgl support, handle Error...
// TODO: Use a better error message
this.state({ error: "Sorry, your computer doesn't support WebGL." });
}
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize, false);
}
createOrbitControls(camera, canvas) { createOrbitControls(camera, canvas) {
const { autoRotate } = this.props; const { autoRotate } = this.props;
const controls = new THREE.OrbitControls(camera, canvas); const controls = new THREE.OrbitControls(camera, canvas);
@ -85,11 +102,15 @@ class ThreeViewer extends React.PureComponent<Props> {
} }
createWireFrame(group) { createWireFrame(group) {
const wireframe = new THREE.WireframeGeometry(group.geometry); const wireframeGeometry = new THREE.WireframeGeometry(group.geometry);
this.wireframe = new THREE.LineSegments(wireframe); const wireframeMaterial = new THREE.LineBasicMaterial({
this.wireframe.material.depthTest = false; opacity: 0,
this.wireframe.material.opacity = 0; transparent: true,
this.wireframe.transparent = true; linewidth: 1,
});
// Set material color
wireframeMaterial.color.set(this.materialColors.green);
this.wireframe = new THREE.LineSegments(wireframeGeometry, wireframeMaterial);
group.add(this.wireframe); group.add(this.wireframe);
} }
@ -115,7 +136,7 @@ class ThreeViewer extends React.PureComponent<Props> {
this.scene.add(mesh); this.scene.add(mesh);
this.fitMeshToCamera(mesh); this.fitMeshToCamera(mesh);
this.createWireFrame(mesh); this.createWireFrame(mesh);
this.setControlsTarget(mesh.position); this.updateControlsTarget(mesh.position);
return mesh; return mesh;
} }
@ -125,8 +146,8 @@ class ThreeViewer extends React.PureComponent<Props> {
} }
fitMeshToCamera(group) { fitMeshToCamera(group) {
let max = { x: 0, y: 0, z: 0 }; const max = { x: 0, y: 0, z: 0 };
let min = { x: 0, y: 0, z: 0 }; const min = { x: 0, y: 0, z: 0 };
group.traverse(child => { group.traverse(child => {
if (child instanceof THREE.Mesh) { if (child instanceof THREE.Mesh) {
@ -144,29 +165,25 @@ class ThreeViewer extends React.PureComponent<Props> {
const meshY = Math.abs(max.y - min.y); const meshY = Math.abs(max.y - min.y);
const meshX = Math.abs(max.x - min.x); const meshX = Math.abs(max.x - min.x);
const meshZ = Math.abs(max.z - min.z); const scaleFactor = 15 / Math.max(meshX, meshY);
const scaleFactor = 10 / Math.max(meshX, meshY);
group.scale.set(scaleFactor, scaleFactor, scaleFactor); group.scale.set(scaleFactor, scaleFactor, scaleFactor);
group.position.y = meshY / 2 * scaleFactor; group.position.setY((meshY / 2) * scaleFactor);
group.position.multiplyScalar(-1); group.position.multiplyScalar(-1);
group.position.y += meshY * scaleFactor; group.position.setY(meshY * scaleFactor);
}
setControlsTarget(point) {
this.controls.target.fromArray([point.x, point.y, point.z]);
this.controls.update();
} }
startLoader() { startLoader() {
const { source } = this.props; const { source } = this.props;
source &&
if (source) {
ThreeLoader(source, this.renderModel.bind(this), { ThreeLoader(source, this.renderModel.bind(this), {
onStart: this.handleStart(this), onStart: this.handleStart(this),
onLoad: this.handleReady.bind(this), onLoad: this.handleReady.bind(this),
onError: this.handleError.bind(this), onError: this.handleError.bind(this),
onProgress: this.handleProgress.bind(this), onProgress: this.handleProgress.bind(this),
}); });
}
} }
handleStart() { handleStart() {
@ -186,13 +203,13 @@ class ThreeViewer extends React.PureComponent<Props> {
this.renderer.setSize(width, height); this.renderer.setSize(width, height);
}; };
handleError(url) { handleError() {
this.setState({ error: "Sorry, looks like we can't load this file" }); this.setState({ error: "Sorry, looks like we can't load this file" });
} }
handleProgress(url, currentItem, totalItems) { handleProgress() {
const progress = (currentItem / totalItems) * 100; // const progress = (currentItem / totalItems) * 100;
this.setState({progress}); // console.info(currentItem, totalItems, progress);
} }
handleColorChange(color) { handleColorChange(color) {
@ -202,6 +219,11 @@ class ThreeViewer extends React.PureComponent<Props> {
this.wireframe.material.color.set(pickColor); this.wireframe.material.color.set(pickColor);
} }
updateControlsTarget(point) {
this.controls.target.fromArray([point.x, point.y, point.z]);
this.controls.update();
}
renderModel(fileType, data) { renderModel(fileType, data) {
const geometry = this.createGeometry(data); const geometry = this.createGeometry(data);
this.mesh = this.createMesh(geometry); this.mesh = this.createMesh(geometry);
@ -243,33 +265,21 @@ class ThreeViewer extends React.PureComponent<Props> {
viewer.appendChild(canvas); viewer.appendChild(canvas);
} }
componentDidMount() {
if (detectWebGL()) {
this.renderScene();
// Update render on resize window
window.addEventListener('resize', this.handleResize, false);
} else {
// No webgl support, handle Error...
// TODO: Use a better error message
this.state({ error: 'No webgl support!' });
}
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize, false);
}
render() { render() {
const { error, progress, isReady, isLoading } = this.state; const { error, isReady, isLoading } = this.state;
const loadingMessage = 'Rendering model.'; const loadingMessage = 'Loading 3D model.';
const showViewer = isReady && !error; const showViewer = isReady && !error;
const showLoading = isLoading && !error; const showLoading = isLoading && !error;
return ( return (
<React.Fragment> <React.Fragment>
{error && <LoadingScreen status={error} spinner={false} />} {error && <LoadingScreen status={error} spinner={false} />}
{showLoading && <LoadingScreen status={loadingMessage} spinner={false} progress={progress} />} {showLoading && <LoadingScreen status={loadingMessage} spinner />}
<div style={{ opacity: isReady ? 1 : 0 }} className="three-viewer" ref={this.viewer} /> <div
style={{ opacity: showViewer ? 1 : 0 }}
className="three-viewer file-render__viewer"
ref={this.viewer}
/>
</React.Fragment> </React.Fragment>
); );
} }

View file

@ -1,10 +1,10 @@
import { LoadingManager, STLLoader, OBJLoader } from './three.js'; import { LoadingManager, STLLoader, OBJLoader } from './three';
const Manager = ({ onLoad, onStart, onProgress, onError }) => { const Manager = ({ onLoad, onStart, onProgress, onError }) => {
const manager = new THREE.LoadingManager(); const manager = new LoadingManager();
manager.onLoad = onLoad; manager.onLoad = onLoad;
manager.onStart = onStart; manager.onStart = onStart;
//manager.onProgress = onProgress; manager.onProgress = onProgress;
manager.onError = onError; manager.onError = onError;
return manager; return manager;
@ -19,17 +19,16 @@ const Loader = (fileType, manager) => {
}; };
const ThreeLoader = ({ fileType, filePath }, renderModel, managerEvents) => { const ThreeLoader = ({ fileType, filePath }, renderModel, managerEvents) => {
if (!fileType) return; if (fileType) {
const manager = Manager(managerEvents);
const loader = Loader(fileType, manager);
const manager = Manager(managerEvents); if (loader) {
const loader = Loader(fileType, manager); loader.load(filePath, data => {
renderModel(fileType, data);
// Unsuported loader });
if (!loader) return false; }
}
loader.load(filePath, data => {
renderModel(fileType, data);
});
}; };
export default ThreeLoader; export default ThreeLoader;

View file

@ -1,4 +1,4 @@
import * as THREE from './three.js'; import * as THREE from './three';
const addGrid = (scene, { gridColor, centerLineColor, size }) => { const addGrid = (scene, { gridColor, centerLineColor, size }) => {
const divisions = size / 2; const divisions = size / 2;
@ -31,25 +31,25 @@ const addLights = (scene, color, groundColor) => {
}; };
const Scene = ({ backgroundColor, groundColor, showFog, showGrid, gridColor, centerLineColor }) => { const Scene = ({ backgroundColor, groundColor, showFog, showGrid, gridColor, centerLineColor }) => {
// Convert colors // Convert color
backgroundColor = new THREE.Color(backgroundColor); const bgColor = new THREE.Color(backgroundColor);
groundColor = new THREE.Color(groundColor);
// New scene // New scene
const scene = new THREE.Scene(); const scene = new THREE.Scene();
// Background color // Background color
scene.background = backgroundColor; scene.background = bgColor;
// Fog effect // Fog effect
scene.fog = showFog === true ? new THREE.Fog(backgroundColor, 1, 95) : null; scene.fog = showFog === true ? new THREE.Fog(bgColor, 1, 95) : null;
// Add grid
showGrid && if (showGrid) {
addGrid(scene, { addGrid(scene, {
size: 100, size: 100,
gridColor, gridColor,
centerLineColor, centerLineColor,
}); });
}
// Add basic lights // Add basic lights
addLights(scene, '#FFFFFF', groundColor); addLights(scene, '#FFFFFF', groundColor);
// Return new three scene // Return new three scene
return scene; return scene;
}; };

View file

@ -1,16 +0,0 @@
.progress-bar {
width: 75%;
height: 5px;
display: block;
background: rgba(255, 255, 255, 0.25);
border-radius: 3px;
overflow: hidden;
}
.progress-bar__progress {
width: 20px;
height: 5px;
background: var(--color-primary);
border-radius: 3px;
transition: width 0.3s ease;
}