在javascript函数上加载画布

时间:2015-12-31 10:05:09

标签: javascript

一旦我在这个页面上的时钟结束,我需要开始一个画布(id =" confetti")。一旦时钟结束并到达午夜,它将显示新年快乐,我想保留,但是我想要画布中的confetti开始,并且不自动加载?我猜测它可以使用"stop: function() {",但我不确定如何启动它?

任何想法都会非常有用。

I have a live version of it currently is here.

三江源。

<html>
    <head>
        <link rel="stylesheet" href="../compiled/flipclock.css">

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

        <script src="../compiled/flipclock.js"></script>
<style>
body {
background: black;
}

h1 {
font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
color: white;
font-size: 7em;
}
.flip-clock-divider.days,
.clock ul:nth-child(1),
.clock ul:nth-child(2),
.clock ul:nth-child(3)
{
    display: none;
}   

.flip-clock-divider hours,
.flip-clock-dot.top {
    top: 30px;
    display: none;
}
.flip-clock-divider hours,
.flip-clock-dot.bottom {
    top: 30px;
    display: none;
}

.flip-clock-divider .flip-clock-label {
color: white;}

.clock {
zoom:345%;
}

            #confetti{
                position: absolute;
                left: 0;
                top: 0;
                height: 100%;
                width: 100%;
            }

</style>
    </head>
    <body>

<canvas id="confetti" width="1" height="1""></canvas>

