Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
267 lines (218 sloc) 8.56 KB
<!--
MovingBoxes.html
Tests performance of transforms vs. top/left
Created by Jonathan Deutsch <jonathan@tumult.com>
Copyright (c) 2013 Tumult Inc.
-->
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<style>
#container {
width: 800px;
height: 600px;
position: relative;
}
</style>
<script>
// from http://paulirish.com/2011/requestanimationframe-for-smart-animating/
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
// modified from source found at: http://frugalcoder.us/post/2010/09/13/browser-detection.aspx
var kBrowserInfo = (function () {
var b = {};
if (!navigator) return b;
//browsermatch method...
function bm(re) {
var m = (navigator && navigator.userAgent && navigator.userAgent.match(re));
return (m && m[1]);
}
//setup browser detection
b.ie = parseFloat(bm(/MSIE (\d+\.\d+)/)) || null;
b.gecko = parseFloat(bm(/Gecko\/(\d+)/)) || null;
b.ff = parseFloat(bm(/Firefox\/(\d+\.\d+)/)) || null;
b.khtml = parseFloat(bm(/\((KHTML)/) && 1) || null;
b.webkit = parseFloat(bm(/AppleWebKit\/(\d+\.\d+)/));
b.chrome = parseFloat(b.webkit && bm(/Chrome\/(\d+\.\d+)/)) || null;
b.safari = parseFloat(b.webkit && bm(/Safari\/(\d+\.\d+)/) && bm(/Version\/(\d+\.\d+)/)) || null;
b.opera = parseFloat(bm(/Opera\/(\d+\.\d+)/) && bm(/Version\/(\d+\.\d+)/)) || bm(/Opera\/(\d+\.\d+)/) || null;
b.android = (navigator.userAgent.search("Android") > -1) || null;
b.ipad = (navigator.userAgent.search("iPad") > -1) || null;
b.iphone = (navigator.userAgent.search("iPhone") > -1) || null;
b.ipod = (navigator.userAgent.search("iPod") > -1) || null;
b.ios = b.ipad || b.iphone || b.ipod || null;
//delete empty values
for (var x in b) {
if (b[x] === null || isNaN(b[x]))
delete b[x];
}
//disable IE matching for older Opera versions.
if (b.opera && b.ie) delete b.ie;
return b;
}());
var kTotalBoxCount = 2000;
var kBoxWidth = 100;
var kBoxHeight = 100;
var kContainerWidth = 800;
var kContainerHeight = 600;
var kTestDuration = 10.0;
var kMaxTestIterations = 1;
var kTransformName = "transform";
var kTransitionName = "transition";
if(kBrowserInfo.webkit != null) {
kTransformName = "-webkit-transform";
kTransitionName = "-webkit-transition";
}
var gBoxes = Array();
var gStartTime = null;
var gFrameCount = 0;
var gTestMode = "transition"; // "javascript"
var gTestProperty = "topleft"; // "topleft"
var gShouldForce3D = false; // false
var gOpaque = true;
var gCurrentTestIndex = 0;
var gCurrentTestIteration = 0;
// test matrix
// transition style rotateY opacity
//
var kTestsMatrix = [
{ "mode" : "javascript", "property" : "topleft", "shouldForce3D" : true, "opaque" : true },
{ "mode" : "javascript", "property" : "topleft", "shouldForce3D" : false, "opaque" : true },
{ "mode" : "javascript", "property" : "translate", "shouldForce3D" : true, "opaque" : true },
{ "mode" : "javascript", "property" : "translate", "shouldForce3D" : false, "opaque" : true },
{ "mode" : "transition", "property" : "topleft", "shouldForce3D" : true, "opaque" : true },
{ "mode" : "transition", "property" : "topleft", "shouldForce3D" : false, "opaque" : true },
{ "mode" : "transition", "property" : "translate", "shouldForce3D" : false, "opaque" : true },
{ "mode" : "transition", "property" : "translate", "shouldForce3D" : true, "opaque" : true },
{ "mode" : "javascript", "property" : "topleft", "shouldForce3D" : true, "opaque" : false },
{ "mode" : "javascript", "property" : "topleft", "shouldForce3D" : false, "opaque" : false },
{ "mode" : "javascript", "property" : "translate", "shouldForce3D" : true, "opaque" : false },
{ "mode" : "javascript", "property" : "translate", "shouldForce3D" : false, "opaque" : false },
{ "mode" : "transition", "property" : "topleft", "shouldForce3D" : true, "opaque" : false },
{ "mode" : "transition", "property" : "topleft", "shouldForce3D" : false, "opaque" : false },
{ "mode" : "transition", "property" : "translate", "shouldForce3D" : false, "opaque" : false },
{ "mode" : "transition", "property" : "translate", "shouldForce3D" : true, "opaque" : false },
];
function beginTesting() {
runNextTest();
}
function runNextTest() {
var testInfo = kTestsMatrix[gCurrentTestIndex];
if(gCurrentTestIndex < kTestsMatrix.length) {
document.getElementById("output").innerHTML += "" + gCurrentTestIndex + " ";
runTest(testInfo.mode, testInfo.property, testInfo.shouldForce3D, testInfo.opaque);
}
if(gCurrentTestIteration + 1 < kMaxTestIterations) {
gCurrentTestIteration += 1;
} else {
gCurrentTestIteration = 0;
gCurrentTestIndex += 1;
}
}
function runTest(mode, property, shouldForce3D, opaque) {
var containerElement = document.getElementById("container");
containerElement.innerHTML = "";
gTestMode = mode;
gTestProperty = property;
gShouldForce3D = shouldForce3D;
gOpaque = opaque;
gFrameCount = 0;
createBoxes();
window.setTimeout((function() {
gStartTime = (((new Date).getTime()) / 1000.0);
if(gTestMode == "transition") {
window.requestAnimFrame(kickoffTransition);
} else if(gTestMode == "javascript") {
window.requestAnimFrame(heartbeat);
}
}), 2000);
}
function endTest(frames, elapsedTime) {
//document.getElementById("output").innerHTML += "" + frames + " / " + elapsedTime + " = " + (frames/elapsedTime) + "<br>";
runNextTest();
}
function kickoffTransition() {
for(var i = 0; i < gBoxes.length; i++) {
setElementPosition(gBoxes[i].element, gBoxes[i].endX, gBoxes[i].endY);
}
window.setTimeout(function() { endTest(); }, (kTestDuration * 1000) + 1000);
}
function heartbeat() {
gFrameCount += 1;
var currentTime = (((new Date).getTime()) / 1000.0) - gStartTime;
var percentComplete = currentTime / kTestDuration;
for(var i = 0; i < gBoxes.length; i++) {
xPos = Math.floor(gBoxes[i].startX + ((gBoxes[i].endX - gBoxes[i].startX) * percentComplete));
yPos = Math.floor(gBoxes[i].startY + ((gBoxes[i].endY - gBoxes[i].startY) * percentComplete));
setElementPosition(gBoxes[i].element, xPos, yPos);
}
if(currentTime < kTestDuration) {
window.requestAnimFrame(heartbeat);
} else {
endTest(gFrameCount, currentTime);
}
}
function setElementPosition(element, xPos, yPos) {
if(gTestProperty == "topleft") {
element.style.left = "" + xPos + "px";
element.style.top = "" + yPos + "px";
} else if(gTestProperty == "translate") {
if(gShouldForce3D == true) {
element.style[kTransformName] = "translateX(" + xPos + "px) translateY(" + yPos + "px) rotateY(0deg)";
} else {
element.style[kTransformName] = "translateX(" + xPos + "px) translateY(" + yPos + "px)";
}
}
}
function createBoxes() {
var containerElement = document.getElementById("container");
gBoxes = Array();
for(var i = 0; i < kTotalBoxCount; i++) {
var boxElement = document.createElement("div");
boxElement.style.border = "1px solid #333";
boxElement.style.backgroundColor = "#acf";
boxElement.style.width = "" + kBoxWidth + "px";
boxElement.style.height = "" + kBoxHeight + "px";
if(gTestProperty == "translate") {
boxElement.style.left = "0px";
boxElement.style.top = "0px";
}
if(gTestMode == "transition") {
if(gTestProperty == "topleft") {
boxElement.style[kTransitionName] = "left " + kTestDuration + "s linear, top " + kTestDuration + "s linear";
} else if(gTestProperty == "translate") {
boxElement.style[kTransitionName] = "" + kTransformName + " " + kTestDuration + "s linear";
}
}
boxElement.style.position = "absolute";
if(gOpaque == false) {
boxElement.style.opacity = 1.0 - (i / kTotalBoxCount);
}
if(gShouldForce3D == true) {
boxElement.style[kTransformName] = "rotateY(0deg)";
}
boxElement.id = "box-" + i;
var startX = Math.floor(Math.random() * (kContainerWidth - kBoxWidth));
var startY = Math.floor(Math.random() * (kContainerHeight - kBoxHeight));
var endX = Math.floor(Math.random() * (kContainerWidth - kBoxWidth));
var endY = Math.floor(Math.random() * (kContainerHeight - kBoxHeight));
gBoxes.push({"startX" : startX, "startY" : startY, "endX" : endX, "endY" : endY , "element" : boxElement});
containerElement.appendChild(boxElement);
setElementPosition(boxElement, startX, startY);
}
}
</script>
</head>
<body onload = "beginTesting()">
<div id = "container"></div>
<div id = "output"></div>
</body>
<html>