1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 3 4 <!-- 5 Copyright (c) 2012 Cameron Adams. All rights reserved. 6 Copyright (c) 2012 Code Aurora Forum. All rights reserved. 7 8 Redistribution and use in source and binary forms, with or without 9 modification, are permitted provided that the following conditions are 10 met: 11 * Redistributions of source code must retain the above copyright 12 notice, this list of conditions and the following disclaimer. 13 * Redistributions in binary form must reproduce the above 14 copyright notice, this list of conditions and the following 15 disclaimer in the documentation and/or other materials provided 16 with the distribution. 17 * Neither the name of Code Aurora Forum, Inc. nor the names of its 18 contributors may be used to endorse or promote products derived 19 from this software without specific prior written permission. 20 21 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 22 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 24 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 25 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 28 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 30 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 31 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 33 This test is based on code written by Cameron Adams and imported from 34 http://themaninblue.com/experiment/AnimationBenchmark/html 35 --> 36 37 <head> 38 39 <title>Benchmark - HTML & JavaScript</title> 40 41 <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> 42 <meta name="author" content="The Man in Blue" /> 43 <meta name="robots" content="all" /> 44 <meta name="MSSmartTagsPreventParsing" content="true" /> 45 <meta name="description" content="" /> 46 <meta name="keywords" content="" /> 47 48 <style type="text/css"> 49 50 html { 51 height: 100%; 52 } 53 54 body { 55 width: 100%; 56 height: 100%; 57 overflow: hidden; 58 margin: 0; 59 padding: 0; 60 } 61 62 span { 63 position: absolute; 64 width: 12px; 65 height: 12px; 66 overflow: hidden; 67 -webkit-border-radius: 6px; 68 -moz-border-radius: 6px; 69 border-radius: 6px; 70 background-color: #000000; 71 } 72 73 .shadows span { 74 -webkit-box-shadow: 4px 4px 3px rgba(0,0,0,0.33); 75 -moz-box-shadow: 4px 4px 3px rgba(0,0,0,0.33); 76 box-shadow: 4px 4px 3px rgba(0,0,0,0.33); 77 } 78 79 #frameRate { 80 position: absolute; 81 right: 10px; 82 bottom: 10px; 83 z-index: 100; 84 font-size: 25px; 85 font-family: Arial, Helvetica, sans-serif; 86 } 87 88 </style> 89 90 <script type="text/javascript"> 91 92 var FRAMES_PER_TIMER_READING = 10; 93 var MAX_PARTICLES = 2500; 94 var MAX_VELOCITY = 50; 95 var PARTICLE_RADIUS = 6; 96 var STAGE_WIDTH = 600; 97 var STAGE_HEIGHT = 600; 98 var COLORS = ["#cc0000", "#ffcc00", "#aaff00", "#0099cc", "#194c99", "#661999"]; 99 100 var frameTimes = []; 101 var iteration = 0; 102 var run = 0; 103 var animateIntervalId = 0; 104 var statistics = []; 105 var frameRates = []; 106 var particles = []; 107 108 window.onload = function () { 109 PerfTestRunner.prepareToMeasureValuesAsync({done: onCompletedRun, unit: 'fps'}); 110 111 // Create the particles 112 for (var i = 0; i < MAX_PARTICLES; i++) 113 particles.push(new Particle()); 114 115 // Start the animation 116 animateIntervalId = setInterval(animate, 1); 117 } 118 119 function animate() 120 { 121 var currTime = PerfTestRunner.now(); 122 var timeDelta = currTime - frameTimes[frameTimes.length - 1]; 123 124 if (isNaN(timeDelta)) 125 timeDelta = 0; 126 127 // Draw each particle 128 for (var particle in particles) 129 particles[particle].draw(timeDelta); 130 131 if ((iteration++ % FRAMES_PER_TIMER_READING) == 0) { 132 // Limit the frame time array to the last 30 frames 133 if (frameTimes.length > 30) 134 frameTimes.splice(0, 1); 135 136 frameTimes.push(currTime); 137 138 // Calculate the framerate based upon the difference between the absolute times of the oldest and newest frames, subdivided by how many frames were drawn inbetween 139 var frameRate = document.getElementById("frameRate"); 140 var frameRateVal = FRAMES_PER_TIMER_READING * 1000 / ((currTime - frameTimes[0]) / (frameTimes.length - 1)); 141 142 if (!isNaN(frameRateVal)) 143 PerfTestRunner.measureValueAsync(frameRateVal); 144 } 145 } 146 147 function Particle() 148 { 149 var angle = Math.PI * 2 * PerfTestRunner.random(); 150 var velocity = MAX_VELOCITY / 8 * 7 * PerfTestRunner.random() + MAX_VELOCITY / 8; 151 var x = STAGE_WIDTH / 2 - PARTICLE_RADIUS; 152 var y = STAGE_HEIGHT / 2 - PARTICLE_RADIUS; 153 154 // Create visual element for the particle 155 var domNode = document.createElement('span'); 156 document.body.appendChild(domNode); 157 158 // Set initial position to middle of screen 159 domNode.style.left = x + "px"; 160 domNode.style.top = y + "px"; 161 162 // Set colour of element 163 domNode.style.backgroundColor = COLORS[Math.floor(Math.random() * COLORS.length)]; 164 165 function destroy() 166 { 167 document.body.removeChild(domNode); 168 return; 169 } 170 171 function draw(timeDelta) 172 { 173 // Calculate next position of particle 174 var nextX = x + Math.cos(angle) * velocity * (timeDelta / 1000); 175 var nextY = y + Math.sin(angle) * velocity * (timeDelta / 1000); 176 177 // If particle is going to move off right side of screen 178 if (nextX + PARTICLE_RADIUS * 2 > STAGE_WIDTH) 179 // If angle is between 3 o'clock and 6 o'clock 180 if ((angle >= 0 && angle < Math.PI / 2)) 181 angle = Math.PI - angle; 182 // If angle is between 12 o'clock and 3 o'clock 183 else if (angle > Math.PI / 2 * 3) 184 angle = angle - (angle - Math.PI / 2 * 3) * 2 185 186 // If particle is going to move off left side of screen 187 if (nextX < 0) 188 // If angle is between 6 o'clock and 9 o'clock 189 if ((angle > Math.PI / 2 && angle < Math.PI)) 190 angle = Math.PI - angle; 191 // If angle is between 9 o'clock and 12 o'clock 192 else if (angle > Math.PI && angle < Math.PI / 2 * 3) 193 angle = angle + (Math.PI / 2 * 3 - angle) * 2 194 195 // If particle is going to move off bottom side of screen 196 if (nextY + PARTICLE_RADIUS * 2 > STAGE_HEIGHT) 197 // If angle is between 3 o'clock and 9 o'clock 198 if ((angle > 0 && angle < Math.PI)) 199 angle = Math.PI * 2 - angle; 200 201 // If particle is going to move off top side of screen 202 if (nextY < 0) 203 // If angle is between 9 o'clock and 3 o'clock 204 if ((angle > Math.PI && angle < Math.PI * 2)) 205 angle = angle - (angle - Math.PI) * 2; 206 207 domNode.style.left = nextX + "px"; 208 domNode.style.top = nextY + "px"; 209 210 x = nextX; 211 y = nextY; 212 } 213 214 return { draw: draw, destroy: destroy } 215 } 216 217 function onCompletedRun() { 218 clearInterval(animateIntervalId); 219 220 for (var particle in particles) { 221 var p = particles[particle]; 222 particles[particle] = 0; 223 p.destroy(); 224 } 225 particles = []; 226 227 frameRate.innerHTML = ""; 228 } 229 </script> 230 <script src="../resources/runner.js"></script> 231 </head> 232 233 <body> 234 <div id="frameRate"> 235 </div> 236 </body> 237 238 </html> 239