<html lang="en">
|
|
<head>
|
|
<title>Clouds</title>
|
|
<meta charset="utf-8">
|
|
|
|
<style type="text/css">
|
|
*{
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0
|
|
}
|
|
body {
|
|
|
|
color: #eee;
|
|
text-shadow: 0 -1px 0 rgba( 0, 0, 0, .6 );
|
|
font-family: 'Open Sans', sans-serif;
|
|
font-size: 13px;
|
|
line-height: 16px;
|
|
overflow: hidden;
|
|
}
|
|
#viewport {
|
|
-webkit-perspective: 1000;
|
|
-moz-perspective: 1000px;
|
|
-o-perspective: 1000;
|
|
perspective: 1000px;
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
overflow: hidden;
|
|
background-image: url('http://www.incoplast-srl.com/SiteAssets/Cielo-despejado-1363594685_18.jpg');
|
|
background-size: cover;
|
|
/*background-image: linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%);
|
|
background-image: -o-linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%);
|
|
background-image: -moz-linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%);
|
|
background-image: -webkit-linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%);
|
|
background-image: -ms-linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%);
|
|
|
|
background-image: -webkit-gradient(
|
|
linear,
|
|
left bottom,
|
|
left top,
|
|
color-stop(0.28, rgb(69,132,180)),
|
|
color-stop(0.64, rgb(31,71,120))
|
|
);*/
|
|
}
|
|
|
|
#world {
|
|
position: absolute;
|
|
left: 50%;
|
|
top: 50%;
|
|
margin-left: -256px;
|
|
margin-top: -256px;
|
|
height: 512px;
|
|
width: 512px;
|
|
-webkit-transform-style: preserve-3d;
|
|
-moz-transform-style: preserve-3d;
|
|
-o-transform-style: preserve-3d;
|
|
transform-style: preserve-3d;
|
|
pointer-events: none;
|
|
}
|
|
|
|
#world div {
|
|
-webkit-transform-style: preserve-3d;
|
|
-moz-transform-style: preserve-3d;
|
|
-o-transform-style: preserve-3d;
|
|
transform-style: preserve-3d;
|
|
}
|
|
|
|
.cloudBase {
|
|
position: absolute;
|
|
left: 256px;
|
|
top: 256px;
|
|
width: 20px;
|
|
height: 20px;
|
|
margin-left: -10px;
|
|
margin-top: -10px;
|
|
}
|
|
|
|
.cloudLayer {
|
|
position: absolute;
|
|
left: 50%;
|
|
top: 50%;
|
|
width: 256px;
|
|
height: 256px;
|
|
margin-left: -128px;
|
|
margin-top: -128px;
|
|
-webkit-transition: opacity .5s ease-out;
|
|
-moz-transition: opacity .5s ease-out;
|
|
-o-transition: opacity .5s ease-out;
|
|
transition: opacity .5s ease-out;
|
|
}
|
|
|
|
</style>
|
|
|
|
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
|
|
|
|
<script type="text/javascript">
|
|
|
|
$( document ).ready(function() {
|
|
|
|
/*
|
|
Defining our variables
|
|
world and viewport are DOM elements,
|
|
worldXAngle and worldYAngle are floats that hold the world rotations,
|
|
d is an int that defines the distance of the world from the camera
|
|
*/
|
|
var world = document.getElementById( 'world' ),
|
|
viewport = document.getElementById( 'viewport' ),
|
|
worldXAngle = 0,
|
|
worldYAngle = 0,
|
|
d = 0;
|
|
|
|
/*
|
|
Event listener to transform mouse position into angles
|
|
from -180 to 180 degress, both vertically and horizontally
|
|
*/
|
|
window.addEventListener( 'mousemove', function( e ) {
|
|
worldYAngle = -( .5 - ( e.clientX / window.innerWidth ) ) * 360;
|
|
worldXAngle = ( .5 - ( e.clientY / window.innerHeight ) ) * 360;
|
|
updateView();
|
|
} );
|
|
|
|
/*
|
|
Changes the transform property of world to be
|
|
translated in the Z axis by d pixels,
|
|
rotated in the X axis by worldXAngle degrees and
|
|
rotated in the Y axis by worldYAngle degrees.
|
|
*/
|
|
function updateView() {
|
|
world.style.transform = 'translateZ( ' + d + 'px ) \
|
|
rotateX( ' + worldXAngle + 'deg) \
|
|
rotateY( ' + worldYAngle + 'deg)';
|
|
}
|
|
|
|
/*
|
|
objects is an array of cloud bases
|
|
layers is an array of cloud layers
|
|
*/
|
|
var objects = [],
|
|
layers = [];
|
|
textures = [
|
|
{ name: 'white cloud', file: 'cloud.png' , opacity: 1, weight: 0 },
|
|
{ name: 'dark cloud', file: 'darkCloud.png' , opacity: 1, weight: 0 },
|
|
{ name: 'smoke cloud', file: 'smoke.png' , opacity: 1, weight: 0 },
|
|
{ name: 'explosion', file: 'explosion.png' , opacity: 1, weight: 0 },
|
|
{ name: 'explosion 2', file: 'explosion2.png' , opacity: 1, weight: 0 },
|
|
{ name: 'box', file: 'box.png' , opacity: 1, weight: 0 }
|
|
];
|
|
|
|
|
|
/*
|
|
Clears the DOM of previous clouds bases
|
|
and generates a new set of cloud bases
|
|
*/
|
|
function generate() {
|
|
objects = [];
|
|
if ( world.hasChildNodes() ) {
|
|
while ( world.childNodes.length >= 1 ) {
|
|
world.removeChild( world.firstChild );
|
|
}
|
|
}
|
|
computedWeights = [];
|
|
var total = 0;
|
|
for( var j = 0; j < textures.length; j++ ) {
|
|
if( textures[ j ].weight > 0 ) {
|
|
total += textures[ j ].weight;
|
|
}
|
|
}
|
|
var accum = 0;
|
|
for( var j = 0; j < textures.length; j++ ) {
|
|
if( textures[ j ].weight > 0 ) {
|
|
var w = textures[ j ].weight / total;
|
|
computedWeights.push( {
|
|
src: textures[ j ].file,
|
|
min: accum,
|
|
max: accum + w
|
|
} );
|
|
accum += w;
|
|
}
|
|
}
|
|
for( var j = 0; j < 100; j++ ) {
|
|
objects.push( createCloud() );
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
Creates a single cloud base and adds several cloud layers.
|
|
Each cloud layer has random position ( x, y, z ), rotation (a)
|
|
and rotation speed (s). layers[] keeps track of those divs.
|
|
*/
|
|
function createCloud() {
|
|
|
|
var div = document.createElement( 'div' );
|
|
div.className = 'cloudBase';
|
|
var x = 256 - ( Math.random() * 1512 );
|
|
var y = 256 - ( Math.random() * 1512 );
|
|
var z = 256 - ( Math.random() * 1512 );
|
|
var t = 'translateX( ' + x + 'px ) translateY( ' + y + 'px ) translateZ( ' + z + 'px )';
|
|
div.style.webkitTransform =
|
|
div.style.MozTransform =
|
|
div.style.oTransform =
|
|
div.style.transform = t;
|
|
world.appendChild( div );
|
|
|
|
for( var j = 0; j < 5 + Math.round( Math.random() * 10 ); j++ ) {
|
|
var cloud = document.createElement( 'img' );
|
|
cloud.style.opacity = 1;
|
|
var r = Math.random();
|
|
var src = 'cloud10.png';
|
|
|
|
cloud.setAttribute( 'src', src );
|
|
cloud.className = 'cloudLayer';
|
|
|
|
var x = 256 - ( Math.random() * 1512 );
|
|
var y = 256 - ( Math.random() * 1512 );
|
|
var z = 100 - ( Math.random() * 1200 );
|
|
var a = Math.random() * 360;
|
|
var s = .25 + Math.random();
|
|
x *= .2; y *= .2;
|
|
cloud.data = {
|
|
x: x,
|
|
y: y,
|
|
z: z,
|
|
a: a,
|
|
s: s,
|
|
speed: .1 * Math.random(),
|
|
r: Math.random()
|
|
};
|
|
var t = 'translateX( ' + x + 'px ) translateY( ' + y + 'px ) translateZ( ' + z + 'px ) rotateZ( ' + a + 'deg ) scale( ' + s + ' )';
|
|
cloud.style.webkitTransform =
|
|
cloud.style.MozTransform =
|
|
cloud.style.oTransform =
|
|
cloud.style.transform = t;
|
|
|
|
div.appendChild( cloud );
|
|
layers.push( cloud );
|
|
}
|
|
|
|
return div;
|
|
}
|
|
|
|
generate();
|
|
|
|
|
|
function update (){
|
|
|
|
for( var j = 0; j < layers.length; j++ ) {
|
|
var layer = layers[ j ];
|
|
if(Math.random() >= layer.data.r){
|
|
layer.data.a += layer.data.speed;
|
|
}else{
|
|
layer.data.a -= layer.data.speed;
|
|
}
|
|
|
|
if(Math.random() >= layer.data.r){
|
|
layer.data.x += layer.data.speed;
|
|
}else{
|
|
layer.data.x -= layer.data.speed;
|
|
}
|
|
|
|
if(Math.random() >= layer.data.r){
|
|
layer.data.y += layer.data.speed;
|
|
}else{
|
|
layer.data.y -= layer.data.speed;
|
|
}
|
|
|
|
var t = 'translateX( ' + layer.data.x + 'px ) translateY( ' + layer.data.y + 'px ) translateZ( ' + layer.data.z + 'px ) rotateY( ' + ( - worldYAngle ) + 'deg ) rotateX( ' + ( - worldXAngle ) + 'deg ) rotateZ( ' + layer.data.a + 'deg ) scale( ' + layer.data.s + ')';
|
|
layer.style.webkitTransform =
|
|
layer.style.MozTransform =
|
|
layer.style.oTransform =
|
|
layer.style.transform = t;
|
|
//layer.style.webkitFilter = 'blur(5px)';
|
|
}
|
|
|
|
requestAnimationFrame( update );
|
|
|
|
}
|
|
|
|
update();
|
|
|
|
});
|
|
</script>
|
|
|
|
</head>
|
|
<body>
|
|
|
|
<div id="viewport" >
|
|
<div id="world" ></div>
|
|
</div>
|
|
|
|
</body>
|
|
</html>
|