Confetti aw yeah
authorCameron Ball <cameron@moodle.com>
Wed, 25 Mar 2020 06:57:27 +0000 (14:57 +0800)
committerCameron Ball <cameron@moodle.com>
Wed, 25 Mar 2020 06:57:27 +0000 (14:57 +0800)
index.html
js/confetti.js [new file with mode: 0644]
js/confetti.min.js [new file with mode: 0644]

index 0b2fb99..5a14ebe 100644 (file)
@@ -7,6 +7,7 @@
           href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/styles/atom-one-dark.min.css">
     <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/highlight.min.js"></script>
     <script>hljs.initHighlightingOnLoad();</script>
+    <script src="js/confetti.min.js"></script>
     <title>Wide-Eyed Crazy Functional Programming</title>
     <style>
      body {
@@ -1234,7 +1235,7 @@ threeFs = repeat("f").substr(0,3);
  }, 250);
 
  urlParts = document.URL.split('#');
- window.console.log(urlParts);
+
  var currentSlide = urlParts.length > 1 ? urlParts[1] : 0;
  var bc = new BroadcastChannel('test_channel');
  document.getElementById('slide-' + currentSlide).style.display = 'block';
@@ -1277,6 +1278,12 @@ threeFs = repeat("f").substr(0,3);
          }
 
      }
+
+     if (currentSlide == 1 || currentSlide == 63) {
+         confetti.start();
+     } else {
+         confetti.stop();
+     }
  }
 
 
diff --git a/js/confetti.js b/js/confetti.js
new file mode 100644 (file)
index 0000000..a24804b
--- /dev/null
@@ -0,0 +1,213 @@
+var confetti = {\r
+       maxCount: 150,          //set max confetti count\r
+       speed: 2,                       //set the particle animation speed\r
+       frameInterval: 15,      //the confetti animation frame interval in milliseconds\r
+       alpha: 1.0,                     //the alpha opacity of the confetti (between 0 and 1, where 1 is opaque and 0 is invisible)\r
+       gradient: false,        //whether to use gradients for the confetti particles\r
+       start: null,            //call to start confetti animation (with optional timeout in milliseconds, and optional min and max random confetti count)\r
+       stop: null,                     //call to stop adding confetti\r
+       toggle: null,           //call to start or stop the confetti animation depending on whether it's already running\r
+       pause: null,            //call to freeze confetti animation\r
+       resume: null,           //call to unfreeze confetti animation\r
+       togglePause: null,      //call to toggle whether the confetti animation is paused\r
+       remove: null,           //call to stop the confetti animation and remove all confetti immediately\r
+       isPaused: null,         //call and returns true or false depending on whether the confetti animation is paused\r
+       isRunning: null         //call and returns true or false depending on whether the animation is running\r
+};\r
+\r
+(function() {\r
+       confetti.start = startConfetti;\r
+       confetti.stop = stopConfetti;\r
+       confetti.toggle = toggleConfetti;\r
+       confetti.pause = pauseConfetti;\r
+       confetti.resume = resumeConfetti;\r
+       confetti.togglePause = toggleConfettiPause;\r
+       confetti.isPaused = isConfettiPaused;\r
+       confetti.remove = removeConfetti;\r
+       confetti.isRunning = isConfettiRunning;\r
+       var supportsAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame;\r
+       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,"];\r
+       var streamingConfetti = false;\r
+       var animationTimer = null;\r
+       var pause = false;\r
+       var lastFrameTime = Date.now();\r
+       var particles = [];\r
+       var waveAngle = 0;\r
+       var context = null;\r
+\r
+       function resetParticle(particle, width, height) {\r
+               particle.color = colors[(Math.random() * colors.length) | 0] + (confetti.alpha + ")");\r
+               particle.color2 = colors[(Math.random() * colors.length) | 0] + (confetti.alpha + ")");\r
+               particle.x = Math.random() * width;\r
+               particle.y = Math.random() * height - height;\r
+               particle.diameter = Math.random() * 10 + 5;\r
+               particle.tilt = Math.random() * 10 - 10;\r
+               particle.tiltAngleIncrement = Math.random() * 0.07 + 0.05;\r
+               particle.tiltAngle = Math.random() * Math.PI;\r
+               return particle;\r
+       }\r
+\r
+       function toggleConfettiPause() {\r
+               if (pause)\r
+                       resumeConfetti();\r
+               else\r
+                       pauseConfetti();\r
+       }\r
+\r
+       function isConfettiPaused() {\r
+               return pause;\r
+       }\r
+\r
+       function pauseConfetti() {\r
+               pause = true;\r
+       }\r
+\r
+       function resumeConfetti() {\r
+               pause = false;\r
+               runAnimation();\r
+       }\r
+\r
+       function runAnimation() {\r
+               if (pause)\r
+                       return;\r
+               else if (particles.length === 0) {\r
+                       context.clearRect(0, 0, window.innerWidth, window.innerHeight);\r
+                       animationTimer = null;\r
+               } else {\r
+                       var now = Date.now();\r
+                       var delta = now - lastFrameTime;\r
+                       if (!supportsAnimationFrame || delta > confetti.frameInterval) {\r
+                               context.clearRect(0, 0, window.innerWidth, window.innerHeight);\r
+                               updateParticles();\r
+                               drawParticles(context);\r
+                               lastFrameTime = now - (delta % confetti.frameInterval);\r
+                       }\r
+                       animationTimer = requestAnimationFrame(runAnimation);\r
+               }\r
+       }\r
+\r
+       function startConfetti(timeout, min, max) {\r
+               var width = window.innerWidth;\r
+               var height = window.innerHeight;\r
+               window.requestAnimationFrame = (function() {\r
+                       return window.requestAnimationFrame ||\r
+                               window.webkitRequestAnimationFrame ||\r
+                               window.mozRequestAnimationFrame ||\r
+                               window.oRequestAnimationFrame ||\r
+                               window.msRequestAnimationFrame ||\r
+                               function (callback) {\r
+                                       return window.setTimeout(callback, confetti.frameInterval);\r
+                               };\r
+               })();\r
+               var canvas = document.getElementById("confetti-canvas");\r
+               if (canvas === null) {\r
+                       canvas = document.createElement("canvas");\r
+                       canvas.setAttribute("id", "confetti-canvas");\r
+                       canvas.setAttribute("style", "display:block;z-index:999999;pointer-events:none;position:fixed;top:0");\r
+                       document.body.prepend(canvas);\r
+                       canvas.width = width;\r
+                       canvas.height = height;\r
+                       window.addEventListener("resize", function() {\r
+                               canvas.width = window.innerWidth;\r
+                               canvas.height = window.innerHeight;\r
+                       }, true);\r
+                       context = canvas.getContext("2d");\r
+               } else if (context === null)\r
+                       context = canvas.getContext("2d");\r
+               var count = confetti.maxCount;\r
+               if (min) {\r
+                       if (max) {\r
+                               if (min == max)\r
+                                       count = particles.length + max;\r
+                               else {\r
+                                       if (min > max) {\r
+                                               var temp = min;\r
+                                               min = max;\r
+                                               max = temp;\r
+                                       }\r
+                                       count = particles.length + ((Math.random() * (max - min) + min) | 0);\r
+                               }\r
+                       } else\r
+                               count = particles.length + min;\r
+               } else if (max)\r
+                       count = particles.length + max;\r
+               while (particles.length < count)\r
+                       particles.push(resetParticle({}, width, height));\r
+               streamingConfetti = true;\r
+               pause = false;\r
+               runAnimation();\r
+               if (timeout) {\r
+                       window.setTimeout(stopConfetti, timeout);\r
+               }\r
+       }\r
+\r
+       function stopConfetti() {\r
+               streamingConfetti = false;\r
+       }\r
+\r
+       function removeConfetti() {\r
+               stop();\r
+               pause = false;\r
+               particles = [];\r
+       }\r
+\r
+       function toggleConfetti() {\r
+               if (streamingConfetti)\r
+                       stopConfetti();\r
+               else\r
+                       startConfetti();\r
+       }\r
+       \r
+       function isConfettiRunning() {\r
+               return streamingConfetti;\r
+       }\r
+\r
+       function drawParticles(context) {\r
+               var particle;\r
+               var x, y, x2, y2;\r
+               for (var i = 0; i < particles.length; i++) {\r
+                       particle = particles[i];\r
+                       context.beginPath();\r
+                       context.lineWidth = particle.diameter;\r
+                       x2 = particle.x + particle.tilt;\r
+                       x = x2 + particle.diameter / 2;\r
+                       y2 = particle.y + particle.tilt + particle.diameter / 2;\r
+                       if (confetti.gradient) {\r
+                               var gradient = context.createLinearGradient(x, particle.y, x2, y2);\r
+                               gradient.addColorStop("0", particle.color);\r
+                               gradient.addColorStop("1.0", particle.color2);\r
+                               context.strokeStyle = gradient;\r
+                       } else\r
+                               context.strokeStyle = particle.color;\r
+                       context.moveTo(x, particle.y);\r
+                       context.lineTo(x2, y2);\r
+                       context.stroke();\r
+               }\r
+       }\r
+\r
+       function updateParticles() {\r
+               var width = window.innerWidth;\r
+               var height = window.innerHeight;\r
+               var particle;\r
+               waveAngle += 0.01;\r
+               for (var i = 0; i < particles.length; i++) {\r
+                       particle = particles[i];\r
+                       if (!streamingConfetti && particle.y < -15)\r
+                               particle.y = height + 100;\r
+                       else {\r
+                               particle.tiltAngle += particle.tiltAngleIncrement;\r
+                               particle.x += Math.sin(waveAngle) - 0.5;\r
+                               particle.y += (Math.cos(waveAngle) + particle.diameter + confetti.speed) * 0.5;\r
+                               particle.tilt = Math.sin(particle.tiltAngle) * 15;\r
+                       }\r
+                       if (particle.x > width + 20 || particle.x < -20 || particle.y > height) {\r
+                               if (streamingConfetti && particles.length <= confetti.maxCount)\r
+                                       resetParticle(particle, width, height);\r
+                               else {\r
+                                       particles.splice(i, 1);\r
+                                       i--;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+})();\r
diff --git a/js/confetti.min.js b/js/confetti.min.js
new file mode 100644 (file)
index 0000000..e19d22c
--- /dev/null
@@ -0,0 +1 @@
+var confetti={maxCount:150,speed:2,frameInterval:15,alpha:1,gradient:!1,start:null,stop:null,toggle:null,pause:null,resume:null,togglePause:null,remove:null,isPaused:null,isRunning:null};!function(){confetti.start=s,confetti.stop=w,confetti.toggle=function(){e?w():s()},confetti.pause=u,confetti.resume=m,confetti.togglePause=function(){i?m():u()},confetti.isPaused=function(){return i},confetti.remove=function(){stop(),i=!1,a=[]},confetti.isRunning=function(){return e};var t=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame,n=["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,"],e=!1,i=!1,o=Date.now(),a=[],r=0,l=null;function d(t,e,i){return t.color=n[Math.random()*n.length|0]+(confetti.alpha+")"),t.color2=n[Math.random()*n.length|0]+(confetti.alpha+")"),t.x=Math.random()*e,t.y=Math.random()*i-i,t.diameter=10*Math.random()+5,t.tilt=10*Math.random()-10,t.tiltAngleIncrement=.07*Math.random()+.05,t.tiltAngle=Math.random()*Math.PI,t}function u(){i=!0}function m(){i=!1,c()}function c(){if(!i)if(0===a.length)l.clearRect(0,0,window.innerWidth,window.innerHeight),null;else{var n=Date.now(),u=n-o;(!t||u>confetti.frameInterval)&&(l.clearRect(0,0,window.innerWidth,window.innerHeight),function(){var t,n=window.innerWidth,i=window.innerHeight;r+=.01;for(var o=0;o<a.length;o++)t=a[o],!e&&t.y<-15?t.y=i+100:(t.tiltAngle+=t.tiltAngleIncrement,t.x+=Math.sin(r)-.5,t.y+=.5*(Math.cos(r)+t.diameter+confetti.speed),t.tilt=15*Math.sin(t.tiltAngle)),(t.x>n+20||t.x<-20||t.y>i)&&(e&&a.length<=confetti.maxCount?d(t,n,i):(a.splice(o,1),o--))}(),function(t){for(var n,e,i,o,r=0;r<a.length;r++){if(n=a[r],t.beginPath(),t.lineWidth=n.diameter,i=n.x+n.tilt,e=i+n.diameter/2,o=n.y+n.tilt+n.diameter/2,confetti.gradient){var l=t.createLinearGradient(e,n.y,i,o);l.addColorStop("0",n.color),l.addColorStop("1.0",n.color2),t.strokeStyle=l}else t.strokeStyle=n.color;t.moveTo(e,n.y),t.lineTo(i,o),t.stroke()}}(l),o=n-u%confetti.frameInterval),requestAnimationFrame(c)}}function s(t,n,o){var r=window.innerWidth,u=window.innerHeight;window.requestAnimationFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,confetti.frameInterval)};var m=document.getElementById("confetti-canvas");null===m?((m=document.createElement("canvas")).setAttribute("id","confetti-canvas"),m.setAttribute("style","display:block;z-index:999999;pointer-events:none;position:fixed;top:0"),document.body.prepend(m),m.width=r,m.height=u,window.addEventListener("resize",function(){m.width=window.innerWidth,m.height=window.innerHeight},!0),l=m.getContext("2d")):null===l&&(l=m.getContext("2d"));var s=confetti.maxCount;if(n)if(o)if(n==o)s=a.length+o;else{if(n>o){var f=n;n=o,o=f}s=a.length+(Math.random()*(o-n)+n|0)}else s=a.length+n;else o&&(s=a.length+o);for(;a.length<s;)a.push(d({},r,u));e=!0,i=!1,c(),t&&window.setTimeout(w,t)}function w(){e=!1}}();