mirror of
https://github.com/seigler/brunch-threejs
synced 2025-07-27 01:26:10 +00:00
:chick: Create project
This commit is contained in:
commit
f0c43dd44c
17 changed files with 5573 additions and 0 deletions
13
app/assets/index.html
Normal file
13
app/assets/index.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Brunch - Three.js - es6</title>
|
||||
<link rel="stylesheet" href="app.css">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript" src="app.js"></script>
|
||||
<script>require('main')</script>
|
||||
</body>
|
||||
</html>
|
46
app/js/components/Example.js
Normal file
46
app/js/components/Example.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
import props from 'js/core/props';
|
||||
|
||||
import exampleVert from '../shaders/example-vert';
|
||||
import exampleFrag from '../shaders/example-frag';
|
||||
|
||||
class Example extends THREE.Object3D {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
// ##
|
||||
// INIT
|
||||
// const exampleMaterial = new THREE.MeshLambertMaterial({
|
||||
// color: 0xdddddd,
|
||||
// shading: THREE.FlatShading,
|
||||
// });
|
||||
const exampleShaderMaterial = new THREE.ShaderMaterial({
|
||||
uniforms: {
|
||||
color: {
|
||||
type: 'v4',
|
||||
value: new THREE.Vector4(0.9, 0.715, 0.072, 1) },
|
||||
},
|
||||
vertexShader: exampleVert,
|
||||
fragmentShader: exampleFrag,
|
||||
wireframe: true,
|
||||
});
|
||||
// - object
|
||||
const exampleGeometry = new THREE.BoxGeometry(1, 1, 1);
|
||||
// - CREATE MESH
|
||||
this.exampleMesh = new THREE.Mesh(exampleGeometry, exampleShaderMaterial);
|
||||
|
||||
// ##
|
||||
// ADD TO EXAMPLE OBJECT
|
||||
this.add(this.exampleMesh);
|
||||
|
||||
// ##
|
||||
// SAVE BINDING
|
||||
this.onUpdate = this.onUpdate.bind(this);
|
||||
}
|
||||
|
||||
onUpdate() {
|
||||
this.rotation.x += props.rotation;
|
||||
this.rotation.y += props.rotation;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Example;
|
52
app/js/core/Loop.js
Normal file
52
app/js/core/Loop.js
Normal file
|
@ -0,0 +1,52 @@
|
|||
class Loop {
|
||||
|
||||
constructor() {
|
||||
this._idRAF = -1;
|
||||
this._count = 0;
|
||||
|
||||
this._listeners = [];
|
||||
|
||||
this._binds = {};
|
||||
this._binds.update = this._update.bind(this);
|
||||
}
|
||||
|
||||
_update() {
|
||||
let listener = null;
|
||||
let i = this._count;
|
||||
while (--i >= 0) {
|
||||
listener = this._listeners[i];
|
||||
if (listener) {
|
||||
listener.apply(this, null);
|
||||
}
|
||||
}
|
||||
this._idRAF = requestAnimationFrame(this._binds.update);
|
||||
}
|
||||
|
||||
start() {
|
||||
this._update();
|
||||
}
|
||||
|
||||
stop() {
|
||||
cancelAnimationFrame(this._idRAF);
|
||||
}
|
||||
|
||||
add(listener) {
|
||||
const idx = this._listeners.indexOf(listener);
|
||||
if (idx >= 0) {
|
||||
return;
|
||||
}
|
||||
this._listeners.push(listener);
|
||||
this._count++;
|
||||
}
|
||||
|
||||
remove(listener) {
|
||||
const idx = this._listeners.indexOf(listener);
|
||||
if (idx < 0) {
|
||||
return;
|
||||
}
|
||||
this._listeners.splice(idx, 1);
|
||||
this._count--;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new Loop();
|
60
app/js/core/Webgl.js
Normal file
60
app/js/core/Webgl.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
import props from 'js/core/props';
|
||||
|
||||
export default class Webgl {
|
||||
constructor(w, h) {
|
||||
this.scene = new THREE.Scene();
|
||||
|
||||
this.camera = new THREE.PerspectiveCamera(50, w / h, 1, 1000);
|
||||
this.camera.position.z = 10;
|
||||
|
||||
this._renderer = new THREE.WebGLRenderer({
|
||||
antialias: true,
|
||||
});
|
||||
this._renderer.setPixelRatio(window.devicePixelRatio);
|
||||
this._renderer.setClearColor(0x0c171a);
|
||||
this.dom = this._renderer.domElement;
|
||||
|
||||
this._passes = [
|
||||
new THREE.RenderPass(this.scene, this.camera),
|
||||
new THREE.AfterimagePass(),
|
||||
];
|
||||
this.initPostprocessing();
|
||||
this.onResize(w, h);
|
||||
|
||||
this.onUpdate = this.onUpdate.bind(this);
|
||||
this.onResize = this.onResize.bind(this);
|
||||
}
|
||||
|
||||
initPostprocessing() {
|
||||
this._composer = new THREE.EffectComposer(this._renderer);
|
||||
this._passes.forEach((effect, i) => {
|
||||
if (i == this._passes.length - 1) {
|
||||
effect.renderToScreen = true;
|
||||
}
|
||||
this._composer.addPass(effect);
|
||||
});
|
||||
}
|
||||
|
||||
add(mesh) {
|
||||
this.scene.add(mesh);
|
||||
}
|
||||
|
||||
onUpdate() {
|
||||
if (props.postprocessing) {
|
||||
this._composer.render(this.scene, this.camera);
|
||||
} else {
|
||||
this._renderer.render(this.scene, this.camera);
|
||||
}
|
||||
}
|
||||
|
||||
onResize(w, h) {
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
|
||||
this.camera.aspect = w / h;
|
||||
this.camera.updateProjectionMatrix();
|
||||
|
||||
this._composer.setSize(w, h);
|
||||
this._renderer.setSize(w, h);
|
||||
}
|
||||
}
|
14
app/js/core/props.js
Normal file
14
app/js/core/props.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
const props = {
|
||||
rotation: 0.025,
|
||||
postprocessing: false
|
||||
};
|
||||
|
||||
function setUpDat() {
|
||||
const gui = new dat.GUI();
|
||||
gui.add(props, 'rotation', 0, 0.2);
|
||||
gui.add(props, "postprocessing");
|
||||
gui.close();
|
||||
}
|
||||
|
||||
export default props;
|
||||
export { setUpDat };
|
5
app/js/shaders/example-frag.glsl
Normal file
5
app/js/shaders/example-frag.glsl
Normal file
|
@ -0,0 +1,5 @@
|
|||
uniform vec4 color;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = color;
|
||||
}
|
5
app/js/shaders/example-vert.glsl
Normal file
5
app/js/shaders/example-vert.glsl
Normal file
|
@ -0,0 +1,5 @@
|
|||
void main() {
|
||||
gl_Position = projectionMatrix *
|
||||
modelViewMatrix *
|
||||
vec4(position, 1.0);
|
||||
}
|
46
app/main.js
Normal file
46
app/main.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
import Webgl from 'js/core/Webgl';
|
||||
import loop from 'js/core/Loop';
|
||||
import props from 'js/core/props';
|
||||
import {setUpDat} from 'js/core/props';
|
||||
import Example from 'js/components/Example';
|
||||
|
||||
|
||||
// ##
|
||||
// INIT
|
||||
const webgl = new Webgl(window.innerWidth, window.innerHeight);
|
||||
document.body.appendChild(webgl.dom);
|
||||
// - Add object update to loop
|
||||
loop.add(webgl.onUpdate);
|
||||
|
||||
// ##
|
||||
// EXAMPLE LIGHT
|
||||
const light = new THREE.DirectionalLight(0xffffff, 0.5);
|
||||
light.position.set(1, 1, 1);
|
||||
webgl.add(light);
|
||||
|
||||
// ##
|
||||
// EXAMPLE BOX
|
||||
const example = new Example();
|
||||
webgl.add(example);
|
||||
loop.add(example.onUpdate);
|
||||
|
||||
// ##
|
||||
// Dat.GUI
|
||||
setUpDat();
|
||||
|
||||
// ##
|
||||
// RENDERER
|
||||
loop.start();
|
||||
|
||||
|
||||
// ##
|
||||
// ON RESIZE / ORIENTATION CHANGE
|
||||
function onResize() {
|
||||
const w = window.innerWidth;
|
||||
const h = window.innerHeight;
|
||||
|
||||
webgl.onResize(w, h);
|
||||
}
|
||||
|
||||
window.addEventListener('resize', onResize);
|
||||
window.addEventListener('orientationchange', onResize);
|
13
app/style.css
Normal file
13
app/style.css
Normal file
|
@ -0,0 +1,13 @@
|
|||
html, body {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height : 100%;
|
||||
color: #f3f3f4;
|
||||
overflow: hidden; /* browser zoom can make this is necessary sometimes */
|
||||
}
|
||||
|
||||
canvas {
|
||||
position: absolute;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue