SHARE
TWEET

Untitled

a guest Nov 21st, 2019 80 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var retina = window.devicePixelRatio,
  2.  
  3.     // Math shorthands
  4.     PI = Math.PI,
  5.     sqrt = Math.sqrt,
  6.     round = Math.round,
  7.     random = Math.random,
  8.     cos = Math.cos,
  9.     sin = Math.sin,
  10.  
  11.     // Local WindowAnimationTiming interface
  12.     rAF = window.requestAnimationFrame,
  13.     cAF = window.cancelAnimationFrame || window.cancelRequestAnimationFrame,
  14.     _now = Date.now || function () {return new Date().getTime();};
  15.  
  16. // Local WindowAnimationTiming interface polyfill
  17. (function (w) {
  18.     /**
  19.      * Fallback implementation.
  20.      */
  21.     var prev = _now();
  22.     function fallback(fn) {
  23.         var curr = _now();
  24.         var ms = Math.max(0, 16 - (curr - prev));
  25.         var req = setTimeout(fn, ms);
  26.         prev = curr;
  27.         return req;
  28.     }
  29.  
  30.     /**
  31.      * Cancel.
  32.      */
  33.     var cancel = w.cancelAnimationFrame
  34.         || w.webkitCancelAnimationFrame
  35.         || w.clearTimeout;
  36.  
  37.     rAF = w.requestAnimationFrame
  38.         || w.webkitRequestAnimationFrame
  39.         || fallback;
  40.  
  41.     cAF = function(id){
  42.         cancel.call(w, id);
  43.     };
  44. }(window));
  45.  
  46. document.addEventListener("DOMContentLoaded", function() {
  47.     var speed = 50,
  48.         duration = (1.0 / speed),
  49.         confettiRibbonCount = 11,
  50.         ribbonPaperCount = 30,
  51.         ribbonPaperDist = 8.0,
  52.         ribbonPaperThick = 8.0,
  53.         confettiPaperCount = 95,
  54.         DEG_TO_RAD = PI / 180,
  55.         RAD_TO_DEG = 180 / PI,
  56.         colors = [
  57.             ["#df0049", "#660671"],
  58.             ["#00e857", "#005291"],
  59.             ["#2bebbc", "#05798a"],
  60.             ["#ffd200", "#b06c00"]
  61.         ];
  62.  
  63.     function Vector2(_x, _y) {
  64.         this.x = _x, this.y = _y;
  65.         this.Length = function() {
  66.             return sqrt(this.SqrLength());
  67.         }
  68.         this.SqrLength = function() {
  69.             return this.x * this.x + this.y * this.y;
  70.         }
  71.         this.Add = function(_vec) {
  72.             this.x += _vec.x;
  73.             this.y += _vec.y;
  74.         }
  75.         this.Sub = function(_vec) {
  76.             this.x -= _vec.x;
  77.             this.y -= _vec.y;
  78.         }
  79.         this.Div = function(_f) {
  80.             this.x /= _f;
  81.             this.y /= _f;
  82.         }
  83.         this.Mul = function(_f) {
  84.             this.x *= _f;
  85.             this.y *= _f;
  86.         }
  87.         this.Normalize = function() {
  88.             var sqrLen = this.SqrLength();
  89.             if (sqrLen != 0) {
  90.                 var factor = 1.0 / sqrt(sqrLen);
  91.                 this.x *= factor;
  92.                 this.y *= factor;
  93.             }
  94.         }
  95.         this.Normalized = function() {
  96.             var sqrLen = this.SqrLength();
  97.             if (sqrLen != 0) {
  98.                 var factor = 1.0 / sqrt(sqrLen);
  99.                 return new Vector2(this.x * factor, this.y * factor);
  100.             }
  101.             return new Vector2(0, 0);
  102.         }
  103.     }
  104.     Vector2.Lerp = function(_vec0, _vec1, _t) {
  105.         return new Vector2((_vec1.x - _vec0.x) * _t + _vec0.x, (_vec1.y - _vec0.y) * _t + _vec0.y);
  106.     }
  107.     Vector2.Distance = function(_vec0, _vec1) {
  108.         return sqrt(Vector2.SqrDistance(_vec0, _vec1));
  109.     }
  110.     Vector2.SqrDistance = function(_vec0, _vec1) {
  111.         var x = _vec0.x - _vec1.x;
  112.         var y = _vec0.y - _vec1.y;
  113.         return (x * x + y * y + z * z);
  114.     }
  115.     Vector2.Scale = function(_vec0, _vec1) {
  116.         return new Vector2(_vec0.x * _vec1.x, _vec0.y * _vec1.y);
  117.     }
  118.     Vector2.Min = function(_vec0, _vec1) {
  119.         return new Vector2(Math.min(_vec0.x, _vec1.x), Math.min(_vec0.y, _vec1.y));
  120.     }
  121.     Vector2.Max = function(_vec0, _vec1) {
  122.         return new Vector2(Math.max(_vec0.x, _vec1.x), Math.max(_vec0.y, _vec1.y));
  123.     }
  124.     Vector2.ClampMagnitude = function(_vec0, _len) {
  125.         var vecNorm = _vec0.Normalized;
  126.         return new Vector2(vecNorm.x * _len, vecNorm.y * _len);
  127.     }
  128.     Vector2.Sub = function(_vec0, _vec1) {
  129.         return new Vector2(_vec0.x - _vec1.x, _vec0.y - _vec1.y, _vec0.z - _vec1.z);
  130.     }
  131.  
  132.     function EulerMass(_x, _y, _mass, _drag) {
  133.         this.position = new Vector2(_x, _y);
  134.         this.mass = _mass;
  135.         this.drag = _drag;
  136.         this.force = new Vector2(0, 0);
  137.         this.velocity = new Vector2(0, 0);
  138.         this.AddForce = function(_f) {
  139.             this.force.Add(_f);
  140.         }
  141.         this.Integrate = function(_dt) {
  142.             var acc = this.CurrentForce(this.position);
  143.             acc.Div(this.mass);
  144.             var posDelta = new Vector2(this.velocity.x, this.velocity.y);
  145.             posDelta.Mul(_dt);
  146.             this.position.Add(posDelta);
  147.             acc.Mul(_dt);
  148.             this.velocity.Add(acc);
  149.             this.force = new Vector2(0, 0);
  150.         }
  151.         this.CurrentForce = function(_pos, _vel) {
  152.             var totalForce = new Vector2(this.force.x, this.force.y);
  153.             var speed = this.velocity.Length();
  154.             var dragVel = new Vector2(this.velocity.x, this.velocity.y);
  155.             dragVel.Mul(this.drag * this.mass * speed);
  156.             totalForce.Sub(dragVel);
  157.             return totalForce;
  158.         }
  159.     }
  160.  
  161.     function ConfettiPaper(_x, _y) {
  162.         this.pos = new Vector2(_x, _y);
  163.         this.rotationSpeed = (random() * 600 + 800);
  164.         this.angle = DEG_TO_RAD * random() * 360;
  165.         this.rotation = DEG_TO_RAD * random() * 360;
  166.         this.cosA = 1.0;
  167.         this.size = 5.0;
  168.         this.oscillationSpeed = (random() * 1.5 + 0.5);
  169.         this.xSpeed = 40.0;
  170.         this.ySpeed = (random() * 60 + 50.0);
  171.         this.corners = new Array();
  172.         this.time = random();
  173.         var ci = round(random() * (colors.length - 1));
  174.         this.frontColor = colors[ci][0];
  175.         this.backColor = colors[ci][1];
  176.         for (var i = 0; i < 4; i++) {
  177.             var dx = cos(this.angle + DEG_TO_RAD * (i * 90 + 45));
  178.             var dy = sin(this.angle + DEG_TO_RAD * (i * 90 + 45));
  179.             this.corners[i] = new Vector2(dx, dy);
  180.         }
  181.         this.Update = function(_dt) {
  182.             this.time += _dt;
  183.             this.rotation += this.rotationSpeed * _dt;
  184.             this.cosA = cos(DEG_TO_RAD * this.rotation);
  185.             this.pos.x += cos(this.time * this.oscillationSpeed) * this.xSpeed * _dt
  186.             this.pos.y += this.ySpeed * _dt;
  187.             if (this.pos.y > ConfettiPaper.bounds.y) {
  188.                 this.pos.x = random() * ConfettiPaper.bounds.x;
  189.                 this.pos.y = 0;
  190.             }
  191.         }
  192.         this.Draw = function(_g) {
  193.             if (this.cosA > 0) {
  194.                 _g.fillStyle = this.frontColor;
  195.             } else {
  196.                 _g.fillStyle = this.backColor;
  197.             }
  198.             _g.beginPath();
  199.             _g.moveTo((this.pos.x + this.corners[0].x * this.size) * retina, (this.pos.y + this.corners[0].y * this.size * this.cosA) * retina);
  200.             for (var i = 1; i < 4; i++) {
  201.                 _g.lineTo((this.pos.x + this.corners[i].x * this.size) * retina, (this.pos.y + this.corners[i].y * this.size * this.cosA) * retina);
  202.             }
  203.             _g.closePath();
  204.             _g.fill();
  205.         }
  206.     }
  207.     ConfettiPaper.bounds = new Vector2(0, 0);
  208.  
  209.     function ConfettiRibbon(_x, _y, _count, _dist, _thickness, _angle, _mass, _drag) {
  210.         this.particleDist = _dist;
  211.         this.particleCount = _count;
  212.         this.particleMass = _mass;
  213.         this.particleDrag = _drag;
  214.         this.particles = new Array();
  215.         var ci = round(random() * (colors.length - 1));
  216.         this.frontColor = colors[ci][0];
  217.         this.backColor = colors[ci][1];
  218.         this.xOff = (cos(DEG_TO_RAD * _angle) * _thickness);
  219.         this.yOff = (sin(DEG_TO_RAD * _angle) * _thickness);
  220.         this.position = new Vector2(_x, _y);
  221.         this.prevPosition = new Vector2(_x, _y);
  222.         this.velocityInherit = (random() * 2 + 4);
  223.         this.time = random() * 100;
  224.         this.oscillationSpeed = (random() * 2 + 2);
  225.         this.oscillationDistance = (random() * 40 + 40);
  226.         this.ySpeed = (random() * 40 + 80);
  227.         for (var i = 0; i < this.particleCount; i++) {
  228.             this.particles[i] = new EulerMass(_x, _y - i * this.particleDist, this.particleMass, this.particleDrag);
  229.         }
  230.         this.Update = function(_dt) {
  231.             var i = 0;
  232.             this.time += _dt * this.oscillationSpeed;
  233.             this.position.y += this.ySpeed * _dt;
  234.             this.position.x += cos(this.time) * this.oscillationDistance * _dt;
  235.             this.particles[0].position = this.position;
  236.             var dX = this.prevPosition.x - this.position.x;
  237.             var dY = this.prevPosition.y - this.position.y;
  238.             var delta = sqrt(dX * dX + dY * dY);
  239.             this.prevPosition = new Vector2(this.position.x, this.position.y);
  240.             for (i = 1; i < this.particleCount; i++) {
  241.                 var dirP = Vector2.Sub(this.particles[i - 1].position, this.particles[i].position);
  242.                 dirP.Normalize();
  243.                 dirP.Mul((delta / _dt) * this.velocityInherit);
  244.                 this.particles[i].AddForce(dirP);
  245.             }
  246.             for (i = 1; i < this.particleCount; i++) {
  247.                 this.particles[i].Integrate(_dt);
  248.             }
  249.             for (i = 1; i < this.particleCount; i++) {
  250.                 var rp2 = new Vector2(this.particles[i].position.x, this.particles[i].position.y);
  251.                 rp2.Sub(this.particles[i - 1].position);
  252.                 rp2.Normalize();
  253.                 rp2.Mul(this.particleDist);
  254.                 rp2.Add(this.particles[i - 1].position);
  255.                 this.particles[i].position = rp2;
  256.             }
  257.             if (this.position.y > ConfettiRibbon.bounds.y + this.particleDist * this.particleCount) {
  258.                 this.Reset();
  259.             }
  260.         }
  261.         this.Reset = function() {
  262.             this.position.y = -random() * ConfettiRibbon.bounds.y;
  263.             this.position.x = random() * ConfettiRibbon.bounds.x;
  264.             this.prevPosition = new Vector2(this.position.x, this.position.y);
  265.             this.velocityInherit = random() * 2 + 4;
  266.             this.time = random() * 100;
  267.             this.oscillationSpeed = random() * 2.0 + 1.5;
  268.             this.oscillationDistance = (random() * 40 + 40);
  269.             this.ySpeed = random() * 40 + 80;
  270.             var ci = round(random() * (colors.length - 1));
  271.             this.frontColor = colors[ci][0];
  272.             this.backColor = colors[ci][1];
  273.             this.particles = new Array();
  274.             for (var i = 0; i < this.particleCount; i++) {
  275.                 this.particles[i] = new EulerMass(this.position.x, this.position.y - i * this.particleDist, this.particleMass, this.particleDrag);
  276.             }
  277.         }
  278.         this.Draw = function(_g) {
  279.             for (var i = 0; i < this.particleCount - 1; i++) {
  280.                 var p0 = new Vector2(this.particles[i].position.x + this.xOff, this.particles[i].position.y + this.yOff);
  281.                 var p1 = new Vector2(this.particles[i + 1].position.x + this.xOff, this.particles[i + 1].position.y + this.yOff);
  282.                 if (this.Side(this.particles[i].position.x, this.particles[i].position.y, this.particles[i + 1].position.x, this.particles[i + 1].position.y, p1.x, p1.y) < 0) {
  283.                     _g.fillStyle = this.frontColor;
  284.                     _g.strokeStyle = this.frontColor;
  285.                 } else {
  286.                     _g.fillStyle = this.backColor;
  287.                     _g.strokeStyle = this.backColor;
  288.                 }
  289.                 if (i == 0) {
  290.                     _g.beginPath();
  291.                     _g.moveTo(this.particles[i].position.x * retina, this.particles[i].position.y * retina);
  292.                     _g.lineTo(this.particles[i + 1].position.x * retina, this.particles[i + 1].position.y * retina);
  293.                     _g.lineTo(((this.particles[i + 1].position.x + p1.x) * 0.5) * retina, ((this.particles[i + 1].position.y + p1.y) * 0.5) * retina);
  294.                     _g.closePath();
  295.                     _g.stroke();
  296.                     _g.fill();
  297.                     _g.beginPath();
  298.                     _g.moveTo(p1.x * retina, p1.y * retina);
  299.                     _g.lineTo(p0.x * retina, p0.y * retina);
  300.                     _g.lineTo(((this.particles[i + 1].position.x + p1.x) * 0.5) * retina, ((this.particles[i + 1].position.y + p1.y) * 0.5) * retina);
  301.                     _g.closePath();
  302.                     _g.stroke();
  303.                     _g.fill();
  304.                 } else if (i == this.particleCount - 2) {
  305.                     _g.beginPath();
  306.                     _g.moveTo(this.particles[i].position.x * retina, this.particles[i].position.y * retina);
  307.                     _g.lineTo(this.particles[i + 1].position.x * retina, this.particles[i + 1].position.y * retina);
  308.                     _g.lineTo(((this.particles[i].position.x + p0.x) * 0.5) * retina, ((this.particles[i].position.y + p0.y) * 0.5) * retina);
  309.                     _g.closePath();
  310.                     _g.stroke();
  311.                     _g.fill();
  312.                     _g.beginPath();
  313.                     _g.moveTo(p1.x * retina, p1.y * retina);
  314.                     _g.lineTo(p0.x * retina, p0.y * retina);
  315.                     _g.lineTo(((this.particles[i].position.x + p0.x) * 0.5) * retina, ((this.particles[i].position.y + p0.y) * 0.5) * retina);
  316.                     _g.closePath();
  317.                     _g.stroke();
  318.                     _g.fill();
  319.                 } else {
  320.                     _g.beginPath();
  321.                     _g.moveTo(this.particles[i].position.x * retina, this.particles[i].position.y * retina);
  322.                     _g.lineTo(this.particles[i + 1].position.x * retina, this.particles[i + 1].position.y * retina);
  323.                     _g.lineTo(p1.x * retina, p1.y * retina);
  324.                     _g.lineTo(p0.x * retina, p0.y * retina);
  325.                     _g.closePath();
  326.                     _g.stroke();
  327.                     _g.fill();
  328.                 }
  329.             }
  330.         }
  331.         this.Side = function(x1, y1, x2, y2, x3, y3) {
  332.             return ((x1 - x2) * (y3 - y2) - (y1 - y2) * (x3 - x2));
  333.         }
  334.     }
  335.     ConfettiRibbon.bounds = new Vector2(0, 0);
  336.     confetti = {};
  337.     confetti.Context = function(id) {
  338.         var i = 0;
  339.         var canvas = document.getElementById(id);
  340.         var canvasParent = canvas.parentNode;
  341.         var canvasWidth = canvasParent.offsetWidth;
  342.         var canvasHeight = canvasParent.offsetHeight;
  343.         canvas.width = canvasWidth * retina;
  344.         canvas.height = canvasHeight * retina;
  345.         var context = canvas.getContext('2d');
  346.         var interval = null;
  347.         var confettiRibbons = new Array();
  348.         ConfettiRibbon.bounds = new Vector2(canvasWidth, canvasHeight);
  349.         for (i = 0; i < confettiRibbonCount; i++) {
  350.             confettiRibbons[i] = new ConfettiRibbon(random() * canvasWidth, -random() * canvasHeight * 2, ribbonPaperCount, ribbonPaperDist, ribbonPaperThick, 45, 1, 0.05);
  351.         }
  352.         var confettiPapers = new Array();
  353.         ConfettiPaper.bounds = new Vector2(canvasWidth, canvasHeight);
  354.         for (i = 0; i < confettiPaperCount; i++) {
  355.             confettiPapers[i] = new ConfettiPaper(random() * canvasWidth, random() * canvasHeight);
  356.         }
  357.         this.resize = function() {
  358.             canvasWidth = canvasParent.offsetWidth;
  359.             canvasHeight = canvasParent.offsetHeight;
  360.             canvas.width = canvasWidth * retina;
  361.             canvas.height = canvasHeight * retina;
  362.             ConfettiPaper.bounds = new Vector2(canvasWidth, canvasHeight);
  363.             ConfettiRibbon.bounds = new Vector2(canvasWidth, canvasHeight);
  364.         }
  365.         this.start = function() {
  366.             this.stop()
  367.             var context = this;
  368.             this.update();
  369.         }
  370.         this.stop = function() {
  371.             cAF(this.interval);
  372.         }
  373.         this.update = function() {
  374.             var i = 0;
  375.             context.clearRect(0, 0, canvas.width, canvas.height);
  376.             for (i = 0; i < confettiPaperCount; i++) {
  377.                 confettiPapers[i].Update(duration);
  378.                 confettiPapers[i].Draw(context);
  379.             }
  380.             for (i = 0; i < confettiRibbonCount; i++) {
  381.                 confettiRibbons[i].Update(duration);
  382.                 confettiRibbons[i].Draw(context);
  383.             }
  384.             this.interval = rAF(function() {
  385.                 confetti.update();
  386.             });
  387.         }
  388.     }
  389.     var confetti = new confetti.Context('confetti');
  390.     confetti.start();
  391.     window.addEventListener('resize', function(event){
  392.         confetti.resize();
  393.     });
  394. });
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top