Skip to content

Instantly share code, notes, and snippets.

@darosh
Last active November 30, 2015 09:35
Show Gist options
  • Save darosh/65f9046bcb91c5f516a1 to your computer and use it in GitHub Desktop.
Save darosh/65f9046bcb91c5f516a1 to your computer and use it in GitHub Desktop.
Tweaking two.js
function BenchTwoRectangles(container, width, height, data, params) {
var self, renderer, objects;
return self = {
init: function () {
renderer = Two.Instances.filter(function (d) {
return {webgl: 'WebGLRenderer', canvas: 'CanvasRenderer'}[params.renderer] === d.type;
})[0];
renderer = renderer || new Two({
type: Two.Types[params.renderer],
width: width,
height: height
});
renderer.appendTo(container.node());
objects = [];
for (var i = 0; i < data.length; i++) {
var d = data[i];
var o = renderer.makeRectangle(0, 0, d.w, d.h);
o.fill = d.fillRgba;
o.noStroke();
objects.push(o);
}
self.update();
},
update: function () {
for (var i = 0; i < data.length; i++) {
var c = data[i];
objects[i].translation.set(c.x, c.y);
}
renderer.update();
},
destroy: function () {
objects = null;
renderer.clear();
if (params.renderer === 'svg') {
Two.Instances.pop();
} else {
// Garbage leftovers?
renderer.scene.subtractions.splice(0);
}
renderer = null;
}
};
}
BenchTwoRectangles.version = Two.Version.replace('v', '');
BenchTwoRectangles.framework = 'two';
BenchTwoRectangles.object = 'rectangle';
BenchTwoRectangles.renderers = ['webgl', 'canvas', 'svg'];
Bench.list.push(BenchTwoRectangles);
function BenchTwoTweakRectangles(container, width, height, data, params) {
var self, renderer, objects;
var _identity, _toArray, _multiply, _scale;
function tweak() {
_identity = Two.Matrix.prototype.identity;
_toArray = Two.Matrix.prototype.toArray;
_multiply = Two.Matrix.prototype.multiply;
_scale = Two.Matrix.prototype.scale;
Backbone.Events.trigger = function () {
};
Two.Matrix.prototype.identity = function () {
this.elements[0] = Two.Matrix.Identity[0];
this.elements[1] = Two.Matrix.Identity[1];
this.elements[2] = Two.Matrix.Identity[2];
this.elements[3] = Two.Matrix.Identity[3];
this.elements[4] = Two.Matrix.Identity[4];
this.elements[5] = Two.Matrix.Identity[5];
this.elements[6] = Two.Matrix.Identity[6];
this.elements[7] = Two.Matrix.Identity[7];
this.elements[8] = Two.Matrix.Identity[8];
return this;
};
Two.Matrix.prototype.toArray = function (fullMatrix, output) {
if (fullMatrix) {
if (output) {
output[0] = this.elements[0];
output[1] = this.elements[3];
output[2] = this.elements[6];
output[3] = this.elements[1];
output[4] = this.elements[4];
output[5] = this.elements[7];
output[6] = this.elements[2];
output[7] = this.elements[5];
output[8] = this.elements[8];
} else {
// ...
}
} else {
if (output) {
output[0] = this.elements[0];
output[1] = this.elements[3];
output[2] = this.elements[1];
output[3] = this.elements[4];
output[4] = this.elements[2];
output[5] = this.elements[5];
} else {
// ...
}
}
};
Two.Matrix.prototype.multiply = function (a, b, c, d, e, f, g, h, i) {
// Multiply scalar
if (b === undefined) {
_.each(this.elements, function (v, i) {
this.elements[i] = v * a;
}, this);
return this;
}
if (d === undefined) { // Multiply Vector
var x, y, z;
a = a || 0;
b = b || 0;
c = c || 0;
e = this.elements;
// Go down rows first
// a, d, g, b, e, h, c, f, i
x = e[0] * a + e[1] * b + e[2] * c;
y = e[3] * a + e[4] * b + e[5] * c;
z = e[6] * a + e[7] * b + e[8] * c;
return {x: x, y: y, z: z};
}
// Multiple matrix
var A = this.elements;
var B = [a, b, c, d, e, f, g, h, i];
var A0 = A[0], A1 = A[1], A2 = A[2];
var A3 = A[3], A4 = A[4], A5 = A[5];
var A6 = A[6], A7 = A[7], A8 = A[8];
var B0 = B[0], B1 = B[1], B2 = B[2];
var B3 = B[3], B4 = B[4], B5 = B[5];
var B6 = B[6], B7 = B[7], B8 = B[8];
this.elements[0] = A0 * B0 + A1 * B3 + A2 * B6;
this.elements[1] = A0 * B1 + A1 * B4 + A2 * B7;
this.elements[2] = A0 * B2 + A1 * B5 + A2 * B8;
this.elements[3] = A3 * B0 + A4 * B3 + A5 * B6;
this.elements[4] = A3 * B1 + A4 * B4 + A5 * B7;
this.elements[5] = A3 * B2 + A4 * B5 + A5 * B8;
this.elements[6] = A6 * B0 + A7 * B3 + A8 * B6;
this.elements[7] = A6 * B1 + A7 * B4 + A8 * B7;
this.elements[8] = A6 * B2 + A7 * B5 + A8 * B8;
return this;
};
Two.Matrix.prototype.scale = function (sx, sy) {
return this.multiply(sx, 0, 0, 0, sy !== undefined ? sy : sx, 0, 0, 0, 1);
};
}
function untweak() {
Two.Matrix.prototype.identity = _identity;
Two.Matrix.prototype.toArray = _toArray;
Two.Matrix.prototype.multiply = _multiply;
Two.Matrix.prototype.scale = _scale;
}
return self = {
init: function () {
tweak();
renderer = Two.Instances.filter(function (d) {
return {webgl: 'WebGLRenderer', canvas: 'CanvasRenderer'}[params.renderer] === d.type;
})[0];
renderer = renderer || new Two({
type: Two.Types[params.renderer],
width: width,
height: height
});
renderer.appendTo(container.node());
objects = [];
for (var i = 0; i < data.length; i++) {
var d = data[i];
var o = renderer.makeRectangle(0, 0, d.w, d.h);
o.fill = d.fillRgba;
o.noStroke();
objects.push(o);
}
self.update();
},
update: function () {
for (var i = 0; i < data.length; i++) {
var c = data[i];
objects[i].translation.set(c.x, c.y);
}
renderer.update();
},
destroy: function () {
objects = null;
renderer.clear();
if (params.renderer === 'svg') {
Two.Instances.pop();
} else {
// Garbage leftovers?
renderer.scene.subtractions.splice(0);
}
renderer = null;
untweak();
}
};
}
BenchTwoTweakRectangles.version = Two.Version.replace('v', '');
BenchTwoTweakRectangles.framework = 'two-tweak';
BenchTwoTweakRectangles.object = 'rectangle';
BenchTwoTweakRectangles.renderers = ['webgl', 'canvas', 'svg'];
Bench.list.push(BenchTwoTweakRectangles);
<!DOCTYPE html>
<meta charset='UTF-8'>
<title>Benchmark</title>
<link rel="stylesheet" href="/darosh/raw/a71ff1c9d6e163e2faea/style.css">
<style>
.cloak {
display: none;
}
</style>
<style>
/* Animated arrow */
#arrow {
transform: rotate(30deg);
}
#arrow polyline {
animation-name: svg-arrow;
animation-duration: 3s;
animation-delay: 1s;
animation-iteration-count: infinite;
transform: translate(44px, 32px) rotate(90deg);
fill: #fff;
}
#arrow path {
animation-name: svg-path;
animation-duration: 3s;
animation-delay: 1s;
animation-iteration-count: infinite;
stroke-dasharray: 4, 4;
stroke-dashoffset: -2;
fill: none;
stroke: #fff;
stroke-width: 3;
stroke-linecap: round;
stroke-linejoin: round;
}
@keyframes svg-arrow {
0% {
fill: #fff;
transform: translate(44px, 0px) rotate(90deg);
}
33% {
transform: translate(44px, 32px) rotate(90deg);
fill: #333;
}
66% {
fill: #333;
}
100% {
fill: #fff;
}
}
@keyframes svg-path {
0% {
stroke: #fff;
stroke-dashoffset: -2;
transform: translateY(-32px);
}
33% {
transform: translateY(0px);
stroke-dashoffset: -34;
stroke: #333;
}
66% {
transform: translateY(0px);
stroke: #333;
stroke-dashoffset: -34;
}
100% {
stroke: #fff;
transform: translateY(32px);
stroke-dashoffset: -66;
}
}
/* Why? Why? Because MS Edge. Cry, cry. :-( */
_:-ms-lang(x), #arrow {
display: none;
}
</style>
<body>
<script src='//cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js'></script>
<script>
// Backup requestAnimationFrame & restore after first call to disable two.js auto loop start
// https://github.com/jonobr1/two.js/issues/135
window._requestAnimationFrame = window.requestAnimationFrame;
window.requestAnimationFrame = function () {
window.requestAnimationFrame = window._requestAnimationFrame;
};
</script>
<script src='//cdnjs.cloudflare.com/ajax/libs/two.js/0.5.0/two.min.js'></script>
<script src='/darosh/raw/a71ff1c9d6e163e2faea/bench.js'></script>
<script src='/darosh/raw/a71ff1c9d6e163e2faea/bench.utils.js'></script>
<script src='bench-two-rectangles.js'></script>
<script src='bench-two-tweak-rectangles.js'></script>
<div>
<div class="cloak block pull-left">
<div id="container" class="container" style="position: relative">
<div id="message" class="block" style="padding: 0 8px">
</div>
<svg id="arrow" width="64" height="64" style="position: absolute; left: -10px; bottom: -6px;">
<defs>
<clipPath id="clip-arrow">
<rect x="0" y="0" width="64" height="32"></rect>
</clipPath>
</defs>
<g clip-path="url(#clip-arrow)">
<path d="M 32 0 L 32 32"></path>
</g>
<polyline points="0,0 24,12 0,24"></polyline>
</svg>
</div>
<div class="cloak controls block-label bottom pull-left">
<span id="run" class="btn click">run</span>
<span id="stop" class="btn click">stop</span>
<span id="info" class="btn click">info</span>
</div>
<div id="name" class="block-label bottom test-name pull-right text-right"></div>
<div class="clear"></div>
</div>
<div class="cloak block pull-left aside">
<div class="controls block-label top">
<div id="filter-object">object: <span class="list"></span></div>
<div id="filter-count">count: <span class="list"></span></div>
</div>
<svg id="pack" width="413" height="400" class="container"></svg>
</div>
</div>
<div class="cloak block pull-right">
<table id="result">
<thead>
<tr>
<th rowspan="2">Framework</th>
<th rowspan="2">Renderer</th>
<th rowspan="2">Object</th>
<th id="version" rowspan="2">Version</th>
<th class="group">Count / FPS</th>
</tr>
<tr class="objects"></tr>
</thead>
<tbody></tbody>
</table>
<div class="controls block-label bottom pull-left">
<span id="reset" class="btn click">reset</span>
<a id="share" class="btn click" href="./" target="_blank">share</a>
</div>
<div id="link" class="controls block-label bottom pull-right"><a href="#" target="_parent">open in a new window</a>
</div>
<div id="note" class="block-label bottom pull-right">click FPS value to run single test</div>
<div class="clear"></div>
</div>
<div class="cloak pull-left">
<svg id="chart"></svg>
</div>
<script>
Bench({
time: 2500,
pause: 250,
width: 400,
height: 400,
tests: [60, 240, 720, 1440, 1920]
});
try {
d3.select(self.frameElement).style('height', document.body.getBoundingClientRect().height + 'px');
} catch (ign) {
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment