Skip to content

Instantly share code, notes, and snippets.

@pjanik
Last active Dec 14, 2015
Embed
What would you like to do?
Canvas (KineticJS) + Shape Caching
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<style>
canvas {
border: 1px dashed gray;
}
#results, #container {
display: inline-block;
margin: 15px;
}
p {
margin: 15px;
}
td {
border: 1px solid #bbb;
}
.header {
font-weight: bold;
}
</style>
<body>
<p id="user-agent"></p>
<div id="container"></div>
<table id="results">
<tr class="header">
<td>Circles</td>
<td>FPS</td>
<td>repaint [ms]</td>
</tr>
</table>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.3.3.min.js"></script>
<script>
/* global requestAnimationFrame, $, Kinetic */
window.requestAnimationFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
return window.setTimeout(callback, 1000/60);
};
})();
var tests = [25, 50, 150, 250, 500, 750];
function updateResults(count, time, steps) {
var repaint = time / steps,
$tr = $("<tr>");
$tr.append("<td>" + count + "</td><td>" + (1000/repaint).toFixed(2) + "</td><td>" + repaint.toFixed(2) + "</td>");
$("#results").append($tr);
}
function test() {
var count,
maxX = 500,
maxY = 400,
maxSteps = 150,
radius = 15,
steps = 0,
circles = [],
cdata = [],
stage,
layer,
startTime,
circle;
if (tests.length > 0) {
$("#container").empty();
count = tests.shift();
} else {
return;
}
stage = new Kinetic.Stage({
container: 'container',
width: maxX,
height: maxY
});
layer = new Kinetic.Layer();
circle = new Kinetic.Circle({
x: radius + 2,
y: radius + 2,
radius: radius,
fill: 'red',
stroke: 'black',
strokeWidth: 2
}).toImage({
width: radius * 2 + 4,
height: radius * 2 + 4,
callback: function (img) {
var i;
for (i = 0; i < count; i++) {
cdata.push({
x: maxX * Math.random(),
y: maxY * Math.random(),
vx: Math.random(),
vy: Math.random()
});
circle = new Kinetic.Image({
image: img,
offset: radius,
x: cdata[i].x,
y: cdata[i].y
});
circles.push(circle);
layer.add(circle);
}
// Add the layer to the stage.
stage.add(layer);
// Start animation.
startTime = new Date().getTime();
requestAnimationFrame(step);
function step() {
var c, i, len, time;
for (i = 0, len = count; i < len; i++) {
c = cdata[i];
if (c.x >= maxX || c.x <= 0) c.vx *= -1;
if (c.y >= maxY || c.y <= 0) c.vy *= -1;
c.x += c.vx;
c.y += c.vy;
circles[i].setX(c.x);
circles[i].setY(c.y);
}
layer.draw();
if (steps < maxSteps) {
steps++;
requestAnimationFrame(step);
} else {
time = new Date().getTime() - startTime;
updateResults(count, time, maxSteps);
test();
}
}
}
});
}
$(function () {
$("#user-agent").text(navigator.userAgent);
test();
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment