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
1
.eslintignore
Normal file
1
.eslintignore
Normal file
|
@ -0,0 +1 @@
|
||||||
|
public/
|
10
.eslintrc.json
Normal file
10
.eslintrc.json
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"extends": "airbnb/base",
|
||||||
|
|
||||||
|
"globals": {
|
||||||
|
"app": true,
|
||||||
|
"dat": true,
|
||||||
|
"THREE": true
|
||||||
|
},
|
||||||
|
"rules": {}
|
||||||
|
}
|
32
.gitignore
vendored
Normal file
32
.gitignore
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# Numerous always-ignore extensions
|
||||||
|
*.diff
|
||||||
|
*.err
|
||||||
|
*.orig
|
||||||
|
*.log
|
||||||
|
*.rej
|
||||||
|
*.swo
|
||||||
|
*.swp
|
||||||
|
*.vi
|
||||||
|
*~
|
||||||
|
*.sass-cache
|
||||||
|
|
||||||
|
# OS or Editor folders
|
||||||
|
.DS_Store
|
||||||
|
.cache
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.tmproj
|
||||||
|
nbproject
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# NPM packages folder.
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Brunch folder for temporary files.
|
||||||
|
tmp/
|
||||||
|
|
||||||
|
# Brunch output folder.
|
||||||
|
public/
|
||||||
|
|
||||||
|
# Bower stuff.
|
||||||
|
bower_components/
|
60
.vscode/settings.json
vendored
Normal file
60
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
{
|
||||||
|
"search.exclude": {
|
||||||
|
"# Numerous always-ignore extensions": true,
|
||||||
|
"*.diff": true,
|
||||||
|
"*.err": true,
|
||||||
|
"*.orig": true,
|
||||||
|
"*.log": true,
|
||||||
|
"*.rej": true,
|
||||||
|
"*.swo": true,
|
||||||
|
"*.swp": true,
|
||||||
|
"*.vi": true,
|
||||||
|
"*~": true,
|
||||||
|
"*.sass-cache": true,
|
||||||
|
"# OS or Editor folders": true,
|
||||||
|
".DS_Store": true,
|
||||||
|
".cache": true,
|
||||||
|
".project": true,
|
||||||
|
".settings": true,
|
||||||
|
".tmproj": true,
|
||||||
|
"nbproject": true,
|
||||||
|
"Thumbs.db": true,
|
||||||
|
"# NPM packages folder.": true,
|
||||||
|
"node_modules/": true,
|
||||||
|
"# Brunch folder for temporary files.": true,
|
||||||
|
"tmp/": true,
|
||||||
|
"# Brunch output folder.": true,
|
||||||
|
"public/": true,
|
||||||
|
"# Bower stuff.": true,
|
||||||
|
"bower_components/": true
|
||||||
|
},
|
||||||
|
"files.exclude": {
|
||||||
|
"# Numerous always-ignore extensions": true,
|
||||||
|
"*.diff": true,
|
||||||
|
"*.err": true,
|
||||||
|
"*.orig": true,
|
||||||
|
"*.log": true,
|
||||||
|
"*.rej": true,
|
||||||
|
"*.swo": true,
|
||||||
|
"*.swp": true,
|
||||||
|
"*.vi": true,
|
||||||
|
"*~": true,
|
||||||
|
"*.sass-cache": true,
|
||||||
|
"# OS or Editor folders": true,
|
||||||
|
".DS_Store": true,
|
||||||
|
".cache": true,
|
||||||
|
".project": true,
|
||||||
|
".settings": true,
|
||||||
|
".tmproj": true,
|
||||||
|
"nbproject": true,
|
||||||
|
"Thumbs.db": true,
|
||||||
|
"# NPM packages folder.": true,
|
||||||
|
"node_modules/": true,
|
||||||
|
"# Brunch folder for temporary files.": true,
|
||||||
|
"tmp/": true,
|
||||||
|
"# Brunch output folder.": true,
|
||||||
|
"public/": true,
|
||||||
|
"# Bower stuff.": true,
|
||||||
|
"bower_components/": true
|
||||||
|
}
|
||||||
|
}
|
55
README.md
Normal file
55
README.md
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
# Brunch app
|
||||||
|
|
||||||
|
|
||||||
|
This is brunch skeleton for starting a project in **WebGL** with [Three.js](http://threejs.org/) and [ES6](http://es6-features.org).
|
||||||
|
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
* Install (if you don't have them):
|
||||||
|
* [Node.js](http://nodejs.org): `brew install node` on OS X
|
||||||
|
* [Brunch](http://brunch.io): `npm install -g brunch`
|
||||||
|
* Create a new project :
|
||||||
|
* Deploy with brunch :
|
||||||
|
* `brunch new myapp --skeleton https://github.com/seigler/brunch-threejs` - create new project
|
||||||
|
* Or use git to clone the brunch-threejs repository :
|
||||||
|
* `git clone https://github.com/Jeremboo/brunch-threejs`
|
||||||
|
* Download dependencies :
|
||||||
|
* `npm run deploy` or `npm install && npm start`
|
||||||
|
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
|
||||||
|
* `npm start` or `brunch watch --server` to watch the project with continuous rebuild.
|
||||||
|
* `npm run prod` or `brunch build --production` to build minified project for production.
|
||||||
|
|
||||||
|
|
||||||
|
## More
|
||||||
|
|
||||||
|
* **Like brunch basic skeleton :**
|
||||||
|
* `public/` dir is fully auto-generated and served by HTTP server. Write your code in `app/` dir.
|
||||||
|
* Place static files you want to be copied from `app/assets/` to `public/`.
|
||||||
|
|
||||||
|
* **Specific to this skeleton :**
|
||||||
|
|
||||||
|
* You can use this dir `/app/js/components/` for your THREE.object3D components. For my part, I create one component for each 3D object. There is an example of a 3D object in this dir (`Example.js`) to show how you can create a THREE.object3D with ES6.
|
||||||
|
|
||||||
|
* `/app/js/shaders` contains fragments and vertex `.glsl` files. If you need to use some `.glsl` file for build a `ShaderMaterial`, you can import these files. Look at `Example.js` for more details.
|
||||||
|
|
||||||
|
* The directory `/app/js/core/` contains:
|
||||||
|
* `Webgl.js` initializes the 3D scene and the camera.
|
||||||
|
* `Loop.js` manages frame animation for each update of 3Dobjects.
|
||||||
|
* `props.js` contains all variables of settings to be uses in all other files. It's specially created to be used by [dat.gui](https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage)
|
||||||
|
|
||||||
|
* `/app/js/main.js` puts these together to animate a 3D object.
|
||||||
|
|
||||||
|
* I also added [EffectComposer](https://threejs.org/examples/#webgl_postprocessing) for post processing.
|
||||||
|
|
||||||
|
|
||||||
|
## Thanks to
|
||||||
|
|
||||||
|
- [Jérémie Boulay](http://jeremieboulay.fr/portfolio/) whose [threejs skeleton](https://github.com/Jeremboo/brunch-threejs-es2015) I forked to get this one.
|
||||||
|
|
||||||
|
- [Valentin Daguenet](http://vdaguenet.fr/) and his repository [Threejs-starter-kit](https://github.com/vdaguenet/threejs-starter-kit).
|
||||||
|
|
||||||
|
- [Florian Zumbrunn](http://www.floz.fr/) for his starter kit during his Three.js workshop at Gobelins, l'école de l'image.
|
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;
|
||||||
|
}
|
19
brunch-config.js
Normal file
19
brunch-config.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
module.exports = {
|
||||||
|
files: {
|
||||||
|
javascripts: {
|
||||||
|
joinTo: 'app.js',
|
||||||
|
},
|
||||||
|
stylesheets: {
|
||||||
|
joinTo: 'app.css',
|
||||||
|
},
|
||||||
|
templates: {
|
||||||
|
joinTo: 'app.js',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
npm: {
|
||||||
|
globals: {
|
||||||
|
THREE: 'three-full',
|
||||||
|
dat: 'dat.gui',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
33
package.json
Normal file
33
package.json
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"name": "brunch-threejs",
|
||||||
|
"description": "Brunch skeleton for beginning a three.js project.",
|
||||||
|
"author": "Joshua Seigler",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/seigler/brunch-threejs"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "brunch watch --server",
|
||||||
|
"deploy": "npm install && npm start",
|
||||||
|
"prod": "rm -r public/ && brunch build --production"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"dat.gui": "^0.7.3",
|
||||||
|
"three-full": "^11.3.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"auto-reload-brunch": "^2.7.1",
|
||||||
|
"babel-brunch": "^7.0.0",
|
||||||
|
"brunch": "^2.10.17",
|
||||||
|
"clean-css-brunch": "^2.10.0",
|
||||||
|
"css-brunch": "^2.10.0",
|
||||||
|
"eslint": "^5.7.0",
|
||||||
|
"eslint-config-airbnb-base": "^13.1.0",
|
||||||
|
"eslint-plugin-import": "^2.14.0",
|
||||||
|
"glslify-brunch": "^1.0.0",
|
||||||
|
"javascript-brunch": "^2.10.0",
|
||||||
|
"uglify-js-brunch": "^2.10.0"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue