c3d2-web/content/static/datenspuren/script/clouds.js

153 lines
3.7 KiB
JavaScript

/* http://paulirish.com/2011/requestanimationframe-for-smart-animating/ */
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function */ callback, /* DOMElement */ element){
window.setTimeout(callback, 1000 / 20);
};
})();
var funEnabled = false;
function now() {
return new Date().getTime();
}
function Flash(x, y) {
this.el = $('<img class="backgroundflash" src="images/flash.png"/>');
this.el.css('left', (x-10)+'px');
this.el.css('top', y+'px');
$('body').append(this.el);
var that = this;
this.el.fadeOut(250, function() {
that.el.detach();
});
}
function Raindrop(x, y, speedX) {
this.lastUpdate = now();
this.fadeUntil = now() + this.ttl;
this.x = x;
this.y = y;
this.speedX = speedX;
this.speedY = 0;
this.el = $('<p class="backgroundraindrop"></p>');
this.el.text(''+Math.floor(Math.random() * 2));
$('body').append(this.el);
this.render();
}
Raindrop.prototype.ttl = 3000;
Raindrop.prototype.render = function() {
var t = now();
var d = (t - this.lastUpdate) / 1000;
this.x += this.speedX * d;
this.speedY += 23 * d; /* gravity */
this.y += this.speedY * d;
this.el.css('left', Math.floor(this.x)+'px');
this.el.css('top', Math.floor(this.y)+'px');
this.el.css('opacity', (this.fadeUntil - t) / this.ttl);
this.lastUpdate = t;
var that = this;
requestAnimFrame(function() {
if (now() > that.fadeUntil)
that.el.detach();
else
that.render();
}, this.el[0]);
};
function Cloud() {
this.lastUpdate = now();
this.speedX = 10 + Math.random() * 50;
if (Math.random() < 0.5) {
this.x = -50;
} else {
this.speedX *= -1;
this.x = screen.width;
}
this.y = Math.floor(Math.random() / 2 * screen.height);
this.el = $('<img class="backgroundcloud" src="images/pixelcloud.png"/>');
$('body').append(this.el);
}
Cloud.prototype.update = function() {
this.x += this.speedX * (now() - this.lastUpdate) / 1000;
this.lastUpdate = now();
this.el.css('left', Math.floor(this.x) + 'px');
this.el.css('top', this.y + 'px');
if (this.isDone())
this.el.detach();
else if (this.raining && Math.random() < 0.1)
new Raindrop(this.x + 8 + Math.random() * 48, this.y + 30, this.speedX);
};
Cloud.prototype.isDone = function() {
return (this.x < -100) || (this.x > screen.width);
};
var clouds = [];
function stepClouds() {
if (clouds.length < 12 && Math.random() < 0.05)
clouds.push(new Cloud());
clouds = clouds.filter(function(cloud) {
cloud.update();
return !cloud.isDone();
});
clouds.forEach(function(cloud1) {
clouds.forEach(function(cloud2) {
if (cloud1 !== cloud2 &&
cloud1.x > cloud2.x - 40 &&
cloud1.x < cloud2.x + 40 &&
cloud1.y > cloud2.y - 72 &&
cloud1.y < cloud2.y + 72 &&
Math.random() < 0.01) {
new Flash(Math.floor((cloud1.x + cloud2.x) / 2),
Math.max(cloud1.y, cloud2.y) + 40);
cloud1.raining = true;
cloud2.raining = true;
}
});
});
if (funEnabled) {
requestAnimFrame(stepClouds, 'body');
} else {
clouds.forEach(function(cloud) {
cloud.el.detach();
});
clouds = [];
}
}
$(document).ready(function() {
$('#cloudy-sun').click(function() {
funEnabled = !funEnabled;
if (funEnabled) {
var solar = $('<div id="solar"> </div>');
solar.hide();
$('#cloudy').append(solar);
$('#solar').fadeIn(1000);
setTimeout(stepClouds, 100);
} else {
$('#solar').detach();
}
});
});