document.addEventListener("DOMContentLoaded",function (ev) { var c = document.getElementById("fireworks"); if (!c || !c.getContext) return; var ctx = c.getContext("2d"); if (!ctx) return; var cH; var cW; var bgColor = srvModel.animationColors[0]; var animations = []; var colorPicker = (function() { var colors = srvModel.animationColors; var index = 0; function next() { index = index++ < colors.length-1 ? index : 0; return colors[index]; } function current() { return colors[index] } return { next: next, current: current } })(); function removeAnimation(animation) { var index = animations.indexOf(animation); if (index > -1) animations.splice(index, 1); } function calcPageFillRadius(x, y) { var l = Math.max(x - 0, cW - x); var h = Math.max(y - 0, cH - y); return Math.sqrt(Math.pow(l, 2) + Math.pow(h, 2)); } function handleEvent(e) { if (e.touches) { e.preventDefault(); e = e.touches[0]; } var currentColor = colorPicker.current(); var nextColor = colorPicker.next(); var targetR = calcPageFillRadius(e.pageX, e.pageY); var rippleSize = Math.min(200, (cW * .4)); var minCoverDuration = 750; var pageFill = new Circle({ x: e.pageX, y: e.pageY, r: 0, fill: nextColor }); var fillAnimation = anime({ targets: pageFill, r: targetR, duration: Math.max(targetR / 2 , minCoverDuration ), easing: "easeOutQuart", complete: function(){ bgColor = pageFill.fill; removeAnimation(fillAnimation); } }); var ripple = new Circle({ x: e.pageX, y: e.pageY, r: 0, fill: currentColor, stroke: { width: 3, color: currentColor }, opacity: 1 }); var rippleAnimation = anime({ targets: ripple, r: rippleSize, opacity: 0, easing: "easeOutExpo", duration: 900, complete: removeAnimation }); var particles = []; for (var i=0; i<32; i++) { var particle = new Circle({ x: e.pageX, y: e.pageY, fill: currentColor, r: anime.random(24, 48) }) particles.push(particle); } var particlesAnimation = anime({ targets: particles, x: function(particle){ return particle.x + anime.random(rippleSize, -rippleSize); }, y: function(particle){ return particle.y + anime.random(rippleSize * 1.15, -rippleSize * 1.15); }, r: 0, easing: "easeOutExpo", duration: anime.random(1000,1300), complete: removeAnimation }); animations.push(fillAnimation, rippleAnimation, particlesAnimation); } function extend(a, b){ for(var key in b) { if(b.hasOwnProperty(key)) { a[key] = b[key]; } } return a; } var Circle = function(opts) { extend(this, opts); } Circle.prototype.draw = function() { ctx.globalAlpha = this.opacity || 1; ctx.beginPath(); ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false); if (this.stroke) { ctx.strokeStyle = this.stroke.color; ctx.lineWidth = this.stroke.width; ctx.stroke(); } if (this.fill) { ctx.fillStyle = this.fill; ctx.fill(); } ctx.closePath(); ctx.globalAlpha = 1; } anime({ duration: Infinity, update: function() { ctx.fillStyle = bgColor; ctx.fillRect(0, 0, cW, cH); animations.forEach(function(anim) { anim.animatables.forEach(function(animatable) { animatable.target.draw(); }); }); } }); var resizeCanvas = function() { cW = window.innerWidth; cH = window.innerHeight; c.width = cW * devicePixelRatio; c.height = cH * devicePixelRatio; ctx.scale(devicePixelRatio, devicePixelRatio); }; (function init() { resizeCanvas(); window.addEventListener("resize", resizeCanvas); })(); window.fireworks = function(count = 0) { const elem = document.getElementById("fireworks"); elem.classList.remove("d-none"); var fauxClick = new Event("mousedown"); fauxClick.pageX = anime.random(0, cW); fauxClick.pageY = anime.random(0, cH); var middleSpaceX = cW * 0.6; var middleSpaceY = cH * 0.6; var middleSpaceX1 = middleSpaceX /2; var middleSpaceX2 = middleSpaceX1 + middleSpaceX; var middleSpaceY1 = middleSpaceY /2; var middleSpaceY2 = middleSpaceY1 + middleSpaceY; while(true){ if(fauxClick.pageX > middleSpaceX1 && fauxClick.pageX < middleSpaceX2){ fauxClick.pageX = anime.random( 0, cW ); continue; } if(fauxClick.pageY > middleSpaceY1 && fauxClick.pageY < middleSpaceY2){ fauxClick.pageY = anime.random( 0, cH ); continue; } break; } handleEvent(fauxClick); setTimeout(function () { if (count < 5) { fireworks(count + 1); } else { elem.classList.add("d-none"); } }, 750); }; });