(Created page with "$(document).ready(function(){var t=document.scripts[document.scripts.length-1],e=document.createElement("canvas");e.style.position="absolute",e.style.left="0",e.style.top="0",...") |
|||
Line 1: | Line 1: | ||
− | $(document).ready(function(){var | + | $(document).ready(function(){ |
+ | function isScrolledIntoView(e) { | ||
+ | var rect = e.getBoundingClientRect(); | ||
+ | var elemTop = rect.top; | ||
+ | var elemBottom = rect.bottom; | ||
+ | var isVisible = elemTop < window.innerHeight && elemBottom >= 0; | ||
+ | return isVisible; | ||
+ | } | ||
+ | |||
+ | // basic render loop | ||
+ | var script = document.scripts[document.scripts.length - 1]; | ||
+ | var canvas = document.createElement("canvas"); | ||
+ | canvas.style.position = "absolute"; canvas.style.left = "0"; canvas.style.top = "0"; | ||
+ | canvas.style.width = "100%"; canvas.style.height = "100%"; | ||
+ | script.parentElement.insertBefore(canvas, script); | ||
+ | var c = canvas.getContext("2d"); | ||
+ | var time = Date.now(), last = time, deltaTime = 0; | ||
+ | var alive = 40; | ||
+ | canvas.width = canvas.parentNode.clientWidth; | ||
+ | canvas.height = canvas.parentNode.clientHeight; | ||
+ | |||
+ | |||
+ | var ready = false; | ||
+ | function loop(){ | ||
+ | if(alive > 0) requestAnimationFrame(loop); | ||
+ | else return; | ||
+ | if(isScrolledIntoView(canvas) && !ready){ | ||
+ | for(var i = 0; i < 40; i++){ | ||
+ | var particle = {id: i, enabled:true}; | ||
+ | randomizeParticle(particle); | ||
+ | particles.push(particle); | ||
+ | } | ||
+ | ready = true; | ||
+ | } | ||
+ | if(ready){ | ||
+ | canvas.width = canvas.parentNode.clientWidth; | ||
+ | canvas.height = canvas.parentNode.clientHeight; | ||
+ | c.clearRect(0, 0, c.width, c.height); | ||
+ | update(); | ||
+ | } | ||
+ | time = Date.now(); | ||
+ | deltaTime = (time - last) * 0.01; | ||
+ | last = time; | ||
+ | } | ||
+ | |||
+ | // create all particles | ||
+ | var particles = []; | ||
+ | var fadeSpeed = 0.15; | ||
+ | var minSpeed = 5.2; | ||
+ | var maxSpeed = 15.2; | ||
+ | var minDist = 30; | ||
+ | |||
+ | function randomizeParticle(particle){ | ||
+ | particle.radius = rnd(10, 20); | ||
+ | particle.position = rndPosition(particle.radius); | ||
+ | particle.rotation = rnd(0, 360); | ||
+ | particle.velocity = {x: rnd(minSpeed,maxSpeed) * (rnd(0,2) == 1 ? -1 : 1), y: rnd(minSpeed,maxSpeed) * (rnd(0,2) == 1 ? -1 : 1)}; | ||
+ | particle.lifetime = rnd(3,5); | ||
+ | particle.spawnTime = time; | ||
+ | particle.color = "rgb("+rnd(0,255)+", " + rnd(0,255)+", " + rnd(0,255) + ")"; | ||
+ | particle.alpha = 0.0; | ||
+ | particle.fadeState = -1; // -1 = NONE, 0 = IN, 1 = OUT | ||
+ | } | ||
+ | |||
+ | function respawnParticle(particle){ | ||
+ | randomizeParticle(particle); | ||
+ | particle.alpha = 0.0; | ||
+ | particle.fadeState = particle.position == -1 ? -1 : 0; | ||
+ | } | ||
+ | |||
+ | function rndPosition(radius){ | ||
+ | var pos = {x: rnd(0, canvas.width), y: rnd(0, 15)}; | ||
+ | var valid = true; | ||
+ | for(var i = 0; i < particles.length; i++){ | ||
+ | var obj = particles[i]; | ||
+ | var d = dist(obj.position, pos); | ||
+ | if(d < radius + obj.radius + minDist) valid = false; | ||
+ | } | ||
+ | if(valid) return pos; | ||
+ | else return -1; | ||
+ | } | ||
+ | |||
+ | |||
+ | // update particles each frame | ||
+ | function update(){ | ||
+ | for(var i = 0; i < particles.length; i++){ | ||
+ | var e = particles[i]; | ||
+ | if(!e.enabled) continue; | ||
+ | // only draw particles without overlapping positions | ||
+ | if(e.position == -1){ | ||
+ | e.position = rndPosition(e.radius); | ||
+ | if(e.position == -1) continue; | ||
+ | else e.fadeState = 0; | ||
+ | } | ||
+ | |||
+ | // apply velocity | ||
+ | e.position.x += e.velocity.x * deltaTime *0.1; | ||
+ | e.position.y += e.velocity.y * deltaTime; | ||
+ | |||
+ | // despawn | ||
+ | if((time - e.spawnTime) / 1000 >= e.lifetime) e.fadeState = 1; | ||
+ | |||
+ | e.rotation += deltaTime * 0.1; | ||
+ | |||
+ | switch(e.fadeState){ | ||
+ | case 0: | ||
+ | if(e.alpha < 1.0) e.alpha += fadeSpeed * deltaTime; | ||
+ | if(e.alpha >= 1.0){ | ||
+ | e.alpha = 1.0; | ||
+ | e.fadeState = -1; | ||
+ | } | ||
+ | break; | ||
+ | case 1: | ||
+ | if(e.alpha > 0.0) e.alpha -= fadeSpeed * deltaTime; | ||
+ | if(e.alpha <= 0.0){ | ||
+ | e.enabled = false; | ||
+ | alive--; | ||
+ | if(alive == 0){ | ||
+ | particles = [];canvas.parentNode.removeChild(canvas); | ||
+ | } | ||
+ | } | ||
+ | break; | ||
+ | } | ||
+ | |||
+ | // render | ||
+ | c.globalAlpha = e.alpha * 0.2; | ||
+ | c.translate(e.position.x, e.position.y); | ||
+ | c.rotate(e.rotation); | ||
+ | drawParticle(e); | ||
+ | c.rotate(e.rotation * -1); | ||
+ | c.translate(-e.position.x, -e.position.y); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | function drawParticle(e){ | ||
+ | c.fillStyle = e.color; | ||
+ | c.fillRect(-e.radius/2,-e.radius/2/2, e.radius, e.radius/2); | ||
+ | } | ||
+ | |||
+ | function rnd(min, max) { | ||
+ | return Math.floor(Math.random() * (max - min + 1) ) + min; | ||
+ | } | ||
+ | |||
+ | function dist(pos1, pos2){ | ||
+ | var a = pos1.x - pos2.x; | ||
+ | var b = pos1.y - pos2.y; | ||
+ | return Math.sqrt(a*a + b*b); | ||
+ | } | ||
+ | |||
+ | function clamp(v, min, max){ | ||
+ | return v < min ? min : v > max ? max : v; | ||
+ | } | ||
+ | |||
+ | loop(); | ||
+ | }); |
Revision as of 13:10, 26 November 2018
$(document).ready(function(){ function isScrolledIntoView(e) { var rect = e.getBoundingClientRect(); var elemTop = rect.top; var elemBottom = rect.bottom; var isVisible = elemTop < window.innerHeight && elemBottom >= 0; return isVisible; }
// basic render loop var script = document.scripts[document.scripts.length - 1]; var canvas = document.createElement("canvas"); canvas.style.position = "absolute"; canvas.style.left = "0"; canvas.style.top = "0"; canvas.style.width = "100%"; canvas.style.height = "100%"; script.parentElement.insertBefore(canvas, script); var c = canvas.getContext("2d"); var time = Date.now(), last = time, deltaTime = 0; var alive = 40; canvas.width = canvas.parentNode.clientWidth; canvas.height = canvas.parentNode.clientHeight;
var ready = false;
function loop(){
if(alive > 0) requestAnimationFrame(loop);
else return;
if(isScrolledIntoView(canvas) && !ready){
for(var i = 0; i < 40; i++){
var particle = {id: i, enabled:true};
randomizeParticle(particle);
particles.push(particle);
}
ready = true;
}
if(ready){
canvas.width = canvas.parentNode.clientWidth;
canvas.height = canvas.parentNode.clientHeight;
c.clearRect(0, 0, c.width, c.height);
update();
}
time = Date.now();
deltaTime = (time - last) * 0.01;
last = time;
}
// create all particles var particles = []; var fadeSpeed = 0.15; var minSpeed = 5.2; var maxSpeed = 15.2; var minDist = 30;
function randomizeParticle(particle){ particle.radius = rnd(10, 20); particle.position = rndPosition(particle.radius); particle.rotation = rnd(0, 360); particle.velocity = {x: rnd(minSpeed,maxSpeed) * (rnd(0,2) == 1 ? -1 : 1), y: rnd(minSpeed,maxSpeed) * (rnd(0,2) == 1 ? -1 : 1)}; particle.lifetime = rnd(3,5); particle.spawnTime = time; particle.color = "rgb("+rnd(0,255)+", " + rnd(0,255)+", " + rnd(0,255) + ")"; particle.alpha = 0.0; particle.fadeState = -1; // -1 = NONE, 0 = IN, 1 = OUT }
function respawnParticle(particle){ randomizeParticle(particle); particle.alpha = 0.0; particle.fadeState = particle.position == -1 ? -1 : 0; }
function rndPosition(radius){ var pos = {x: rnd(0, canvas.width), y: rnd(0, 15)}; var valid = true; for(var i = 0; i < particles.length; i++){ var obj = particles[i]; var d = dist(obj.position, pos); if(d < radius + obj.radius + minDist) valid = false; } if(valid) return pos; else return -1; }
// update particles each frame
function update(){
for(var i = 0; i < particles.length; i++){
var e = particles[i];
if(!e.enabled) continue;
// only draw particles without overlapping positions
if(e.position == -1){
e.position = rndPosition(e.radius);
if(e.position == -1) continue;
else e.fadeState = 0;
}
// apply velocity e.position.x += e.velocity.x * deltaTime *0.1; e.position.y += e.velocity.y * deltaTime;
// despawn if((time - e.spawnTime) / 1000 >= e.lifetime) e.fadeState = 1;
e.rotation += deltaTime * 0.1;
switch(e.fadeState){ case 0: if(e.alpha < 1.0) e.alpha += fadeSpeed * deltaTime; if(e.alpha >= 1.0){ e.alpha = 1.0; e.fadeState = -1; } break; case 1: if(e.alpha > 0.0) e.alpha -= fadeSpeed * deltaTime; if(e.alpha <= 0.0){ e.enabled = false; alive--; if(alive == 0){ particles = [];canvas.parentNode.removeChild(canvas); } } break; }
// render c.globalAlpha = e.alpha * 0.2; c.translate(e.position.x, e.position.y); c.rotate(e.rotation); drawParticle(e); c.rotate(e.rotation * -1); c.translate(-e.position.x, -e.position.y); } }
function drawParticle(e){
c.fillStyle = e.color;
c.fillRect(-e.radius/2,-e.radius/2/2, e.radius, e.radius/2);
}
function rnd(min, max) { return Math.floor(Math.random() * (max - min + 1) ) + min; }
function dist(pos1, pos2){ var a = pos1.x - pos2.x; var b = pos1.y - pos2.y; return Math.sqrt(a*a + b*b); }
function clamp(v, min, max){ return v < min ? min : v > max ? max : v; }
loop(); });