Skip to content

Instantly share code, notes, and snippets.

@AaronGhent
Created September 7, 2017 05:19
Show Gist options
  • Save AaronGhent/94306ccafb5bc27808617a939ccdeef1 to your computer and use it in GitHub Desktop.
Save AaronGhent/94306ccafb5bc27808617a939ccdeef1 to your computer and use it in GitHub Desktop.
[EmberJS] Doobs Cloudy Day + ThreeJS
data:image/png;base64,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
import Ember from 'ember';
/* global THREE */
/* global Detector */
/* jshint -W079 */
var start_time = Date.now();
var camera = null;
var position = null;
var renderer = null;
var mouseX = 0;
var mouseY = 0;
var scene = null;
var speed = 0.03;
var rotation = 0;
var requestAnimationFrameRequestID = null;
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
var cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;
export default Ember.Component.extend({
classNames: ['doobs-cloudy-day-background'],
tagName: 'div',
containerGfx: null,
mesh: null,
geometry: null,
material: null,
didInsertElement() {
if (!Detector.webgl) {
Detector.addGetWebGLMessage();
} else {
this.initGfx();
}
},
initGfx() {
this.containerGfx = this.$().get(0);
// Bg gradient
var canvas = document.createElement('canvas');
canvas.width = 32;
canvas.height = window.innerHeight;
var context = canvas.getContext('2d');
var gradient = context.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(0, "#1e4877");
gradient.addColorStop(0.5, "#4584b4");
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
this.containerGfx.style.background = 'url(' + canvas.toDataURL('image/png') + ')';
this.containerGfx.style.backgroundSize = '32px 100%';
camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 3000 );
camera.position.z = 6000;
scene = new THREE.Scene();
this.geometry = new THREE.Geometry();
var texture = THREE.ImageUtils.loadTexture('img/cloud9.png', null, animate);
texture.magFilter = THREE.LinearFilter;
texture.minFilter = THREE.LinearMipMapLinearFilter;
var fog = new THREE.Fog( 0x4584b4, - 100, 3000 );
this.material = new THREE.ShaderMaterial({
uniforms: {
"map": { type: "t", value: texture },
"fogColor" : { type: "c", value: fog.color },
"fogNear" : { type: "f", value: fog.near },
"fogFar" : { type: "f", value: fog.far },
},
vertexShader: document.getElementById('vs').textContent,
fragmentShader: document.getElementById('fs').textContent,
depthWrite: false,
depthTest: false,
transparent: true
});
var plane = new THREE.Mesh(new THREE.PlaneGeometry(64, 64));
for (var i = 0; i < 8000; i++) {
plane.position.x = Math.random() * 1000 - 500;
plane.position.y = - Math.random() * Math.random() * 200 - 15;
plane.position.z = i;
plane.rotation.z = Math.random() * Math.PI;
plane.scale.x = plane.scale.y = Math.random() * Math.random() * 1.5 + 0.5;
THREE.GeometryUtils.merge(this.geometry, plane);
}
this.mesh = new THREE.Mesh(this.geometry, this.material);
scene.add(this.mesh);
this.mesh = new THREE.Mesh(this.geometry, this.material);
this.mesh.position.z = -8000;
scene.add(this.mesh);
renderer = new THREE.WebGLRenderer({ antialias: false });
renderer.setSize(window.innerWidth, window.innerHeight);
this.containerGfx.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize, false);
},
willDestroyElement() {
this._super(...arguments);
window.removeEventListener('resize', onWindowResize, false);
cancelAnimationFrame(requestAnimationFrameRequestID);
this.geometry.dispose();
this.material.dispose();
}
});
function animate() {
position = ((Date.now() - start_time) * speed) % 8000;
camera.position.x += (mouseX - camera.position.x) * 0.01;
camera.position.y += (-mouseY - camera.position.y) * 0.01;
camera.position.z = - position + 8000;
camera.rotation.z = rotation;
renderer.render(scene, camera);
requestAnimationFrameRequestID = requestAnimationFrame(animate);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
<div id="vs" type="x-shader/x-vertex" style="display: none;">
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</div>
<div id="fs" type="x-shader/x-fragment" style="display: none;">
uniform sampler2D map;
uniform vec3 fogColor;
uniform float fogNear;
uniform float fogFar;
varying vec2 vUv;
void main() {
float depth = gl_FragCoord.z / gl_FragCoord.w;
float fogFactor = smoothstep( fogNear, fogFar, depth );
gl_FragColor = texture2D( map, vUv );
gl_FragColor.w *= pow( gl_FragCoord.z, 20.0 );
gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
}
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment