371 lines
9.9 KiB
JavaScript
371 lines
9.9 KiB
JavaScript
var renderer, scene, camera, controls, light;
|
|
|
|
var waterSettings = {
|
|
base: 0.001,
|
|
size: {
|
|
x: 8,
|
|
y: 0,
|
|
z: 8
|
|
},
|
|
maxValue: 8,
|
|
selected: 0,
|
|
level: 1,
|
|
slosh: 0,
|
|
sloshRange: [0.3, 0.7],
|
|
sections: 10,
|
|
range: 0.05,
|
|
ranges: [0.06, 0.05],
|
|
spaceBetween: 25,
|
|
speed: 0.1
|
|
}
|
|
|
|
var sceneSettings = {
|
|
cameraZ: 0
|
|
}
|
|
|
|
var timeline = new TimelineMax();
|
|
var sloshAnimation = new TimelineMax();
|
|
|
|
var waterBlocks = [{
|
|
title: 'One',
|
|
bars: [
|
|
{color: 0xEF3740, value: 5},
|
|
{color: 0xEA962E, value: 4},
|
|
{color: 0x6FA272, value: 3},
|
|
{color: 0xEFF270, value: 3},
|
|
{color: 0x6DE57E, value: 2},
|
|
]
|
|
}, {
|
|
title: 'Two',
|
|
bars: [
|
|
{color: 0xEF3740, value: 6},
|
|
{color: 0xEA962E, value: 2},
|
|
{color: 0x6FA272, value: 3},
|
|
{color: 0xEFF270, value: 1},
|
|
{color: 0x6DE57E, value: 4},
|
|
]
|
|
}, {
|
|
title: 'Three',
|
|
bars: [
|
|
{color: 0xEF3740, value: 2},
|
|
{color: 0xEA962E, value: 2},
|
|
{color: 0x6FA272, value: 2},
|
|
{color: 0xEFF270, value: 2},
|
|
{color: 0x6DE57E, value: 2},
|
|
]
|
|
}, {
|
|
title: 'Four',
|
|
bars: [
|
|
{color: 0xEF3740, value: 7},
|
|
{color: 0xEA962E, value: 2},
|
|
{color: 0x6FA272, value: 1.4},
|
|
{color: 0xEFF270, value: 2},
|
|
{color: 0x6DE57E, value: 4},
|
|
]
|
|
}, {
|
|
title: 'Five',
|
|
bars: [
|
|
{color: 0xEF3740, value: 5},
|
|
{color: 0xEA962E, value: 5},
|
|
{color: 0x6FA272, value: 4},
|
|
{color: 0xEFF270, value: 2},
|
|
{color: 0x6DE57E, value: 2},
|
|
]
|
|
}];
|
|
|
|
function init() {
|
|
// renderer
|
|
|
|
renderer = new THREE.WebGLRenderer({
|
|
antialias: true,
|
|
alpha: true
|
|
});
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
renderer.setClearColor(0x222428, 1);
|
|
document.body.appendChild(renderer.domElement);
|
|
|
|
// scene
|
|
|
|
scene = new THREE.Scene();
|
|
|
|
// camera
|
|
|
|
var aspect = window.innerWidth / window.innerHeight;
|
|
var d = 20;
|
|
camera = new THREE.OrthographicCamera(-d * aspect, d * aspect, d, -d, -100, 1000);
|
|
camera.lookAt(new THREE.Vector3(0, 0, 0));
|
|
|
|
// materials
|
|
|
|
var waterSides = new THREE.MeshPhongMaterial({
|
|
color: 0x4DBFE1,
|
|
side: THREE.DoubleSide,
|
|
transparent: true,
|
|
opacity: 0.8,
|
|
//shading: THREE.FlatShading,
|
|
specular: 0x4DBFE1,
|
|
shininess: 5,
|
|
});
|
|
|
|
var waterTop = new THREE.MeshPhongMaterial({
|
|
color: 0x14435C,
|
|
side: THREE.DoubleSide,
|
|
shading: THREE.FlatShading,
|
|
transparent: true,
|
|
opacity: 0.9,
|
|
specular: 0xFFFFFF,
|
|
shininess: 10,
|
|
});
|
|
|
|
var materials = [waterSides, waterSides, waterTop, waterSides, waterSides, waterSides];
|
|
|
|
|
|
//light
|
|
|
|
light = new THREE.PointLight(0xffffff, 2, 600, 5);
|
|
light.position.set(waterSettings.size.x + 1.5, waterSettings.maxValue * 2, (waterSettings.size.z + 1) - (waterSettings.spaceBetween * waterSettings.selected));
|
|
scene.add(light);
|
|
|
|
//grid
|
|
|
|
var grid = new THREE.GridHelper(200, 1);
|
|
grid.setColors(0x2B2A2F, 0x2B2A2F);
|
|
scene.add(grid);
|
|
|
|
// water blocks
|
|
|
|
for (var j = 0; j < waterBlocks.length; j++)
|
|
{
|
|
var group = new THREE.Group();
|
|
|
|
waterBlocks[j].group = group;
|
|
waterBlocks[j].water = null;
|
|
waterBlocks[j].waterMesh = null;
|
|
waterBlocks[j].sloshOffsets = [];
|
|
waterBlocks[j].topVertices = [];
|
|
waterBlocks[j].angles = [];
|
|
|
|
//floor
|
|
|
|
var floorGeometry = new THREE.BoxGeometry(waterSettings.size.x, 0.5, waterSettings.size.z);
|
|
floorGeometry.applyMatrix(new THREE.Matrix4().makeTranslation(0, 0.25, 0));
|
|
|
|
var floor = new THREE.Mesh(
|
|
floorGeometry,
|
|
new THREE.MeshLambertMaterial({
|
|
color: 0x333333
|
|
})
|
|
);
|
|
floor.position.y = 0;
|
|
floor.position.x = 0;
|
|
floor.position.z = 0;
|
|
|
|
group.add(floor);
|
|
|
|
//sphere
|
|
|
|
/* var geometry = new THREE.SphereGeometry( 2, 15, 15 );
|
|
var material = new THREE.MeshLambertMaterial( {color: 0xff5555} );
|
|
var sphere = new THREE.Mesh( geometry, material );
|
|
sphere.position.y = 5;
|
|
group.add( sphere ); */
|
|
|
|
// geometry
|
|
waterBlocks[j].water = new THREE.BoxGeometry(waterSettings.size.x, waterSettings.maxValue, waterSettings.size.z, waterSettings.sections, 1, waterSettings.sections);
|
|
|
|
var count = 0;
|
|
var pos = 0 - Math.floor(waterSettings.sections / 2);
|
|
var zeds = [];
|
|
|
|
for (var i = waterBlocks[j].water.vertices.length - 1; i >= 0; i--) {
|
|
|
|
if (waterBlocks[j].water.vertices[i].y >= (waterSettings.maxValue / 2))
|
|
{
|
|
waterBlocks[j].topVertices.push(waterBlocks[j].water.vertices[i]);
|
|
zeds.push(waterBlocks[j].water.vertices[i].z)
|
|
waterBlocks[j].angles.push(count + waterSettings.speed + (Math.random()*2));
|
|
waterBlocks[j].sloshOffsets.push( Math.random() / 2);
|
|
count++;
|
|
}
|
|
};
|
|
|
|
zeds = _.uniq(zeds);
|
|
zeds.sort(function(a, b)
|
|
{
|
|
return a - b
|
|
});
|
|
|
|
for (var i = waterBlocks[j].topVertices.length - 1; i >= 0; i--)
|
|
{
|
|
waterBlocks[j].topVertices[i].zPos = zeds.indexOf(waterBlocks[j].topVertices[i].z) - Math.floor(zeds.length / 2);
|
|
}
|
|
|
|
waterBlocks[j].water.applyMatrix(new THREE.Matrix4().makeTranslation(0, (waterSettings.maxValue / 2) - waterSettings.base, 0));
|
|
|
|
// mesh
|
|
waterBlocks[j].waterMesh = new THREE.Mesh(waterBlocks[j].water, new THREE.MeshFaceMaterial(materials));
|
|
waterBlocks[j].waterMesh.position.y = 0.51;
|
|
waterBlocks[j].waterMesh.position.x = 0;
|
|
waterBlocks[j].waterMesh.position.z = 0;
|
|
group.add(waterBlocks[j].waterMesh);
|
|
|
|
waterBlocks[j].wireframe = new THREE.WireframeHelper( waterBlocks[j].waterMesh, 0x00ff00 );
|
|
//group.add(waterBlocks[j].wireframe);
|
|
|
|
for (var i = 0; i < waterBlocks[j].bars.length; i++)
|
|
{
|
|
var height = waterBlocks[j].bars[i].value;
|
|
var color = waterBlocks[j].bars[i].color;
|
|
|
|
var row = Math.floor(i/2);
|
|
var col = i%2 == 0 ? 0 : 1;
|
|
|
|
var dataBar = new THREE.BoxGeometry(0.8 * 2, height * 2, 0.8 * 2, 10, 10, 10);
|
|
dataBar.applyMatrix( new THREE.Matrix4().makeTranslation( 0, height, 0 ) );
|
|
|
|
var dataBarMesh = new THREE.Mesh
|
|
(
|
|
dataBar,
|
|
new THREE.MeshLambertMaterial({color: color, transparent: false, opacity: 0.9})
|
|
);
|
|
dataBarMesh.position.y = 0;
|
|
dataBarMesh.position.x = -0 + (2.1 * col);
|
|
dataBarMesh.position.z = -2 + (2.1 * row);
|
|
|
|
group.add( dataBarMesh );
|
|
|
|
// var dataBarMeshOutline = new THREE.EdgesHelper( dataBarMesh, 0xdddddd );
|
|
// dataBarMeshOutline.material.linewidth = 2;
|
|
// dataBarMeshOutline.material.transparent = true;
|
|
// dataBarMeshOutline.material.opacity = 0.75;
|
|
// group.add( dataBarMeshOutline );
|
|
|
|
dataBarMesh.scale.y = 0.1;
|
|
TweenLite.to(dataBarMesh.scale, 2, {y: 1, delay: 0.1 + (i/6), ease: Elastic.easeOut});
|
|
//dataBarMeshOutline.scale.y = 0.1;
|
|
//TweenLite.to(dataBarMeshOutline.scale, 2, {y: 0.1, delay: 1 + (i/6), ease: Elastic.easeOut});
|
|
}
|
|
|
|
scene.add(group);
|
|
|
|
group.position.z = 0 - j * waterSettings.spaceBetween;
|
|
};
|
|
}
|
|
|
|
function render() {
|
|
renderer.render(scene, camera);
|
|
}
|
|
|
|
function animate() {
|
|
camera.position.set(20, 20, 20 + sceneSettings.cameraZ);
|
|
camera.lookAt(new THREE.Vector3(0, 5.6, sceneSettings.cameraZ));
|
|
|
|
requestAnimationFrame(animate);
|
|
|
|
for (var i = 0; i < waterBlocks.length; i++)
|
|
{
|
|
waterBlocks[i].waterMesh.scale.y = waterSettings.size.y / 100;
|
|
|
|
for (var j = waterBlocks[i].topVertices.length - 1; j >= 0; j--)
|
|
{
|
|
var sloshAmount = waterBlocks[i].topVertices[j].zPos * waterSettings.slosh * waterBlocks[i].sloshOffsets[j];
|
|
waterBlocks[i].topVertices[j].y = sloshAmount + (waterSettings.maxValue + Math.sin(waterBlocks[i].angles[j]) * waterSettings.range);
|
|
waterBlocks[i].angles[j] += waterSettings.speed;
|
|
}
|
|
|
|
waterBlocks[i].water.verticesNeedUpdate = true;
|
|
}
|
|
|
|
render();
|
|
}
|
|
|
|
function next()
|
|
{
|
|
var toSelect = waterSettings.selected + 1;
|
|
if(toSelect >= waterBlocks.length) toSelect = 0;
|
|
selectBlock(toSelect, waterSettings.selected);
|
|
}
|
|
|
|
function prev()
|
|
{
|
|
var toSelect = waterSettings.selected - 1;
|
|
if(toSelect < 0) toSelect = waterBlocks.length - 1;
|
|
selectBlock(toSelect, waterSettings.selected);
|
|
}
|
|
|
|
function selectBlock(newPos, oldPos)
|
|
{
|
|
waterSettings.selected = newPos;
|
|
var targetSlosh = 0;
|
|
var sloshAmount = (((waterSettings.sloshRange[0] - waterSettings.sloshRange[1]) / 100) * (100 - waterSettings.size.y)) + waterSettings.sloshRange[1]
|
|
if (newPos > oldPos) targetSlosh = -sloshAmount
|
|
else if (newPos < oldPos) targetSlosh = sloshAmount
|
|
|
|
sloshAnimation.clear()
|
|
sloshAnimation.append(TweenMax.to(waterSettings, 0.4, {
|
|
slosh: targetSlosh,
|
|
ease: Power2.easeIn
|
|
}));
|
|
sloshAnimation.append(TweenMax.to(waterSettings, 2.5, {
|
|
slosh: 0,
|
|
ease: Elastic.easeOut
|
|
}));
|
|
sloshAnimation.restart();
|
|
|
|
TweenMax.to(sceneSettings, 1, {
|
|
cameraZ: 0 - (waterSettings.spaceBetween * newPos),
|
|
ease: Power4.easeInOut
|
|
});
|
|
TweenMax.to(light.position, 1, {
|
|
z: (waterSettings.size.z + 0.5) - (waterSettings.spaceBetween * waterSettings.selected),
|
|
ease: Power4.easeInOut
|
|
});
|
|
}
|
|
|
|
function setWaterLevel(percent)
|
|
{
|
|
waterSettings.oldlevel = waterSettings.level;
|
|
|
|
var level = (waterSettings.maxValue / 100) * percent;
|
|
var p = percent == 100 ? 105 : percent;
|
|
TweenLite.to(waterSettings.size, 0.5, {
|
|
y: level > 0.5 ? p : ((0.5 / waterSettings.maxValue) * 100),
|
|
ease: Power2.easeInOut
|
|
});
|
|
|
|
var diff = percent - waterSettings.level;
|
|
var disturbAmount = (diff / 100) * 0.5;
|
|
timeline.clear()
|
|
var r = (((waterSettings.ranges[0] - waterSettings.ranges[1]) / 100) * (100 - waterSettings.size.y)) + waterSettings.ranges[1]
|
|
timeline.append(TweenMax.to(waterSettings, 0.5, {
|
|
range: r + disturbAmount,
|
|
ease: Power2.easeIn
|
|
}));
|
|
timeline.append(TweenMax.to(waterSettings, 2.5, {
|
|
range: r,
|
|
ease: Elastic.easeOut
|
|
}));
|
|
|
|
timeline.restart();
|
|
|
|
waterSettings.level = percent;
|
|
}
|
|
|
|
function randomHeight()
|
|
{
|
|
setWaterLevel(Math.random() * 100);
|
|
}
|
|
|
|
init();
|
|
render();
|
|
animate();
|
|
setWaterLevel(50);
|
|
|
|
window.addEventListener( 'resize', function ()
|
|
{
|
|
camera.aspect = window.innerWidth / window.innerHeight;
|
|
camera.updateProjectionMatrix();
|
|
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
|
|
}, false ); |