var fernetjs = {}; fernetjs.config = { maxParticulas: [50, 200, 50], dibujarPoligono: false }; fernetjs.imagenes = {}; fernetjs.imagenes.fondo = new Image(); fernetjs.imagenes.santa = new Image(); fernetjs.navidad = (function(){ var reqAnimId, lastTime = Date.now(), time = 0, canvas, contexto, segmentos= [[99,291],[120,240],[156,218],[198,206],[204,171],[220,140],[237,106],[270,94],[307,108],[328,171],[342,186],[338,232],[357,241],[372,258],[383,282],[390,297],[390,237],[439,230],[446,220],[491,228],[520,227],[532,339]]; particulas = [[], [], []]; function crearParticulas(indice){ var max = fernetjs.config.maxParticulas[indice]; var ps = particulas[indice]; if(max > ps.length){ var x = Math.floor((Math.random()*canvas.width)); ps.push({ x: x, y: -Math.floor((Math.random()*400)+20), r: Math.floor((Math.random()*5)+1), vx: 0, vy: Math.floor((Math.random()*20)+10), initX: x, sinTime: Math.floor((Math.random()*7000)+3000), amp: Math.floor((Math.random()*10)+1), opacity: Math.floor((Math.random()*10)+5)/10 }); } } function actualizarParticulas(dt, indice){ var ps = particulas[indice]; for(var i=0; i < ps.length; i++){ if (ps[i].colision <= 0 || !ps[i].colision){ ps[i].x = ps[i].amp * Math.sin(time * 2 * Math.PI / ps[i].sinTime) + ps[i].initX; ps[i].y += ps[i].vy * dt; if (ps[i].y + ps[i].r > canvas.height){ ps.splice(i, 1); } else if(indice === 1 && !ps[i].colision && colisionSegmentos(ps[i])){ ps[i].colision = 20; ps[i].initX = ps[i].x; } } else { ps[i].colision -= dt; } } } function colisionSegmentos(particula){ var c = false; var cantVertices = segmentos.length; for(var i=0, j=cantVertices-1; i<cantVertices; j=i++) { if ((( segmentos[i][1] > particula.y) != ( segmentos[j][1] > particula.y )) && (particula.x < (segmentos[j][0]-segmentos[i][0]) * (particula.y-segmentos[i][1]) / ( segmentos[j][1]-segmentos[i][1]) + segmentos[i][0])) { c = !c; } } return c; } function actualizar(dt) { for (var i=0; i <=2; i++){ crearParticulas(i); actualizarParticulas(dt, i); } } function dibujarParticulas(indice){ var ps = particulas[indice]; for(var i=0; i<ps.length; i++){ contexto.beginPath(); contexto.arc(ps[i].x, ps[i].y, ps[i].r, 0, 2 * Math.PI, false); contexto.fillStyle = 'rgba(255,255,255,' + ps[i].opacity + ')'; contexto.fill(); } } function dibujar() { contexto.clearRect(0, 0, canvas.width, canvas.height); contexto.drawImage(fernetjs.imagenes.fondo, 0, 0); dibujarParticulas(0); contexto.drawImage(fernetjs.imagenes.santa, 0, 0); dibujarParticulas(1); if (fernetjs.config.dibujarPoligono){ // segmentos contexto.save(); contexto.beginPath(); contexto.moveTo(segmentos[0][0], segmentos[0][1]); for(var i=1; i<segmentos.length; i++){ contexto.lineTo(segmentos[i][0], segmentos[i][1]); } contexto.lineWidth = 5; contexto.strokeStyle = 'rgb(255,0,255)'; contexto.stroke(); contexto.restore(); } dibujarParticulas(2); } function iniciarCanvas() { canvas = document.getElementById('canvas'); if (canvas.getContext){ contexto = canvas.getContext('2d'); } else throw new Error("canvas no soportado!"); } function loop(){ var now = Date.now(); var delta = now - lastTime; lastTime = now; time += delta; actualizar(delta/1000); dibujar(); reqAnimId = window.requestAnimationFrame(loop); } return { iniciar: function() { if (!canvas) iniciarCanvas(); if(reqAnimId) this.detener(); loop(); }, detener: function() { window.cancelAnimationFrame(reqAnimId); reqAnimId = 0; } } })(); var carga = 0; fernetjs.imagenes.fondo.onload = function() { carga++; iniciar(); }; fernetjs.imagenes.santa.onload = function() { carga++; iniciar(); }; fernetjs.imagenes.fondo.src = 'http://fernetjs.com/wp-content/uploads/2013/12/bg.png'; fernetjs.imagenes.santa.src = 'http://fernetjs.com/wp-content/uploads/2013/12/santa.png'; function iniciar(){ if (carga === 2) { fernetjs.navidad.iniciar(); } } //detener: //fernetjs.navidad.detener(); $("#debug").on("click", function(){ fernetjs.config.dibujarPoligono = !fernetjs.config.dibujarPoligono; }); /* $("#canvas").on("click", function(e){ var offset = $(e.target).offset(); var pos = { x: e.pageX - offset.left, y: e.pageY - offset.top }; $("#coords").append(",[" + pos.x + "," + pos.y + "]"); }); */
<a id="debug" href="#">mostrar/ocultar segmentos</a> <br/> <canvas id="canvas" width="600" height="600"></canvas> <label id="coords"></label>
canvas { border: solid 1px silver; background-color: black; }