3

I need to start a canvas (id="confetti") once the clock I have on this page has finished. Once the clock finishes and reaches midnight, it will display Happy New Year, which I want to keep, but I'd like for the confetti in the canvas to start, and to not load automatically? I'm guessing it's possible to use "stop: function() {" but i'm not sure how to start it?

Any ideas would be massively helpful.

I have a live version of it currently is here.

Thankyou.

<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 Answer 1

1

For a fairly simple quick fix replace the line document.addEventListener("DOMContentLoaded", function() { with function runConfetti(){ and remove the ); from the end of the script block. Instead of passing an anonymous function to be run on "DOMContentLoaded" we're naming the function and calling it ourselves at the correct time.

Just call the runConfetti function when your ready now :)

I've added it to the "stop" function for now, although I can't see what that library is actually doing so this might be wrong.

<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>

Sign up to request clarification or add additional context in comments.

4 Comments

I have one little issue with this. It seems to stop the firing of the Happy New Year! message. If you can work out why? There is a link to a version where you can see it hit the countdown here - browno.co.uk/nye/examples/countdown-stop-callback.html
I can't seem to find any elements with the .message class name in HTML snippet, the code the append the message is running but can't find an element to insert the text into... Did you forget to add it to that version?
Ah ok. Previously it just did this by itself. So should I add a div with the class of message, so it can insert it?
mmm well I can't see anything that would add an element with that class and nothing there errors. Yeah just adding something like <div class="message"></div> to the body should fix it. Or you could replace the current title with it by changing the top part to <div class="message"> <h1>Welcome to Horsford Social Club</h1></div>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.