three.proton
Version:
three.Proton is an easily customizable html5 particle engine for three.js
219 lines (182 loc) • 6.78 kB
HTML
<html>
<head>
<title>three.proton - helloworld</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style type="text/css">
body {
font-family: Monospace;
background-color: #fff;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="../lib/stats.min.js"></script>
<script src="../lib/three.min.js"></script>
<script src="../build/three.proton.min.js"></script>
<script>
var proton, emitter;
var camera, scene, renderer, stats, clock, mouseXpercent, mouseYpercent, cameraTarget;
init();
function init() {
addScene();
addLights();
addPlane();
addInteraction();
addProton();
addStats();
animate();
}
function addScene() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 3000);
camera.position.z = 500;
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0xffffff, 1, 10000);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize, false);
}
function addLights() {
var spotLight = new THREE.SpotLight(0xffffff, .5);
spotLight.position.set(0, 500, 100);
scene.add(spotLight);
spotLight.lookAt(scene);
// var spotLightHelper = new THREE.SpotLightHelper(spotLight);
// scene.add(spotLightHelper);
var pointLight = new THREE.PointLight(0xffffff, 2, 1000, 1);
pointLight.position.set(0, 200, 200);
scene.add(pointLight);
}
function addPlane() {
var plane = new THREE.Mesh(
new THREE.PlaneGeometry(2000, 2000, 9, 24),
new THREE.MeshLambertMaterial({
color: "#3c5887",
fog: false
})
);
var planeGeometry = plane.geometry;
for (i = 0, l = planeGeometry.vertices.length; i < l; i++) {
var y = Math.floor(i / 10);
var x = i - (y * 10);
if (x == 4 || x == 5) {
planeGeometry.vertices[i].z = 0;
} else {
planeGeometry.vertices[i].z = (Math.random() * 480) - 240;
}
if (y == 0 || y == 24) {
planeGeometry.vertices[i].z = -60;
}
}
plane.rotation.x = -Math.PI / 3;
plane.position.y = -200;
scene.add(plane);
}
function addStats() {
stats = new Stats();
stats.showPanel(0);
stats.dom.style.position = 'absolute';
stats.dom.style.left = '0px';
stats.dom.style.top = '0px';
container.appendChild(stats.dom);
}
function addProton() {
proton = new Proton();
emitter = new Proton.Emitter();
emitter.rate = new Proton.Rate(new Proton.Span(34, 48), new Proton.Span(.2, .5));
emitter.addInitialize(new Proton.Mass(1));
emitter.addInitialize(new Proton.Radius(new Proton.Span(10, 20)));
var position = new Proton.Position();
position.addZone(new Proton.BoxZone(2500, 10, 2500));
emitter.addInitialize(position);
emitter.addInitialize(new Proton.Life(5, 10));
emitter.addInitialize(new Proton.Body(createSnow()));
emitter.addInitialize(new Proton.Velocity(0, new Proton.Vector3D(0, -1, 0), 90));
emitter.addBehaviour(new Proton.RandomDrift(10, 1, 10, .05));
emitter.addBehaviour(new Proton.Rotate("random", "random"));
emitter.addBehaviour(new Proton.Gravity(2));
var sceenZone = new Proton.ScreenZone(camera, renderer, 20, "234");
emitter.addBehaviour(new Proton.CrossZone(sceenZone, "dead"));
emitter.p.x = 0;
emitter.p.y = 800;
emitter.emit();
proton.addEmitter(emitter);
proton.addRender(new Proton.SpriteRender(scene));
//Proton.Debug.drawZone(proton,scene,new Proton.BoxZone(800, 10, 800));
}
function createSnow() {
var map = new THREE.TextureLoader().load("./img/snow.png");
var material = new THREE.SpriteMaterial({
map: map,
transparent: true,
opacity: .5,
color: 0xffffff
});
return new THREE.Sprite(material);
}
function initInteraction() {
window.addEventListener('mousemove', onMouseMove, false);
var pos = {
x: 0,
y: 0
};
function onMouseMove(event) {
pos.x = event.clientX;
pos.y = event.clientY;
var target = Proton.THREEUtil.toSpacePos(pos, camera, renderer.domElement);
emitter.p.x += (target.x - emitter.p.x) / 10;
emitter.p.y += (target.y - emitter.p.y) / 10;
emitter.p.z += (target.z - emitter.p.z) / 10;
}
}
function animate() {
stats.begin();
requestAnimationFrame(animate);
render();
stats.end();
}
function render() {
proton.update();
renderer.render(scene, camera);
controlCamera();
Proton.Debug.renderInfo(proton, 3);
}
function addInteraction() {
document.addEventListener('mousemove', onDocumentMouseMove, false);
document.addEventListener('touchmove', onTouchMove, false);
mouseXpercent = mouseYpercent = 0;
cameraTarget = new THREE.Vector3();
function onDocumentMouseMove(event) {
var windowHalfX = window.innerWidth >> 1;
var windowHalfY = window.innerHeight >> 1;
var mouseX = (event.clientX - windowHalfX);
var mouseY = (event.clientY - windowHalfY);
mouseXpercent = mouseX / windowHalfX;
mouseYpercent = mouseY / windowHalfY;
}
function onTouchMove(event) {
event.preventDefault();
onDocumentMouseMove(event.touches[0]);
}
}
function controlCamera() {
cameraTarget.y += (((camera.position.y + 80) - mouseYpercent * 120) - cameraTarget.y) / 20;
cameraTarget.x += (mouseXpercent * 400 - cameraTarget.x) / 20;
camera.lookAt(cameraTarget);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
//controls.handleResize();
}
</script>
</body>
</html>