1var confetti = { 2 maxCount: 150, //set max confetti count 3 speed: 2, //set the particle animation speed 4 frameInterval: 15, //the confetti animation frame interval in milliseconds 5 alpha: 1.0, //the alpha opacity of the confetti (between 0 and 1, where 1 is opaque and 0 is invisible) 6 gradient: false, //whether to use gradients for the confetti particles 7 start: null, //call to start confetti animation (with optional timeout in milliseconds, and optional min and max random confetti count) 8 stop: null, //call to stop adding confetti 9 toggle: null, //call to start or stop the confetti animation depending on whether it's already running 10 pause: null, //call to freeze confetti animation 11 resume: null, //call to unfreeze confetti animation 12 togglePause: null, //call to toggle whether the confetti animation is paused 13 remove: null, //call to stop the confetti animation and remove all confetti immediately 14 isPaused: null, //call and returns true or false depending on whether the confetti animation is paused 15 isRunning: null //call and returns true or false depending on whether the animation is running 16}; 17 18(function() { 19 confetti.start = startConfetti; 20 confetti.stop = stopConfetti; 21 confetti.toggle = toggleConfetti; 22 confetti.pause = pauseConfetti; 23 confetti.resume = resumeConfetti; 24 confetti.togglePause = toggleConfettiPause; 25 confetti.isPaused = isConfettiPaused; 26 confetti.remove = removeConfetti; 27 confetti.isRunning = isConfettiRunning; 28 var supportsAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame; 29 var colors = ["rgba(30,144,255,", "rgba(107,142,35,", "rgba(255,215,0,", "rgba(255,192,203,", "rgba(106,90,205,", "rgba(173,216,230,", "rgba(238,130,238,", "rgba(152,251,152,", "rgba(70,130,180,", "rgba(244,164,96,", "rgba(210,105,30,", "rgba(220,20,60,"]; 30 var streamingConfetti = false; 31 var animationTimer = null; 32 var pause = false; 33 var lastFrameTime = Date.now(); 34 var particles = []; 35 var waveAngle = 0; 36 var context = null; 37 38 function resetParticle(particle, width, height) { 39 particle.color = colors[(Math.random() * colors.length) | 0] + (confetti.alpha + ")"); 40 particle.color2 = colors[(Math.random() * colors.length) | 0] + (confetti.alpha + ")"); 41 particle.x = Math.random() * width; 42 particle.y = Math.random() * height - height; 43 particle.diameter = Math.random() * 10 + 5; 44 particle.tilt = Math.random() * 10 - 10; 45 particle.tiltAngleIncrement = Math.random() * 0.07 + 0.05; 46 particle.tiltAngle = Math.random() * Math.PI; 47 return particle; 48 } 49 50 function toggleConfettiPause() { 51 if (pause) 52 resumeConfetti(); 53 else 54 pauseConfetti(); 55 } 56 57 function isConfettiPaused() { 58 return pause; 59 } 60 61 function pauseConfetti() { 62 pause = true; 63 } 64 65 function resumeConfetti() { 66 pause = false; 67 runAnimation(); 68 } 69 70 function runAnimation() { 71 if (pause) 72 return; 73 else if (particles.length === 0) { 74 context.clearRect(0, 0, window.innerWidth, window.innerHeight); 75 animationTimer = null; 76 } else { 77 var now = Date.now(); 78 var delta = now - lastFrameTime; 79 if (!supportsAnimationFrame || delta > confetti.frameInterval) { 80 context.clearRect(0, 0, window.innerWidth, window.innerHeight); 81 updateParticles(); 82 drawParticles(context); 83 lastFrameTime = now - (delta % confetti.frameInterval); 84 } 85 animationTimer = requestAnimationFrame(runAnimation); 86 } 87 } 88 89 function startConfetti(timeout, min, max) { 90 var width = window.innerWidth; 91 var height = window.innerHeight; 92 window.requestAnimationFrame = (function() { 93 return window.requestAnimationFrame || 94 window.webkitRequestAnimationFrame || 95 window.mozRequestAnimationFrame || 96 window.oRequestAnimationFrame || 97 window.msRequestAnimationFrame || 98 function (callback) { 99 return window.setTimeout(callback, confetti.frameInterval); 100 }; 101 })(); 102 var canvas = document.getElementById("confetti-canvas"); 103 if (canvas === null) { 104 canvas = document.createElement("canvas"); 105 canvas.setAttribute("id", "confetti-canvas"); 106 canvas.setAttribute("style", "display:block;z-index:999999;pointer-events:none;position:fixed;top:0"); 107 document.body.prepend(canvas); 108 canvas.width = width; 109 canvas.height = height; 110 window.addEventListener("resize", function() { 111 canvas.width = window.innerWidth; 112 canvas.height = window.innerHeight; 113 }, true);
114 context = canvas.getContext("2d"); 115 } else if (context === null) 116 context = canvas.getContext("2d"); 117 var count = confetti.maxCount; 118 if (min) { 119 if (max) { 120 if (min == max) 121 count = particles.length + max; 122 else { 123 if (min > max) { 124 var temp = min; 125 min = max; 126 max = temp; 127 } 128 count = particles.length + ((Math.random() * (max - min) + min) | 0); 129 } 130 } else 131 count = particles.length + min; 132 } else if (max) 133 count = particles.length + max; 134 while (particles.length < count) 135 particles.push(resetParticle({}, width, height)); 136 streamingConfetti = true; 137 pause = false; 138 runAnimation(); 139 if (timeout) { 140 window.setTimeout(stopConfetti, timeout); 141 } 142 } 143 144 function stopConfetti() { 145 streamingConfetti = false; 146 } 147 148 function removeConfetti() { 149 stop(); 150 pause = false; 151 particles = []; 152 } 153 154 function toggleConfetti() { 155 if (streamingConfetti) 156 stopConfetti(); 157 else 158 startConfetti(); 159 } 160 161 function isConfettiRunning() { 162 return streamingConfetti; 163 } 164 165 function drawParticles(context) { 166 var particle; 167 var x, y, x2, y2; 168 for (var i = 0; i < particles.length; i++) { 169 particle = particles[i]; 170 context.beginPath(); 171 context.lineWidth = particle.diameter; 172 x2 = particle.x + particle.tilt; 173 x = x2 + particle.diameter / 2; 174 y2 = particle.y + particle.tilt + particle.diameter / 2; 175 if (confetti.gradient) { 176 var gradient = context.createLinearGradient(x, particle.y, x2, y2); 177 gradient.addColorStop("0", particle.color); 178 gradient.addColorStop("1.0", particle.color2); 179 context.strokeStyle = gradient; 180 } else 181 context.strokeStyle = particle.color; 182 context.moveTo(x, particle.y); 183 context.lineTo(x2, y2); 184 context.stroke(); 185 } 186 } 187 188 function updateParticles() { 189 var width = window.innerWidth; 190 var height = window.innerHeight; 191 var particle; 192 waveAngle += 0.01; 193 for (var i = 0; i < particles.length; i++) { 194 particle = particles[i]; 195 if (!streamingConfetti && particle.y < -15) 196 particle.y = height + 100; 197 else { 198 particle.tiltAngle += particle.tiltAngleIncrement; 199 particle.x += Math.sin(waveAngle) - 0.5; 200 particle.y += (Math.cos(waveAngle) + particle.diameter + confetti.speed) * 0.5; 201 particle.tilt = Math.sin(particle.tiltAngle) * 15; 202 } 203 if (particle.x > width + 20 || particle.x < -20 || particle.y > height) { 204 if (streamingConfetti && particles.length <= confetti.maxCount) 205 resetParticle(particle, width, height); 206 else { 207 particles.splice(i, 1); 208 i--; 209 } 210 } 211 } 212 } 213})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.