Few optimizations in _parsePath implementation.

This commit is contained in:
kangax 2011-02-09 16:35:46 -05:00
parent d42ba6ec02
commit 45c9a333a8
5 changed files with 87 additions and 77 deletions

21
dist/all.js vendored
View file

@ -6122,6 +6122,7 @@ fabric.util.animate = animate;
toFixed = fabric.util.toFixed,
capitalize = fabric.util.string.capitalize,
getPointer = fabric.util.getPointer,
degreesToRadians = fabric.util.degreesToRadians,
slice = Array.prototype.slice;
if (fabric.Object) {
@ -7018,11 +7019,10 @@ fabric.util.animate = animate;
*/
_setCornerCoords: function() {
var coords = this.oCoords,
theta = fabric.util.degreesToRadians(45 - this.getAngle()),
theta = degreesToRadians(45 - this.getAngle()),
cornerHypotenuse = Math.sqrt(2 * Math.pow(this.cornersize, 2)) / 2,
cosHalfOffset = cornerHypotenuse * Math.cos(theta),
sinHalfOffset = cornerHypotenuse * Math.sin(theta),
corner;
sinHalfOffset = cornerHypotenuse * Math.sin(theta);
coords.tl.corner = {
tl: {
@ -7175,8 +7175,6 @@ fabric.util.animate = animate;
y: coords.mb.y + cosHalfOffset
}
};
corner = coords.mb.corner;
},
/**
@ -8636,15 +8634,18 @@ fabric.util.animate = animate;
* @method _parsePath
*/
_parsePath: function() {
var result = [],
var result = [ ],
currentPath,
chunks;
for (var i = 0, len = this.path.length; i < len; i++) {
for (var i = 0, j, chunksParsed, len = this.path.length; i < len; i++) {
currentPath = this.path[i];
chunks = currentPath.slice(1).trim().replace(/(\d)-/g, '$1###-').split(/\s|,|###/);
result.push([currentPath.charAt(0)].concat(chunks.map(parseFloat)));
j = chunks.length, chunksParsed = [ currentPath.charAt(0) ];
while (j--) {
chunksParsed[j+1] = parseFloat(chunks[j]);
}
result.push(chunksParsed);
}
return result;
},
@ -8740,7 +8741,7 @@ fabric.util.animate = animate;
*/
fabric.Path.fromElement = function(element, options) {
var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES);
return new fabric.Path(parsedAttributes.d, parsedAttributes ? extend(parsedAttributes, options) : undefined);
return new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options));
};
})(this);

View file

