Skip to content

Commit

Permalink
Merge pull request #8 from Perkovec/file-manager
Browse files Browse the repository at this point in the history
Added loading screen and file manager
  • Loading branch information
Perkovec authored Feb 2, 2020
2 parents 05a4c1c + 84cf194 commit cfc65c1
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 40 deletions.
11 changes: 7 additions & 4 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export class App {
constructor(THREE, plugins) {
this.THREE = THREE;
this.objects = [];
this.sceneObjects = [];
this.isShiftDown = false;
this.editorContainer = document.getElementById('editor');

Expand Down Expand Up @@ -44,6 +45,8 @@ export class App {
renderer: this.renderer,
camera: this.camera,
render: this.render.bind(this),
scene: this.scene,
sceneObjects: this.sceneObjects,
}

plugins.forEach(Plugin => {
Expand Down Expand Up @@ -100,7 +103,7 @@ export class App {
);
this.raycaster.setFromCamera(this.mouse, this.camera);

const intersects = this.raycaster.intersectObjects(this.objects);
const intersects = this.raycaster.intersectObjects([...this.objects, ...this.sceneObjects]);
if (intersects.length > 0) {
const intersect = intersects[0];
this.rollOverMesh.position.copy(intersect.point).add(intersect.face.normal);
Expand All @@ -120,15 +123,15 @@ export class App {
);
this.raycaster.setFromCamera(this.mouse, this.camera);

const intersects = this.raycaster.intersectObjects(this.objects);
const intersects = this.raycaster.intersectObjects([...this.objects, ...this.sceneObjects]);
if (intersects.length > 0) {
const intersect = intersects[0];

// delete cube
if (this.isShiftDown) {
if (intersect.object !== this.plane) {
this.scene.remove(intersect.object);
this.objects.splice(this.objects.indexOf(intersect.object), 1);
this.sceneObjects.splice(this.sceneObjects.indexOf(intersect.object), 1);
}
} else {
// create cube
Expand All @@ -137,7 +140,7 @@ export class App {
voxel.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25);
this.scene.add(voxel);

this.objects.push(voxel);
this.sceneObjects.push(voxel);
}
this.render();
}
Expand Down
45 changes: 43 additions & 2 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ html, body {
height: 100%;
}

.main-layout {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
}

.editor-layout {
width: 100%;
height: 100%;
Expand All @@ -17,6 +24,7 @@ html, body {

.editor-layout #editor canvas {
outline: none;
display: block;
}

.brush-color-container {
Expand Down Expand Up @@ -91,11 +99,27 @@ html, body {
bottom: 0;
left: 0;
right: 0;
background-color: #191818;
color: #ffffff;
background-color: #f0f0f0;
color: grey;
display: flex;
justify-content: center;
align-items: center;
z-index: 100;
flex-direction: column;
}

.ui-loader .loader-container {
width: 300px;
height: 10px;
border: 1px solid grey;
border-radius: 10px;
}

.ui-loader .loader-progress {
height: 100%;
background-color: grey;
width: 0;
transition: width 0.2s ease-in-out;
}

/* (UI) SIDEBAR */
Expand All @@ -104,6 +128,7 @@ html, body {
width: 275px;
display: flex;
flex-direction: column;
border-right: 1px solid grey;
}

.ui-sidebar .pure-menu-list {
Expand All @@ -115,3 +140,19 @@ html, body {
font-size: 14px;
color: grey;
}

/* (UI) TOPBAR */

.ui-topbar {
border-bottom: 1px solid grey;
user-select: none;
}

.ui-topbar .pure-menu-children {
border: 1px solid grey;
}

.ui-topbar .pure-menu-list {
margin-left: 20px;
cursor: pointer;
}
10 changes: 7 additions & 3 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
<meta charset="utf-8" />
</head>
<body>
<div class="editor-layout">
<include src="ui-parts/sidebar.html"></include>
<div id="editor"></div>
<include src="ui-parts/loader.html"></include>
<div class="main-layout">
<include src="ui-parts/topbar.html"></include>
<div class="editor-layout">
<include src="ui-parts/sidebar.html"></include>
<div id="editor"></div>
</div>
</div>
<script src="index.js"></script>
</body>
Expand Down
77 changes: 48 additions & 29 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,58 @@
import 'purecss/build/pure-min.css';
import './index.css';

Promise.all([
const loader = document.getElementById('loader');
const loaderContainer = document.getElementById('loader-container');
const loaderProgress = document.getElementById('loader-progress');

const progressPromise = (promises, tickCallback) => {
const len = promises.length;
let progress = 0;

const tick = (promise) => {
promise.then(() => {
progress++;
tickCallback(progress, len);
});
return promise;
}

return Promise.all(promises.map(tick));
}

const assets = [
import('./three.js'),
import('./app.js'),

// PLUGINS
import('./plugins/file-manager/file-manager.js'),
import('./plugins/color-picker.js'),
import('./plugins/camera-control.js'),
]).then(([
{ THREE },
{ App },
];

// PLUGINS
{ ColorPicker },
{ CameraControl },
]) => {
const plugins = [
ColorPicker,
CameraControl,
];

const app = new App(THREE, plugins);
// app.init();
app.render();
// app.animate();
});

// window.addEventListener( 'resize', onWindowResize, false );
//
// function onWindowResize(){
//
// camera.aspect = window.innerWidth / window.innerHeight;
// camera.updateProjectionMatrix();
//
// renderer.setSize( window.innerWidth, window.innerHeight );
//
// }
const update = (completed, total) => {
const progressWidth = loaderContainer.clientWidth / total * completed;
loaderProgress.style.width = `${progressWidth}px`;
}

progressPromise(assets, update)
.then(([
{ THREE },
{ App },

// PLUGINS
{ FileManager },
{ ColorPicker },
{ CameraControl },
]) => {
const plugins = [
FileManager,
ColorPicker,
CameraControl,
];

const app = new App(THREE, plugins);
app.render();

loader.style.display = 'none';
});
1 change: 0 additions & 1 deletion src/plugins/camera-control.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,6 @@ export class CameraControl {
}

onKeyDown(event) {
console.log(event);
if (this.enableKeys === false || this.enablePan === false) return;

this.handleKeyDown(event);
Expand Down
19 changes: 19 additions & 0 deletions src/plugins/file-manager/exporter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const exporter = (voxels) => {
const data = {
version: '1',
voxels: [],
}

let minorVoxel;
voxels.forEach(voxel => {
minorVoxel = {
position: voxel.position.toArray(),
material: {
color: voxel.material.color.toArray(),
}
};
data.voxels.push(minorVoxel);
});

return data;
}
93 changes: 93 additions & 0 deletions src/plugins/file-manager/file-manager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { exporter } from './exporter';
import { loader } from './loader';

export class FileManager {
constructor(configs) {
this.configs = configs;

const menuItems = document.querySelectorAll('.plugin-file-manager');
menuItems.forEach(item => {
item.addEventListener('click', (event) => this.dispatchEvent(event, item.dataset.event));
})

this.fakeLink = document.createElement('a');
this.fakeLink.style.display = 'none';
document.body.appendChild(this.fakeLink);

this.fakeInput = document.createElement('input');
this.fakeInput.type = 'file';
this.fakeInput.accept = '.vxl';
this.fakeInput.style.display = 'none';
document.body.appendChild(this.fakeInput);

this.fakeInput.addEventListener('change', (event) => this.fileSelected(event));
}

dispatchEvent(event, eventName) {
switch(eventName) {
case 'new':
this.handleNew();
break;
case 'save':
this.handleSave();
break;
case 'open':
this.handleOpen();
break;
}
}

clearScene() {
const scene = this.configs.scene;
const sceneObjects = this.configs.sceneObjects;

scene.remove(...sceneObjects);
sceneObjects.splice(0, sceneObjects.length);
}

handleNew() {
if (confirm('Are you sure you want to create a new file?')) {
this.clearScene();
this.configs.render();
}
}

handleSave() {
const data = exporter(this.configs.sceneObjects);

const output = JSON.stringify(data, null, 2);
this.fakeLink.href = URL.createObjectURL(new Blob([output], { type: 'text/plain' }));
this.fakeLink.download = 'scene.vxl';
this.fakeLink.click();
}

handleOpen() {
this.fakeInput.click();
}

fileSelected(event) {
const files = event.target.files;
const THREE = this.configs.THREE;
const scene = this.configs.scene;
const sceneObjects = this.configs.sceneObjects;

if (files && files.length) {
const reader = new FileReader();
reader.readAsText(files[0]);

reader.onload = () => {
this.clearScene();

const data = loader(THREE, reader.result);
data.forEach(voxel => {
scene.add(voxel);
sceneObjects.push(voxel);
})

this.configs.render();
};
}

event.target.value = null;
}
}
16 changes: 16 additions & 0 deletions src/plugins/file-manager/loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const loader = (THREE, plainText) => {
const voxels = [];

const parsedData = JSON.parse(plainText);
parsedData.voxels.forEach(voxel => {
const mesh = new THREE.Mesh(
new THREE.BoxBufferGeometry(50, 50, 50),
new THREE.MeshLambertMaterial({ color: new THREE.Color(...voxel.material.color) }),
);
mesh.position.fromArray(voxel.position);

voxels.push(mesh);
});

return voxels;
}
5 changes: 4 additions & 1 deletion src/ui-parts/loader.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
<div class="ui-loader">
<div class="ui-loader" id="loader">
<h2>Loading...</h2>
<div class="loader-container" id="loader-container">
<div class="loader-progress" id="loader-progress"></div>
</div>
</div>
Loading

0 comments on commit cfc65c1

Please sign in to comment.