| <!-- |
| 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 Animations</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/perf_test_helper.js"></script> |
| <script> |
| var measurementReady = false; |
| 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 animationDuration = 10; |
| |
| var particles = []; |
| |
| window.onload = function () { |
| generateStyleElement(); |
| |
| // Create the particles |
| for (var i = 0; i < maxParticles; i++) { |
| var particle = new Particle(i); |
| particle.start(); |
| particles.push(particle); |
| } |
| |
| measurementReady = true; |
| } |
| |
| function generateStyleElement() { |
| var allParticleKeyframes = ''; |
| for (var i = 0; i < maxParticles; i++) |
| allParticleKeyframes += generateParticleKeyframes(i); |
| document.querySelector('#keyframes').innerHTML = allParticleKeyframes; |
| } |
| |
| function generateParticleKeyframes(index) { |
| var keyframes = '@-webkit-keyframes ' + animationNameForIndex(index) + '{\n'; |
| |
| var angle = Math.PI * 2 * PerfTestHelper.random(); |
| var velocity = minVelocity + ((maxVelocity - minVelocity) * PerfTestHelper.random()); |
| var x = stageWidth / 2 - particleRadius; |
| var y = stageHeight / 2 - particleRadius; |
| var dx = Math.cos(angle) * velocity; |
| var dy = Math.sin(angle) * velocity; |
| |
| function detectCollision(lineX, normalX, lineY, normalY) { |
| var dtx = Infinity; |
| var dty = Infinity; |
| if (dx * normalX < 0) |
| dtx = (lineX - x) / dx; |
| if (dy * normalY < 0) |
| dty = (lineY - y) / dy; |
| var dt = Math.min(dtx, dty); |
| var hitX = (dtx < dty); |
| return { |
| dt: dt, |
| x: hitX ? lineX : x + (dx * dt), |
| y: hitX ? y + (dy * dt) : lineY, |
| dx: hitX ? -dx : dx, |
| dy: hitX ? dy : -dy, |
| }; |
| } |
| |
| var t = 0; |
| keyframes += generateKeyframe(0, x, y); |
| while (t < animationDuration) { |
| var collisionA = detectCollision(0, 1, 0, 1); |
| var collisionB = detectCollision(stageWidth, -1, stageHeight, -1); |
| var collision = collisionA.dt < collisionB.dt ? collisionA : collisionB; |
| if (t + collision.dt > animationDuration) { |
| var dt = animationDuration - t; |
| t = animationDuration; |
| x += dx * dt; |
| y += dy * dt; |
| } else { |
| t += collision.dt; |
| x = collision.x; |
| y = collision.y; |
| dx = collision.dx; |
| dy = collision.dy; |
| } |
| keyframes += generateKeyframe(t, x, y); |
| } |
| |
| keyframes += '}\n'; |
| return keyframes; |
| } |
| |
| function generateKeyframe(t, x, y) { |
| return (100 * t / animationDuration) + '% { left: ' + x + 'px; top: ' + y + 'px; }\n'; |
| } |
| |
| function animationNameForIndex(index) { |
| return 'animation-' + index; |
| } |
| |
| function Particle(index) |
| { |
| // Create visual element for the particle. |
| var domNode = document.createElement('span'); |
| document.body.appendChild(domNode); |
| |
| // Set colour of element. |
| domNode.style.backgroundColor = colors[Math.floor(PerfTestHelper.random() * colors.length)]; |
| domNode.style.webkitAnimationTimingFunction = 'linear'; |
| domNode.style.webkitAnimationIterationCount = 'infinite'; |
| domNode.style.webkitAnimationDirection = 'alternate'; |
| domNode.style.webkitAnimationDuration = animationDuration + 's'; |
| |
| function start() { |
| domNode.style.webkitAnimationName = animationNameForIndex(index); |
| } |
| |
| function destroy() |
| { |
| document.body.removeChild(domNode); |
| } |
| |
| this.start = start; |
| this.destroy = destroy; |
| } |
| </script> |
| <style id="keyframes"></style> |
| </head> |
| </html> |