<script type="text/javascript">
            var retina = window.devicePixelRatio,

                // Math shorthands
                PI = Math.PI,
                sqrt = Math.sqrt,
                round = Math.round,
                random = Math.random,
                cos = Math.cos,
                sin = Math.sin,

                // Local WindowAnimationTiming interface
                rAF = window.requestAnimationFrame,
                cAF = window.cancelAnimationFrame || window.cancelRequestAnimationFrame;

            // Local WindowAnimationTiming interface polyfill
            (function (w) {
                /**
                * Fallback implementation.
                */
                var prev = new Date().getTime();
                function fallback(fn) {
                    var curr = _now();
                    var ms = Math.max(0, 16 - (curr - prev));
                    var req = setTimeout(fn, ms);
                    prev = curr;
                    return req;
                }

                /**
                * Cancel.
                */
                var cancel = w.cancelAnimationFrame
                    || w.webkitCancelAnimationFrame
                    || w.clearTimeout;

                rAF = w.requestAnimationFrame
                    || w.webkitRequestAnimationFrame
                    || fallback;

                cAF = function(id){
                    cancel.call(w, id);
                };
            }(window));

            document.addEventListener("DOMContentLoaded", function() {
                var speed = 50,
                    duration = (1.0 / speed),
                    confettiRibbonCount = 11,
                    ribbonPaperCount = 30,
                    ribbonPaperDist = 8.0,
                    ribbonPaperThick = 8.0,
                    confettiPaperCount = 95,
                    DEG_TO_RAD = PI / 180,
                    RAD_TO_DEG = 180 / PI,
                    colors = [
                        ["#df0049", "#660671"],
                        ["#00e857", "#005291"],
                        ["#2bebbc", "#05798a"],
                        ["#ffd200", "#b06c00"]
                    ];

                function Vector2(_x, _y) {
                    this.x = _x, this.y = _y;
                    this.Length = function() {
                        return sqrt(this.SqrLength());
                    }
                    this.SqrLength = function() {
                        return this.x * this.x + this.y * this.y;
                    }
                    this.Add = function(_vec) {
                        this.x += _vec.x;
                        this.y += _vec.y;
                    }
                    this.Sub = function(_vec) {
                        this.x -= _vec.x;
                        this.y -= _vec.y;
                    }
                    this.Div = function(_f) {
                        this.x /= _f;
                        this.y /= _f;
                    }
                    this.Mul = function(_f) {
                        this.x *= _f;
                        this.y *= _f;
                    }
                    this.Normalize = function() {
                        var sqrLen = this.SqrLength();
                        if (sqrLen != 0) {
                            var factor = 1.0 / sqrt(sqrLen);
                            this.x *= factor;
                            this.y *= factor;
                        }
                    }
                    this.Normalized = function() {
                        var sqrLen = this.SqrLength();
                        if (sqrLen != 0) {
                            var factor = 1.0 / sqrt(sqrLen);
                            return new Vector2(this.x * factor, this.y * factor);
                        }
                        return new Vector2(0, 0);
                    }
                }
                Vector2.Lerp = function(_vec0, _vec1, _t) {
                    return new Vector2((_vec1.x - _vec0.x) * _t + _vec0.x, (_vec1.y - _vec0.y) * _t + _vec0.y);
                }
                Vector2.Distance = function(_vec0, _vec1) {
                    return sqrt(Vector2.SqrDistance(_vec0, _vec1));
                }
                Vector2.SqrDistance = function(_vec0, _vec1) {
                    var x = _vec0.x - _vec1.x;
                    var y = _vec0.y - _vec1.y;
                    return (x * x + y * y + z * z);
                }
                Vector2.Scale = function(_vec0, _vec1) {
                    return new Vector2(_vec0.x * _vec1.x, _vec0.y * _vec1.y);
                }
                Vector2.Min = function(_vec0, _vec1) {
                    return new Vector2(Math.min(_vec0.x, _vec1.x), Math.min(_vec0.y, _vec1.y));
                }
                Vector2.Max = function(_vec0, _vec1) {
                    return new Vector2(Math.max(_vec0.x, _vec1.x), Math.max(_vec0.y, _vec1.y));
                }
                Vector2.ClampMagnitude = function(_vec0, _len) {
                    var vecNorm = _vec0.Normalized;
                    return new Vector2(vecNorm.x * _len, vecNorm.y * _len);
                }
                Vector2.Sub = function(_vec0, _vec1) {
                    return new Vector2(_vec0.x - _vec1.x, _vec0.y - _vec1.y, _vec0.z - _vec1.z);
                }

                function EulerMass(_x, _y, _mass, _drag) {
                    this.position = new Vector2(_x, _y);
                    this.mass = _mass;
                    this.drag = _drag;
                    this.force = new Vector2(0, 0);
                    this.velocity = new Vector2(0, 0);
                    this.AddForce = function(_f) {
                        this.force.Add(_f);
                    }
                    this.Integrate = function(_dt) {
                        var acc = this.CurrentForce(this.position);
                        acc.Div(this.mass);
                        var posDelta = new Vector2(this.velocity.x, this.velocity.y);
                        posDelta.Mul(_dt);
                        this.position.Add(posDelta);
                        acc.Mul(_dt);
                        this.velocity.Add(acc);
                        this.force = new Vector2(0, 0);
                    }
                    this.CurrentForce = function(_pos, _vel) {
                        var totalForce = new Vector2(this.force.x, this.force.y);
                        var speed = this.velocity.Length();
                        var dragVel = new Vector2(this.velocity.x, this.velocity.y);
                        dragVel.Mul(this.drag * this.mass * speed);
                        totalForce.Sub(dragVel);
                        return totalForce;
                    }
                }

                function ConfettiPaper(_x, _y) {
                    this.pos = new Vector2(_x, _y);
                    this.rotationSpeed = (random() * 600 + 800);
                    this.angle = DEG_TO_RAD * random() * 360;
                    this.rotation = DEG_TO_RAD * random() * 360;
                    this.cosA = 1.0;
                    this.size = 5.0;
                    this.oscillationSpeed = (random() * 1.5 + 0.5);
                    this.xSpeed = 40.0;
                    this.ySpeed = (random() * 60 + 50.0);
                    this.corners = new Array();
                    this.time = random();
                    var ci = round(random() * (colors.length - 1));
                    this.frontColor = colors[ci][0];
                    this.backColor = colors[ci][1];
                    for (var i = 0; i < 4; i++) {
                        var dx = cos(this.angle + DEG_TO_RAD * (i * 90 + 45));
                        var dy = sin(this.angle + DEG_TO_RAD * (i * 90 + 45));
                        this.corners[i] = new Vector2(dx, dy);
                    }
                    this.Update = function(_dt) {
                        this.time += _dt;
                        this.rotation += this.rotationSpeed * _dt;
                        this.cosA = cos(DEG_TO_RAD * this.rotation);
                        this.pos.x += cos(this.time * this.oscillationSpeed) * this.xSpeed * _dt
                        this.pos.y += this.ySpeed * _dt;
                        if (this.pos.y > ConfettiPaper.bounds.y) {
                            this.pos.x = random() * ConfettiPaper.bounds.x;
                            this.pos.y = 0;
                        }
                    }
                    this.Draw = function(_g) {
                        if (this.cosA > 0) {
                            _g.fillStyle = this.frontColor;
                        } else {
                            _g.fillStyle = this.backColor;
                        }
                        _g.beginPath();
                        _g.moveTo((this.pos.x + this.corners[0].x * this.size) * retina, (this.pos.y + this.corners[0].y * this.size * this.cosA) * retina);
                        for (var i = 1; i < 4; i++) {
                            _g.lineTo((this.pos.x + this.corners[i].x * this.size) * retina, (this.pos.y + this.corners[i].y * this.size * this.cosA) * retina);
                        }
                        _g.closePath();
                        _g.fill();
                    }
                }
                ConfettiPaper.bounds = new Vector2(0, 0);

                function ConfettiRibbon(_x, _y, _count, _dist, _thickness, _angle, _mass, _drag) {
                    this.particleDist = _dist;
                    this.particleCount = _count;
                    this.particleMass = _mass;
                    this.particleDrag = _drag;
                    this.particles = new Array();
                    var ci = round(random() * (colors.length - 1));
                    this.frontColor = colors[ci][0];
                    this.backColor = colors[ci][1];
                    this.xOff = (cos(DEG_TO_RAD * _angle) * _thickness);
                    this.yOff = (sin(DEG_TO_RAD * _angle) * _thickness);
                    this.position = new Vector2(_x, _y);
                    this.prevPosition = new Vector2(_x, _y);
                    this.velocityInherit = (random() * 2 + 4);
                    this.time = random() * 100;
                    this.oscillationSpeed = (random() * 2 + 2);
                    this.oscillationDistance = (random() * 40 + 40);
                    this.ySpeed = (random() * 40 + 80);
                    for (var i = 0; i < this.particleCount; i++) {
                        this.particles[i] = new EulerMass(_x, _y - i * this.particleDist, this.particleMass, this.particleDrag);
                    }
                    this.Update = function(_dt) {
                        var i = 0;
                        this.time += _dt * this.oscillationSpeed;
                        this.position.y += this.ySpeed * _dt;
                        this.position.x += cos(this.time) * this.oscillationDistance * _dt;
                        this.particles[0].position = this.position;
                        var dX = this.prevPosition.x - this.position.x;
                        var dY = this.prevPosition.y - this.position.y;
                        var delta = sqrt(dX * dX + dY * dY);
                        this.prevPosition = new Vector2(this.position.x, this.position.y);
                        for (i = 1; i < this.particleCount; i++) {
                            var dirP = Vector2.Sub(this.particles[i - 1].position, this.particles[i].position);
                            dirP.Normalize();
                            dirP.Mul((delta / _dt) * this.velocityInherit);
                            this.particles[i].AddForce(dirP);
                        }
                        for (i = 1; i < this.particleCount; i++) {
                            this.particles[i].Integrate(_dt);
                        }
                        for (i = 1; i < this.particleCount; i++) {
                            var rp2 = new Vector2(this.particles[i].position.x, this.particles[i].position.y);
                            rp2.Sub(this.particles[i - 1].position);
                            rp2.Normalize();
                            rp2.Mul(this.particleDist);
                            rp2.Add(this.particles[i - 1].position);
                            this.particles[i].position = rp2;
                        }
                        if (this.position.y > ConfettiRibbon.bounds.y + this.particleDist * this.particleCount) {
                            this.Reset();
                        }
                    }
                    this.Reset = function() {
                        this.position.y = -random() * ConfettiRibbon.bounds.y;
                        this.position.x = random() * ConfettiRibbon.bounds.x;
                        this.prevPosition = new Vector2(this.position.x, this.position.y);
                        this.velocityInherit = random() * 2 + 4;
                        this.time = random() * 100;
                        this.oscillationSpeed = random() * 2.0 + 1.5;
                        this.oscillationDistance = (random() * 40 + 40);
                        this.ySpeed = random() * 40 + 80;
                        var ci = round(random() * (colors.length - 1));
                        this.frontColor = colors[ci][0];
                        this.backColor = colors[ci][1];
                        this.particles = new Array();
                        for (var i = 0; i < this.particleCount; i++) {
                            this.particles[i] = new EulerMass(this.position.x, this.position.y - i * this.particleDist, this.particleMass, this.particleDrag);
                        }
                    }
                    this.Draw = function(_g) {
                        for (var i = 0; i < this.particleCount - 1; i++) {
                            var p0 = new Vector2(this.particles[i].position.x + this.xOff, this.particles[i].position.y + this.yOff);
                            var p1 = new Vector2(this.particles[i + 1].position.x + this.xOff, this.particles[i + 1].position.y + this.yOff);
                            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) {
                                _g.fillStyle = this.frontColor;
                                _g.strokeStyle = this.frontColor;
                            } else {
                                _g.fillStyle = this.backColor;
                                _g.strokeStyle = this.backColor;
                            }
                            if (i == 0) {
                                _g.beginPath();
                                _g.moveTo(this.particles[i].position.x * retina, this.particles[i].position.y * retina);
                                _g.lineTo(this.particles[i + 1].position.x * retina, this.particles[i + 1].position.y * retina);
                                _g.lineTo(((this.particles[i + 1].position.x + p1.x) * 0.5) * retina, ((this.particles[i + 1].position.y + p1.y) * 0.5) * retina);
                                _g.closePath();
                                _g.stroke();
                                _g.fill();
                                _g.beginPath();
                                _g.moveTo(p1.x * retina, p1.y * retina);
                                _g.lineTo(p0.x * retina, p0.y * retina);
                                _g.lineTo(((this.particles[i + 1].position.x + p1.x) * 0.5) * retina, ((this.particles[i + 1].position.y + p1.y) * 0.5) * retina);
                                _g.closePath();
                                _g.stroke();
                                _g.fill();
                            } else if (i == this.particleCount - 2) {
                                _g.beginPath();
                                _g.moveTo(this.particles[i].position.x * retina, this.particles[i].position.y * retina);
                                _g.lineTo(this.particles[i + 1].position.x * retina, this.particles[i + 1].position.y * retina);
                                _g.lineTo(((this.particles[i].position.x + p0.x) * 0.5) * retina, ((this.particles[i].position.y + p0.y) * 0.5) * retina);
                                _g.closePath();
                                _g.stroke();
                                _g.fill();
                                _g.beginPath();
                                _g.moveTo(p1.x * retina, p1.y * retina);
                                _g.lineTo(p0.x * retina, p0.y * retina);
                                _g.lineTo(((this.particles[i].position.x + p0.x) * 0.5) * retina, ((this.particles[i].position.y + p0.y) * 0.5) * retina);
                                _g.closePath();
                                _g.stroke();
                                _g.fill();
                            } else {
                                _g.beginPath();
                                _g.moveTo(this.particles[i].position.x * retina, this.particles[i].position.y * retina);
                                _g.lineTo(this.particles[i + 1].position.x * retina, this.particles[i + 1].position.y * retina);
                                _g.lineTo(p1.x * retina, p1.y * retina);
                                _g.lineTo(p0.x * retina, p0.y * retina);
                                _g.closePath();
                                _g.stroke();
                                _g.fill();
                            }
                        }
                    }
                    this.Side = function(x1, y1, x2, y2, x3, y3) {
                        return ((x1 - x2) * (y3 - y2) - (y1 - y2) * (x3 - x2));
                    }
                }
                ConfettiRibbon.bounds = new Vector2(0, 0);
                confetti = {};
                confetti.Context = function(id) {
                    var i = 0;
                    var canvas = document.getElementById(id);
                    var canvasParent = canvas.parentNode;
                    var canvasWidth = canvasParent.offsetWidth;
                    var canvasHeight = canvasParent.offsetHeight;
                    canvas.width = canvasWidth * retina;
                    canvas.height = canvasHeight * retina;
                    var context = canvas.getContext('2d');
                    var interval = null;
                    var confettiRibbons = new Array();
                    ConfettiRibbon.bounds = new Vector2(canvasWidth, canvasHeight);
                    for (i = 0; i < confettiRibbonCount; i++) {
                        confettiRibbons[i] = new ConfettiRibbon(random() * canvasWidth, -random() * canvasHeight * 2, ribbonPaperCount, ribbonPaperDist, ribbonPaperThick, 45, 1, 0.05);
                    }
                    var confettiPapers = new Array();
                    ConfettiPaper.bounds = new Vector2(canvasWidth, canvasHeight);
                    for (i = 0; i < confettiPaperCount; i++) {
                        confettiPapers[i] = new ConfettiPaper(random() * canvasWidth, random() * canvasHeight);
                    }
                    this.resize = function() {
                        canvasWidth = canvasParent.offsetWidth;
                        canvasHeight = canvasParent.offsetHeight;
                        canvas.width = canvasWidth * retina;
                        canvas.height = canvasHeight * retina;
                        ConfettiPaper.bounds = new Vector2(canvasWidth, canvasHeight);
                        ConfettiRibbon.bounds = new Vector2(canvasWidth, canvasHeight);
                    }
                    this.start = function() {
                        this.stop()
                        var context = this;
                        this.update();
                    }
                    this.stop = function() {
                        cAF(this.interval);
                    }
                    this.update = function() {
                        var i = 0;
                        context.clearRect(0, 0, canvas.width, canvas.height);
                        for (i = 0; i < confettiPaperCount; i++) {
                            confettiPapers[i].Update(duration);
                            confettiPapers[i].Draw(context);
                        }
                        for (i = 0; i < confettiRibbonCount; i++) {
                            confettiRibbons[i].Update(duration);
                            confettiRibbons[i].Draw(context);
                        }
                        this.interval = rAF(function() {
                            confetti.update();
                        });
                    }
                }
                var confetti = new confetti.Context('confetti');
                confetti.start();
                window.addEventListener('resize', function(event){
                    confetti.resize();
                });
            });
        </script>