@ -8,6 +8,7 @@
toFixed = fabric.util.toFixed,
capitalize = fabric.util.string.capitalize,
getPointer = fabric.util.getPointer,
degreesToRadians = fabric.util.degreesToRadians,
slice = Array.prototype.slice;
if (fabric.Object) {
@ -955,11 +956,10 @@
*/
_setCornerCoords: function() {
var coords = this.oCoords,
theta = fabric.util.degreesToRadians(45 - this.getAngle()),
theta = degreesToRadians(45 - this.getAngle()),
cornerHypotenuse = Math.sqrt(2 * Math.pow(this.cornersize, 2)) / 2,
cosHalfOffset = cornerHypotenuse * Math.cos(theta),
sinHalfOffset = cornerHypotenuse * Math.sin(theta),
corner;
sinHalfOffset = cornerHypotenuse * Math.sin(theta);
coords.tl.corner = {
tl: {
@ -1112,8 +1112,6 @@
y: coords.mb.y + cosHalfOffset
}
};
corner = coords.mb.corner;
},
/**

View file

@ -402,16 +402,20 @@
* @method _parsePath
*/
_parsePath: function() {
var result = [],
var result = [ ],
currentPath,
chunks;
// use plain loop for perf.
for (var i = 0, len = this.path.length; i < len; i++) {
// use plain loop for performance reasons.
// this chunk of code can be called thousands of times per second (when parsing large shapes)
for (var i = 0, j, chunksParsed, len = this.path.length; i < len; i++) {
currentPath = this.path[i];
chunks = currentPath.slice(1).trim().replace(/(\d)-/g, '$1###-').split(/\s|,|###/);
result.push([currentPath.charAt(0)].concat(chunks.map(parseFloat)));
j = chunks.length, chunksParsed = [ currentPath.charAt(0) ];
while (j--) {
chunksParsed[j+1] = parseFloat(chunks[j]);
}
result.push(chunksParsed);
}
return result;
},

View file

@ -21,31 +21,6 @@
var logEl = document.getElementById('log');
(function testRaphael() {
var start = function () {
// storing original coordinates
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.attr({opacity: .5});
},
move = function (dx, dy) {
// move will be called with dx and dy
this.attr({cx: this.ox + dx, cy: this.oy + dy});
},
up = function () {
// restoring state
this.attr({opacity: 1});
};
var startTime = new Date();
var shape = Raphael(tiger).translate(200, 200);
shape.drag(start, move, up);
logEl.innerHTML = 'Raphael: <b>' + (new Date() - startTime) + '</b>ms<br>';
})();
(function testFabric() {
var canvas = window.__canvas = new fabric.Element('canvas', {
@ -78,10 +53,37 @@
canvas.calcOffset();
})();
(function testRaphael() {
var start = function () {
// storing original coordinates
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.attr({opacity: .5});
},
move = function (dx, dy) {
// move will be called with dx and dy
this.attr({cx: this.ox + dx, cy: this.oy + dy});
},
up = function () {
// restoring state
this.attr({opacity: 1});
};
var startTime = new Date();
var shape = Raphael(tiger).translate(200, 200);
shape.drag(start, move, up);
logEl.innerHTML = 'Raphael: <b>' + (new Date() - startTime) + '</b>ms<br>';
})();
};
</script>
</head>
<body>
<!-- preload svg -->
<iframe src="tiger2.svg" style="position:absolute;top:-999px;left:-999px"></iframe>
<p id="description">Rendering a complex shape</p>
<canvas id="canvas" width="600" height="600"></canvas>
<p id="log"></p>

View file

@ -29,6 +29,41 @@
var logEl = document.getElementById('log');
(function testFabric() {
var canvas = window.__canvas = new fabric.Element('canvas', {
renderOnAddition: false,
stateful: false
});
//console.profile('parsing');
canvas.loadSVGFromURL('dragon.svg', function(objects) {
//console.profileEnd('parsing');
var startTime = new Date();
var group = new fabric.PathGroup(objects, {
left: 185,
top: 380,
width: 371,
height: 760
});
canvas.add(group);
canvas.renderAll();
var renderingTime = new Date() - startTime;
logEl.innerHTML += 'fabric: <b>' + (fabric.documentParsingTime + renderingTime) +
'</b>ms (parsing: ' + fabric.documentParsingTime + ', rendering: ' + renderingTime + ')';
document.getElementById('description').appendChild(document.createTextNode(' (' + group.complexity() + ' paths)'))
});
canvas.calcOffset();
})();
(function testRaphael() {
var start = function () {
@ -56,42 +91,12 @@
logEl.innerHTML = 'Raphael: <b>' + (new Date() - startTime) + '</b>ms<br>';
})();
(function testFabric() {
var canvas = window.__canvas = new fabric.Element('canvas', {
renderOnAddition: false,
stateful: false
});
canvas.loadSVGFromURL('dragon.svg', function(objects) {
var startTime = new Date();
var group = new fabric.PathGroup(objects, {
left: 185,
top: 380,
width: 371,
height: 760
});
canvas.add(group);
canvas.renderAll();
var renderingTime = new Date() - startTime;
logEl.innerHTML += 'fabric: <b>' + (fabric.documentParsingTime + renderingTime) +
'</b>ms (parsing: ' + fabric.documentParsingTime + ', rendering: ' + renderingTime + ')';
document.getElementById('description').appendChild(document.createTextNode(' (' + group.complexity() + ' paths)'))
});
canvas.calcOffset();
})();
};
</script>
</head>
<body>
<!-- preload svg -->
<iframe src="dragon.svg" style="position:absolute;top:-999px;left:-999px"></iframe>
<p id="description">Rendering a complex shape</p>
<div id="holder"></div>
<canvas id="canvas" width="380" height="760"></canvas>