<!--
Copyright (c) 2012 Cameron Adams. All rights reserved.
Copyright (c) 2012 Code Aurora Forum. All rights reserved.
Copyright (C) 2013 Google Inc. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
    * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
    * Neither the name of Code Aurora Forum Inc., Google Inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This test is based on code written by Cameron Adams and imported from
  http://themaninblue.com/experiment/AnimationBenchmark/html
-->

<!doctype html>
<head>
<title>Benchmark - Balls Animation using CSS and requestAnimationFrame</title>
<style>
html {
    height: 100%;
}

body {
    width: 100%;
    height: 100%;
    overflow: hidden;
    margin: 0;
    padding: 0;
}

span {
    position: absolute;
    width: 12px;
    height: 12px;
    border-radius: 6px;
}
</style>
<script src="../resources/runner.js"></script>
<script src="resources/framerate.js"></script>
<script>
var stageWidth = 600;
var stageHeight = 600;
var maxParticles = 2500;
var minVelocity = 50;
var maxVelocity = 500;
var particleRadius = 6;
var colors = ["#cc0000", "#ffcc00", "#aaff00", "#0099cc", "#194c99", "#661999"];

var testRunning = true;
var particles = [];
var prevTime;

window.onload = function () {
    PerfTestRunner.prepareToMeasureValuesAsync({done: onCompletedRun, unit: 'fps'});

    // Create the particles
    for (var i = 0; i < maxParticles; i++)
        particles.push(new Particle());

    // Start the animation
    prevTime = PerfTestRunner.now();
    animate();
    startTrackingFrameRate();
}

function animate()
{
    var currTime = PerfTestRunner.now();
    var timeDelta = currTime - prevTime;

    // Draw each particle
    for (var particle in particles)
        particles[particle].draw(timeDelta);

    prevTime = currTime;

    if (testRunning)
        requestAnimationFrame(animate);
}

function Particle()
{
    var angle = Math.PI * 2 * PerfTestRunner.random();
    var velocity = minVelocity + ((maxVelocity - minVelocity) * PerfTestRunner.random());
    var x = stageWidth / 2 - particleRadius;
    var y = stageHeight / 2 - particleRadius;
    var dx = Math.cos(angle) * velocity;
    var dy = Math.sin(angle) * velocity;

    // Create visual element for the particle
    var domNode = document.createElement('span');
    document.body.appendChild(domNode);

    // Set initial position to middle of screen
    domNode.style.left = x + "px";
    domNode.style.top = y + "px";

    // Set colour of element
    domNode.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];

    function destroy()
    {
        document.body.removeChild(domNode);
    }

    function draw(timeDelta)
    {
        var timeDeltaSeconds = timeDelta / 1000;
        var testX = x + (dx * timeDeltaSeconds);
        var testY = y + (dy * timeDeltaSeconds);

        if (testX < 0 || testX > stageWidth) {
            dx = -dx;
            x += dx;
        } else {
            x = testX;
        }
        if (testY < 0 || testY > stageHeight) {
            dy = -dy;
            y += dy;
        } else {
            y = testY;
        }

        domNode.style.left = x + "px";
        domNode.style.top = y + "px";
    }

    this.draw = draw;
    this.destroy = destroy;
}

function onCompletedRun() {
    stopTrackingFrameRate();

    for (var i = 0; i < particles.length; i++)
        particles[i].destroy();
    particles = [];
}
</script>
</head>
</html>