<center>
<div>
<h1>Welcome to Horsford Social Club</h1></div></br>
        <div class="clock" style="margin:2em;"></div>

        <script type="text/javascript">
            var clock;

            $(document).ready(function() {

                // Grab the current date
                var currentDate = new Date();

                // Set some date in the future. In this case, it's always Jan 1
                var futureDate  = new Date(currentDate.getFullYear() + 1, 0, 1);

                // Calculate the difference in seconds between the future and current date
                var diff = futureDate.getTime() / 1000 - currentDate.getTime() / 1000;

                // Instantiate a coutdown FlipClock
                clock = $('.clock').FlipClock(diff, {
                    clockFace: 'DailyCounter',
                                    callbacks: {
                    stop: function() {
                        $('.message').html('<h1>Happy New Year!</h1>');
                    }
                }
            });

        });
        </script>
        </center></body>
</html>

1 个答案:

答案 0 :(得分:1)

对于一个相当简单的快速修复,更换线 document.addEventListener("DOMContentLoaded", function() { 使用function runConfetti(){并从脚本块的末尾删除);。我们没有传递一个匿名函数来在“DOMContentLoaded”上运行,而是命名该函数并在正确的时间自己调用它。

现在就准备好调用runConfetti函数:)

我现在已将它添加到“停止”功能,虽然我看不到该库实际上在做什么,所以这可能是错误的。

<html>
    <head>
        <link rel="stylesheet" href="../compiled/flipclock.css">

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

        <script src="../compiled/flipclock.js"></script>
<style>
body {
background: black;
}

h1 {
font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
color: white;
font-size: 7em;
}
.flip-clock-divider.days,
.clock ul:nth-child(1),
.clock ul:nth-child(2),
.clock ul:nth-child(3)
{
    display: none;
}   

.flip-clock-divider hours,
.flip-clock-dot.top {
    top: 30px;
    display: none;
}
.flip-clock-divider hours,
.flip-clock-dot.bottom {
    top: 30px;
    display: none;
}

.flip-clock-divider .flip-clock-label {
color: white;}

.clock {
zoom:345%;
}

            #confetti{
                position: absolute;
                left: 0;
                top: 0;
                height: 100%;
                width: 100%;
            }

