| <!-- |
| 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 SVG 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 () { |
| svgContainer.setAttribute('width', stageWidth); |
| svgContainer.setAttribute('height', stageHeight); |
| |
| for (var i = 0; i < maxParticles; i++) |
| addParticle(); |
| |
| measurementReady = true; |
| } |
| |
| function addParticle() |
| { |
| var circle = document.createElementNS('http://www.w3.org/2000/svg','circle'); |
| circle.setAttribute('r', particleRadius); |
| circle.setAttribute('fill', colors[Math.floor(PerfTestHelper.random() * colors.length)]); |
| addAnimation(circle); |
| svgContainer.appendChild(circle); |
| } |
| |
| function addAnimation(target) { |
| 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; |
| var prevX = x; |
| var prevY = y; |
| |
| 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; |
| var prevT = t; |
| 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; |
| } |
| target.appendChild(generateTransition(prevT, prevX, prevY, t, x, y)); |
| prevX = x; |
| prevY = y; |
| prevT = t; |
| } |
| if (target.lastChild) { |
| target.lastChild.setAttribute('repeatCount', '1000'); |
| } |
| } |
| |
| function generateTransition(prevT, prevX, prevY, t, x, y) { |
| var animation = document.createElementNS('http://www.w3.org/2000/svg','animateTransform'); |
| animation.setAttribute('attributeName', 'transform'); |
| animation.setAttribute('attributeType', 'xml'); |
| animation.setAttribute('type', 'translate' ); |
| animation.setAttribute('from', prevX + ' ' + prevY); |
| animation.setAttribute('to', x + ' ' + y); |
| animation.setAttribute('begin', prevT + 's'); |
| animation.setAttribute('dur', (t - prevT) + 's'); |
| return animation; |
| } |
| </script> |
| </head> |
| <svg ns="http://www.w3.org/2000/svg" version="1.1" id="svgContainer"></svg> |
| </html> |