first round of new Path shape. Despite multiple optimizations, the path performance isn't as good as a previous experiment done with v3.8.1. Will keep this as a separate branch until the performance issues are resolved

This commit is contained in:
Eric Rowell 2012-05-27 21:46:03 -07:00
parent 4488f22c32
commit cc35abd0f6
8 changed files with 484 additions and 3 deletions

View File

@ -6,7 +6,7 @@ class Build < Thor
"license.js", "src/GlobalObject.js", "src/Node.js", "src/Container.js", "src/Stage.js",
"src/Layer.js", "src/Group.js", "src/Shape.js", "src/shapes/Rect.js", "src/shapes/Circle.js", "src/shapes/Image.js",
"src/shapes/Sprite.js", "src/shapes/Polygon.js", "src/shapes/RegularPolygon.js", "src/shapes/Star.js", "src/shapes/Text.js",
"src/shapes/Line.js", "src/util/Transform.js", "src/util/Transition.js"
"src/shapes/Line.js", "src/shapes/Path.js", "src/util/Transform.js", "src/util/Transition.js"
]
desc "dev", "Concatenate all the js files into /dist/kinetic-VERSION.js."

133
dist/kinetic-core.js vendored
View File

@ -4047,6 +4047,139 @@ Kinetic.Line.prototype = {
// extend Shape
Kinetic.GlobalObject.extend(Kinetic.Line, Kinetic.Shape);
///////////////////////////////////////////////////////////////////////
// SVG Path
///////////////////////////////////////////////////////////////////////
/**
* Path constructor. This shape was inspired by jfollas's
* SVG Path plugin
* @constructor
* @augments Kinetic.Shape
* @param {Object} config
*/
Kinetic.Path = function(config) {
this.shapeType = "Path";
this.commandsArray = [];
config.drawFunc = function() {
var context = this.getContext();
var ca = this.commandsArray;
// context position
var cpx = 0;
var cpy = 0;
context.beginPath();
for(var n = 0; n < ca.length; n++) {
var c = ca[n].command;
var p = ca[n].points;
switch(c) {
case 'M':
context.moveTo(p[0], p[1]);
break;
case 'L':
context.lineTo(p[0], p[1]);
break;
case 'z':
break;
}
}
context.closePath();
//this.fill();
context.fillStyle = '#999';
context.fill();
context.strokeStyle = '#555';
context.stroke();
//this.stroke();
};
// call super constructor
Kinetic.Shape.apply(this, [config]);
this.setCommandsArray();
};
/*
* Path methods
*/
Kinetic.Path.prototype = {
setCommandsArray: function() {
var c = this.attrs.commands;
// command chars
var cc = ['M', 'l', 'L', 'v', 'V', 'h', 'H', 'z'];
// remove white spaces
c = c.replace(new RegExp(' ', 'g'), '');
for(var n = 0; n < cc.length; n++) {
c = c.replace(new RegExp(cc[n], 'g'), '|' + cc[n]);
}
var arr = c.split('|');
var ca = [];
for(var n = 1; n < arr.length; n++) {
var str = arr[n];
var command = str.charAt(0);
str = str.slice(1);
// remove ,- for consistency
str = str.replace(new RegExp(',-', 'g'), '-');
// add commas so that it's easy to split
str = str.replace(new RegExp('-', 'g'), ',-');
var points = str.split(',');
if(points.length > 0 && points[0] === '') {
points.shift();
}
// convert strings to floats
for(var i = 0; i < points.length; i++) {
points[i] = parseFloat(points[i]);
}
ca.push({
command: command,
points: points
});
}
// convert l, h, and v to L
var cpx = 0;
var cpy = 0;
for(var n = 0; n < ca.length; n++) {
var c = ca[n].command;
var p = ca[n].points;
// update context point
switch(c) {
case 'M':
cpx = p[0];
cpy = p[1];
break;
case 'l':
cpx += p[0];
cpy += p[1];
break;
case 'L':
cpx = p[0];
cpy = p[1];
break;
case 'h':
cpx += p[0];
break;
case 'H':
cpx = p[0];
break;
case 'v':
cpy += p[0];
break;
case 'V':
cpy = p[0];
break;
}
// reassign command
if(c !== 'L' && c !== 'M') {
ca[n].command = 'L';
ca[n].points[0] = cpx;
ca[n].points[1] = cpy;
}
}
this.commandsArray = ca;
}
};
// extend Shape
Kinetic.GlobalObject.extend(Kinetic.Path, Kinetic.Shape);
/*
* Last updated November 2011
* By Simon Sarris

File diff suppressed because one or more lines are too long

132
src/shapes/Path.js Normal file
View File

@ -0,0 +1,132 @@
///////////////////////////////////////////////////////////////////////
// SVG Path
///////////////////////////////////////////////////////////////////////
/**
* Path constructor. This shape was inspired by jfollas's
* SVG Path plugin
* @constructor
* @augments Kinetic.Shape
* @param {Object} config
*/
Kinetic.Path = function(config) {
this.shapeType = "Path";
this.commandsArray = [];
config.drawFunc = function() {
var context = this.getContext();
var ca = this.commandsArray;
// context position
var cpx = 0;
var cpy = 0;
context.beginPath();
for(var n = 0; n < ca.length; n++) {
var c = ca[n].command;
var p = ca[n].points;
switch(c) {
case 'M':
context.moveTo(p[0], p[1]);
break;
case 'L':
context.lineTo(p[0], p[1]);
break;
case 'z':
break;
}
}
context.closePath();
//this.fill();
context.fillStyle = '#999';
context.fill();
context.strokeStyle = '#555';
context.stroke();
//this.stroke();
};
// call super constructor
Kinetic.Shape.apply(this, [config]);
this.setCommandsArray();
};
/*
* Path methods
*/
Kinetic.Path.prototype = {
setCommandsArray: function() {
var c = this.attrs.commands;
// command chars
var cc = ['M', 'l', 'L', 'v', 'V', 'h', 'H', 'z'];
// remove white spaces
c = c.replace(new RegExp(' ', 'g'), '');
for(var n = 0; n < cc.length; n++) {
c = c.replace(new RegExp(cc[n], 'g'), '|' + cc[n]);
}
var arr = c.split('|');
var ca = [];
for(var n = 1; n < arr.length; n++) {
var str = arr[n];
var command = str.charAt(0);
str = str.slice(1);
// remove ,- for consistency
str = str.replace(new RegExp(',-', 'g'), '-');
// add commas so that it's easy to split
str = str.replace(new RegExp('-', 'g'), ',-');
var points = str.split(',');
if(points.length > 0 && points[0] === '') {
points.shift();
}
// convert strings to floats
for(var i = 0; i < points.length; i++) {
points[i] = parseFloat(points[i]);
}
ca.push({
command: command,
points: points
});
}
// convert l, h, and v to L
var cpx = 0;
var cpy = 0;
for(var n = 0; n < ca.length; n++) {
var c = ca[n].command;
var p = ca[n].points;
// update context point
switch(c) {
case 'M':
cpx = p[0];
cpy = p[1];
break;
case 'l':
cpx += p[0];
cpy += p[1];
break;
case 'L':
cpx = p[0];
cpy = p[1];
break;
case 'h':
cpx += p[0];
break;
case 'H':
cpx = p[0];
break;
case 'v':
cpy += p[0];
break;
case 'V':
cpy = p[0];
break;
}
// reassign command
if(c !== 'L' && c !== 'M') {
ca[n].command = 'L';
ca[n].points[0] = cpx;
ca[n].points[1] = cpy;
}
}
this.commandsArray = ca;
}
};
// extend Shape
Kinetic.GlobalObject.extend(Kinetic.Path, Kinetic.Shape);

177
tests/assets/worldMap.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" type="text/css"href="../base.css">
<script src="../../dist/kinetic-core.js"></script>
<script src="../assets/worldMap.js"></script>
<script src="../js/Test.js"></script>
<script src="../js/unitTests.js"></script>
<script>

View File

@ -16,7 +16,7 @@ function log(message) {
* Test constructor
*/
function Test() {
this.testOnly = '';
this.testOnly = 'SHAPE - add path';
this.counter = 0;
testCounter = document.createElement('div');

View File

@ -1169,6 +1169,44 @@ Test.prototype.tests = {
});
//stage.start();
},
'SHAPE - add path': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 1024,
height: 480
});
var layer = new Kinetic.Layer();
for(var key in worldMap) {
var c = worldMap[key];
// induce scope
( function() {
var path = new Kinetic.Path({
commands: c,
fill: '#ccc',
stroke: '#999',
strokeWidth: 1
});
path.on('mouseover', function() {
//console.log(1)
//path.setFill('red');
//layer.draw();
});
path.on('mouseout', function() {
//path.setFill('#ccc');
//layer.draw();
});
layer.add(path);
}());
stage.add(layer);
}
},
'SHAPE - add shape with custom attr pointing to self': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,