</style>
    </head>
    <body>

<canvas id="confetti" width="1" height="1""></canvas>

<script type="text/javascript">
            var retina = window.devicePixelRatio,

                // Math shorthands
                PI = Math.PI,
                sqrt = Math.sqrt,
                round = Math.round,
                random = Math.random,
                cos = Math.cos,
                sin = Math.sin,

                // Local WindowAnimationTiming interface
                rAF = window.requestAnimationFrame,
                cAF = window.cancelAnimationFrame || window.cancelRequestAnimationFrame;

            // Local WindowAnimationTiming interface polyfill
            (function (w) {
                /**
                * Fallback implementation.
                */
                var prev = new Date().getTime();
                function fallback(fn) {
                    var curr = _now();
                    var ms = Math.max(0, 16 - (curr - prev));
                    var req = setTimeout(fn, ms);
                    prev = curr;
                    return req;
                }

                /**
                * Cancel.
                */
                var cancel = w.cancelAnimationFrame
                    || w.webkitCancelAnimationFrame
                    || w.clearTimeout;

                rAF = w.requestAnimationFrame
                    || w.webkitRequestAnimationFrame
                    || fallback;

                cAF = function(id){
                    cancel.call(w, id);
                };
            }(window));

            function runConfetti() {
                var speed = 50,
                    duration = (1.0 / speed),
                    confettiRibbonCount = 11,
                    ribbonPaperCount = 30,
                    ribbonPaperDist = 8.0,
                    ribbonPaperThick = 8.0,
                    confettiPaperCount = 95,
                    DEG_TO_RAD = PI / 180,
                    RAD_TO_DEG = 180 / PI,
                    colors = [
                        ["#df0049", "#660671"],
                        ["#00e857", "#005291"],
                        ["#2bebbc", "#05798a"],
                        ["#ffd200", "#b06c00"]
                    ];

                function Vector2(_x, _y) {
                    this.x = _x, this.y = _y;
                    this.Length = function() {
                        return sqrt(this.SqrLength());
                    }
                    this.SqrLength = function() {
                        return this.x * this.x + this.y * this.y;
                    }
                    this.Add = function(_vec) {
                        this.x += _vec.x;
                        this.y += _vec.y;
                    }
                    this.Sub = function(_vec) {
                        this.x -= _vec.x;
                        this.y -= _vec.y;
                    }
                    this.Div = function(_f) {
                        this.x /= _f;
                        this.y /= _f;
                    }
                    this.Mul = function(_f) {
                        this.x *= _f;
                        this.y *= _f;
                    }
                    this.Normalize = function() {
                        var sqrLen = this.SqrLength();
                        if (sqrLen != 0) {
                            var factor = 1.0 / sqrt(sqrLen);
                            this.x *= factor;
                            this.y *= factor;
                        }
                    }
                    this.Normalized = function() {
                        var sqrLen = this.SqrLength();
                        if (sqrLen != 0) {
                            var factor = 1.0 / sqrt(sqrLen);
                            return new Vector2(this.x * factor, this.y * factor);
                        }
                        return new Vector2(0, 0);
                    }
                }
                Vector2.Lerp = function(_vec0, _vec1, _t) {
                    return new Vector2((_vec1.x - _vec0.x) * _t + _vec0.x, (_vec1.y - _vec0.y) * _t + _vec0.y);
                }
                Vector2.Distance = function(_vec0, _vec1) {
                    return sqrt(Vector2.SqrDistance(_vec0, _vec1));
                }
                Vector2.SqrDistance = function(_vec0, _vec1) {
                    var x = _vec0.x - _vec1.x;
                    var y = _vec0.y - _vec1.y;
                    return (x * x + y * y + z * z);
                }
                Vector2.Scale = function(_vec0, _vec1) {
                    return new Vector2(_vec0.x * _vec1.x, _vec0.y * _vec1.y);
                }
                Vector2.Min = function(_vec0, _vec1) {
                    return new Vector2(Math.min(_vec0.x, _vec1.x), Math.min(_vec0.y, _vec1.y));
                }
                Vector2.Max = function(_vec0, _vec1) {
                    return new Vector2(Math.max(_vec0.x, _vec1.x), Math.max(_vec0.y, _vec1.y));
                }
                Vector2.ClampMagnitude = function(_vec0, _len) {
                    var vecNorm = _vec0.Normalized;
                    return new Vector2(vecNorm.x * _len, vecNorm.y * _len);
                }
                Vector2.Sub = function(_vec0, _vec1) {
                    return new Vector2(_vec0.x - _vec1.x, _vec0.y - _vec1.y, _vec0.z - _vec1.z);
                }

                function EulerMass(_x, _y, _mass, _drag) {
                    this.position = new Vector2(_x, _y);
                    this.mass = _mass;
                    this.drag = _drag;
                    this.force = new Vector2(0, 0);
                    this.velocity = new Vector2(0, 0);
                    this.AddForce = function(_f) {
                        this.force.Add(_f);
                    }
                    this.Integrate = function(_dt) {
                        var acc = this.CurrentForce(this.position);
                        acc.Div(this.mass);
                        var posDelta = new Vector2(this.velocity.x, this.velocity.y);
                        posDelta.Mul(_dt);
                        this.position.Add(posDelta);
                        acc.Mul(_dt);
                        this.velocity.Add(acc);
                        this.force = new Vector2(0, 0);
                    }
                    this.CurrentForce = function(_pos, _vel) {
                        var totalForce = new Vector2(this.force.x, this.force.y);
                        var speed = this.velocity.Length();
                        var dragVel = new Vector2(this.velocity.x, this.velocity.y);
                        dragVel.Mul(this.drag * this.mass * speed);
                        totalForce.Sub(dragVel);
                        return totalForce;
                    }
                }

                function ConfettiPaper(_x, _y) {
                    this.pos = new Vector2(_x, _y);
                    this.rotationSpeed = (random() * 600 + 800);
                    this.angle = DEG_TO_RAD * random() * 360;
                    this.rotation = DEG_TO_RAD * random() * 360;
                    this.cosA = 1.0;
                    this.size = 5.0;
                    this.oscillationSpeed = (random() * 1.5 + 0.5);
                    this.xSpeed = 40.0;
                    this.ySpeed = (random() * 60 + 50.0);
                    this.corners = new Array();
                    this.time = random();
                    var ci = round(random() * (colors.length - 1));
                    this.frontColor = colors[ci][0];
                    this.backColor = colors[ci][1];
                    for (var i = 0; i < 4; i++) {
                        var dx = cos(this.angle + DEG_TO_RAD * (i * 90 + 45));
                        var dy = sin(this.angle + DEG_TO_RAD * (i * 90 + 45));
                        this.corners[i] = new Vector2(dx, dy);
                    }
                    this.Update = function(_dt) {
                        this.time += _dt;
                        this.rotation += this.rotationSpeed * _dt;
                        this.cosA = cos(DEG_TO_RAD * this.rotation);
                        this.pos.x += cos(this.time * this.oscillationSpeed) * this.xSpeed * _dt
                        this.pos.y += this.ySpeed * _dt;
                        if (this.pos.y > ConfettiPaper.bounds.y) {
                            this.pos.x = random() * ConfettiPaper.bounds.x;
                            this.pos.y = 0;
                        }
                    }
                    this.Draw = function(_g) {
                        if (this.cosA > 0) {
                            _g.fillStyle = this.frontColor;
                        } else {
                            _g.fillStyle = this.backColor;
                        }
                        _g.beginPath();
                        _g.moveTo((this.pos.x + this.corners[0].x * this.size) * retina, (this.pos.y + this.corners[0].y * this.size * this.cosA) * retina);
                        for (var i = 1; i < 4; i++) {
                            _g.lineTo((this.pos.x + this.corners[i].x * this.size) * retina, (this.pos.y + this.corners[i].y * this.size * this.cosA) * retina);
                        }
                        _g.closePath();
                        _g.fill();
                    }
                }
                ConfettiPaper.bounds = new Vector2(0, 0);

                function ConfettiRibbon(_x, _y, _count, _dist, _thickness, _angle, _mass, _drag) {
                    this.particleDist = _dist;
                    this.particleCount = _count;
                    this.particleMass = _mass;
                    this.particleDrag = _drag;
                    this.particles = new Array();
                    var ci = round(random() * (colors.length - 1));
                    this.frontColor = colors[ci][0];
                    this.backColor = colors[ci][1];
                    this.xOff = (cos(DEG_TO_RAD * _angle) * _thickness);
                    this.yOff = (sin(DEG_TO_RAD * _angle) * _thickness);
                    this.position = new Vector2(_x, _y);
                    this.prevPosition = new Vector2(_x, _y);
                    this.velocityInherit = (random() * 2 + 4);
                    this.time = random() * 100;
                    this.oscillationSpeed = (random() * 2 + 2);
                    this.oscillationDistance = (random() * 40 + 40);
                    this.ySpeed = (random() * 40 + 80);
                    for (var i = 0; i < this.particleCount; i++) {
                        this.particles[i] = new EulerMass(_x, _y - i * this.particleDist, this.particleMass, this.particleDrag);
                    }
                    this.Update = function(_dt) {
                        var i = 0;
                        this.time += _dt * this.oscillationSpeed;
                        this.position.y += this.ySpeed * _dt;
                        this.position.x += cos(this.time) * this.oscillationDistance * _dt;
                        this.particles[0].position = this.position;
                        var dX = this.prevPosition.x - this.position.x;
                        var dY = this.prevPosition.y - this.position.y;
                        var delta = sqrt(dX * dX + dY * dY);
                        this.prevPosition = new Vector2(this.position.x, this.position.y);
                        for (i = 1; i < this.particleCount; i++) {
                            var dirP = Vector2.Sub(this.particles[i - 1].position, this.particles[i].position);
                            dirP.Normalize();
                            dirP.Mul((delta / _dt) * this.velocityInherit);
                            this.particles[i].AddForce(dirP);
                        }
                        for (i = 1; i < this.particleCount; i++) {
                            this.particles[i].Integrate(_dt);
                        }
                        for (i = 1; i < this.particleCount; i++) {
                            var rp2 = new Vector2(this.particles[i].position.x, this.particles[i].position.y);
                            rp2.Sub(this.particles[i - 1].position);
                            rp2.Normalize();
                            rp2.Mul(this.particleDist);
                            rp2.Add(this.particles[i - 1].position);
                            this.particles[i].position = rp2;
                        }
                        if (this.position.y > ConfettiRibbon.bounds.y + this.particleDist * this.particleCount) {
                            this.Reset();
                        }
                    }
                    this.Reset = function() {
                        this.position.y = -random() * ConfettiRibbon.bounds.y;
                        this.position.x = random() * ConfettiRibbon.bounds.x;
                        this.prevPosition = new Vector2(this.position.x, this.position.y);
                        this.velocityInherit = random() * 2 + 4;
                        this.time = random() * 100;
                        this.oscillationSpeed = random() * 2.0 + 1.5;
                        this.oscillationDistance = (random() * 40 + 40);
                        this.ySpeed = random() * 40 + 80;
                        var ci = round(random() * (colors.length - 1));
                        this.frontColor = colors[ci][0];
                        this.backColor = colors[ci][1];
                        this.particles = new Array();
                        for (var i = 0; i < this.particleCount; i++) {
                            this.particles[i] = new EulerMass(this.position.x, this.position.y - i * this.particleDist, this.particleMass, this.particleDrag);
                        }
                    }
                    this.Draw = function(_g) {
                        for (var i = 0; i < this.particleCount - 1; i++) {
                            var p0 = new Vector2(this.particles[i].position.x + this.xOff, this.particles[i].position.y + this.yOff);
                            var p1 = new Vector2(this.particles[i + 1].position.x + this.xOff, this.particles[i + 1].position.y + this.yOff);
                            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) {
                                _g.fillStyle = this.frontColor;
                                _g.strokeStyle = this.frontColor;
                            } else {
                                _g.fillStyle = this.backColor;
                                _g.strokeStyle = this.backColor;
                            }
                            if (i == 0) {
                                _g.beginPath();
                                _g.moveTo(this.particles[i].position.x * retina, this.particles[i].position.y * retina);
                                _g.lineTo(this.particles[i + 1].position.x * retina, this.particles[i + 1].position.y * retina);
                                _g.lineTo(((this.particles[i + 1].position.x + p1.x) * 0.5) * retina, ((this.particles[i + 1].position.y + p1.y) * 0.5) * retina);
                                _g.closePath();
                                _g.stroke();
                                _g.fill();
                                _g.beginPath();
                                _g.moveTo(p1.x * retina, p1.y * retina);
                                _g.lineTo(p0.x * retina, p0.y * retina);
                                _g.lineTo(((this.particles[i + 1].position.x + p1.x) * 0.5) * retina, ((this.particles[i + 1].position.y + p1.y) * 0.5) * retina);
                                _g.closePath();
                                _g.stroke();
                                _g.fill();
                            } else if (i == this.particleCount - 2) {
                                _g.beginPath();
                                _g.moveTo(this.particles[i].position.x * retina, this.particles[i].position.y * retina);
                                _g.lineTo(this.particles[i + 1].position.x * retina, this.particles[i + 1].position.y * retina);
                                _g.lineTo(((this.particles[i].position.x + p0.x) * 0.5) * retina, ((this.particles[i].position.y + p0.y) * 0.5) * retina);
                                _g.closePath();
                                _g.stroke();
                                _g.fill();
                                _g.beginPath();
                                _g.moveTo(p1.x * retina, p1.y * retina);
                                _g.lineTo(p0.x * retina, p0.y * retina);
                                _g.lineTo(((this.particles[i].position.x + p0.x) * 0.5) * retina, ((this.particles[i].position.y + p0.y) * 0.5) * retina);
                                _g.closePath();
                                _g.stroke();
                                _g.fill();
                            } else {
                                _g.beginPath();
                                _g.moveTo(this.particles[i].position.x * retina, this.particles[i].position.y * retina);
                                _g.lineTo(this.particles[i + 1].position.x * retina, this.particles[i + 1].position.y * retina);
                                _g.lineTo(p1.x * retina, p1.y * retina);
                                _g.lineTo(p0.x * retina, p0.y * retina);
                                _g.closePath();
                                _g.stroke();
                                _g.fill();
                            }
                        }
                    }
                    this.Side = function(x1, y1, x2, y2, x3, y3) {
                        return ((x1 - x2) * (y3 - y2) - (y1 - y2) * (x3 - x2));
                    }
                }
                ConfettiRibbon.bounds = new Vector2(0, 0);
                confetti = {};
                confetti.Context = function(id) {
                    var i = 0;
                    var canvas = document.getElementById(id);
                    var canvasParent = canvas.parentNode;
                    var canvasWidth = canvasParent.offsetWidth;
                    var canvasHeight = canvasParent.offsetHeight;
                    canvas.width = canvasWidth * retina;
                    canvas.height = canvasHeight * retina;
                    var context = canvas.getContext('2d');
                    var interval = null;
                    var confettiRibbons = new Array();
                    ConfettiRibbon.bounds = new Vector2(canvasWidth, canvasHeight);
                    for (i = 0; i < confettiRibbonCount; i++) {
                        confettiRibbons[i] = new ConfettiRibbon(random() * canvasWidth, -random() * canvasHeight * 2, ribbonPaperCount, ribbonPaperDist, ribbonPaperThick, 45, 1, 0.05);
                    }
                    var confettiPapers = new Array();
                    ConfettiPaper.bounds = new Vector2(canvasWidth, canvasHeight);
                    for (i = 0; i < confettiPaperCount; i++) {
                        confettiPapers[i] = new ConfettiPaper(random() * canvasWidth, random() * canvasHeight);
                    }
                    this.resize = function() {
                        canvasWidth = canvasParent.offsetWidth;
                        canvasHeight = canvasParent.offsetHeight;
                        canvas.width = canvasWidth * retina;
                        canvas.height = canvasHeight * retina;
                        ConfettiPaper.bounds = new Vector2(canvasWidth, canvasHeight);
                        ConfettiRibbon.bounds = new Vector2(canvasWidth, canvasHeight);
                    }
                    this.start = function() {
                        this.stop()
                        var context = this;
                        this.update();
                    }
                    this.stop = function() {
                        cAF(this.interval);
                    }
                    this.update = function() {
                        var i = 0;
                        context.clearRect(0, 0, canvas.width, canvas.height);
                        for (i = 0; i < confettiPaperCount; i++) {
                            confettiPapers[i].Update(duration);
                            confettiPapers[i].Draw(context);
                        }
                        for (i = 0; i < confettiRibbonCount; i++) {
                            confettiRibbons[i].Update(duration);
                            confettiRibbons[i].Draw(context);
                        }
                        this.interval = rAF(function() {
                            confetti.update();
                        });
                    }
                }
                var confetti = new confetti.Context('confetti');
                confetti.start();
                window.addEventListener('resize', function(event){
                    confetti.resize();
                });
            }
        </script>
<center>
<div>
<h1>Welcome to Horsford Social Club</h1></div></br>
        <div class="clock" style="margin:2em;"></div>

        <script type="text/javascript">
            var clock;

            $(document).ready(function() {

                // Grab the current date
                var currentDate = new Date();

                // Set some date in the future. In this case, it's always Jan 1
                var futureDate  = new Date(currentDate.getFullYear() + 1, 0, 1);

                // Calculate the difference in seconds between the future and current date
                var diff = futureDate.getTime() / 1000 - currentDate.getTime() / 1000;

                // Instantiate a coutdown FlipClock
                clock = $('.clock').FlipClock(diff, {
                    clockFace: 'DailyCounter',
                                    callbacks: {
                    stop: function() {
                        runConfetti();
                        $('.message').html('<h1>Happy New Year!</h1>');
                    }
                }
            });

        });
        </script>
        </center></body>
</html>