mirror of
https://github.com/konvajs/konva.git
synced 2025-11-18 17:21:36 +08:00
Added multi-point string handling to the path parser. Added support for 'm' and 'Z'.
This commit is contained in:
@@ -26,7 +26,11 @@ Kinetic.Path = function(config) {
|
||||
break;
|
||||
case 'M':
|
||||
context.moveTo(p[0], p[1]);
|
||||
c = 'L'; // Subsequent points are treated as lineTo
|
||||
break;
|
||||
//case 'C':
|
||||
// context.bezierCurveTo(p[0], p[1], p[2], p[3], path[i].p.x, path[i].p.y);
|
||||
|
||||
case 'z':
|
||||
context.closePath();
|
||||
break;
|
||||
@@ -51,10 +55,29 @@ Kinetic.Path.prototype = {
|
||||
* rendering
|
||||
*/
|
||||
getCommandsArray: function() {
|
||||
|
||||
// Path Data Segment must begin with a moveTo
|
||||
//m (x y)+ Relative moveTo (subsequent points are treated as lineTo)
|
||||
//M (x y)+ Absolute moveTo (subsequent points are treated as lineTo)
|
||||
//l (x y)+ Relative lineTo
|
||||
//L (x y)+ Absolute LineTo
|
||||
//h (x)+ Relative horizontal lineTo
|
||||
//H (x)+ Absolute horizontal lineTo
|
||||
//v (y)+ Relative vertical lineTo
|
||||
//V (y)+ Absolute vertical lineTo
|
||||
//z (closepath)
|
||||
//Z (closepath)
|
||||
//c (x1 y1 x2 y2 x y)+ Relative Bezier curve
|
||||
//C (x1 y1 x2 y2 x y)+ Absolute Bezier curve
|
||||
//q (x1 y1 x y)+ Relative Quadratic Bezier
|
||||
//Q (x1 y1 x y)+ Absolute Quadratic Bezier
|
||||
// Note: SVG s,S,t,T,a,A not implemented here
|
||||
|
||||
|
||||
// command string
|
||||
var cs = this.attrs.commands;
|
||||
// command chars
|
||||
var cc = ['M', 'l', 'L', 'v', 'V', 'h', 'H', 'z'];
|
||||
var cc = ['m', 'M', 'l', 'L', 'v', 'V', 'h', 'H', 'z', 'Z'];
|
||||
// convert white spaces to commas
|
||||
cs = cs.replace(new RegExp(' ', 'g'), ',');
|
||||
// create pipes so that we can split the commands
|
||||
@@ -83,44 +106,68 @@ Kinetic.Path.prototype = {
|
||||
for(var i = 0; i < p.length; i++) {
|
||||
p[i] = parseFloat(p[i]);
|
||||
}
|
||||
|
||||
while (p.length > 0)
|
||||
{
|
||||
if (isNaN(p[0])) // case for a trailing comma before next command
|
||||
break;
|
||||
|
||||
var cmd = undefined;
|
||||
|
||||
// convert l, H, h, V, and v to L
|
||||
switch(c) {
|
||||
case 'm':
|
||||
cmd = 'M';
|
||||
cpx += p.shift();
|
||||
cpy += p.shift();
|
||||
c = 'l'; // subsequent points are treated as relative lineTo
|
||||
break;
|
||||
case 'M':
|
||||
cpx = p[0];
|
||||
cpy = p[1];
|
||||
cmd = 'M';
|
||||
cpx = p.shift();
|
||||
cpy = p.shift();
|
||||
c = 'L'; // subsequent points are treated as absolute lineTo
|
||||
break;
|
||||
case 'l':
|
||||
cpx += p[0];
|
||||
cpy += p[1];
|
||||
cmd = 'L';
|
||||
cpx += p.shift();
|
||||
cpy += p.shift();
|
||||
break;
|
||||
case 'L':
|
||||
cpx = p[0];
|
||||
cpy = p[1];
|
||||
cmd = 'L';
|
||||
cpx = p.shift();
|
||||
cpy = p.shift();
|
||||
break;
|
||||
case 'h':
|
||||
cpx += p[0];
|
||||
cmd = 'L';
|
||||
cpx += p.shift();
|
||||
break;
|
||||
case 'H':
|
||||
cpx = p[0];
|
||||
cmd = 'L';
|
||||
cpx = p.shift();
|
||||
break;
|
||||
case 'v':
|
||||
cpy += p[0];
|
||||
cmd = 'L';
|
||||
cpy += p.shift();
|
||||
break;
|
||||
case 'V':
|
||||
cpy = p[0];
|
||||
cmd = 'L';
|
||||
cpy = p.shift();
|
||||
break;
|
||||
}
|
||||
// reassign command
|
||||
if(c == 'l' || c == 'V' || c == 'v' || c == 'H' || c == 'h') {
|
||||
c = 'L';
|
||||
p[0] = cpx;
|
||||
p[1] = cpy;
|
||||
}
|
||||
|
||||
ca.push({
|
||||
command: c,
|
||||
points: p
|
||||
command: cmd || c,
|
||||
points: [cpx, cpy] // Need to add additional points if curves, etc.
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if (c === 'z' || c === 'Z')
|
||||
ca.push( {command: 'z', points: [] });
|
||||
}
|
||||
|
||||
|
||||
return ca;
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -1226,6 +1226,50 @@ Test.prototype.tests = {
|
||||
|
||||
path.setCommands('M200,100h100v50z');
|
||||
|
||||
},
|
||||
'SHAPE - moveTo with implied lineTos and trailing comma': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 1024,
|
||||
height: 480,
|
||||
scale: 0.5,
|
||||
x: 50,
|
||||
y: 10
|
||||
});
|
||||
var layer = new Kinetic.Layer();
|
||||
|
||||
var path = new Kinetic.Path({
|
||||
commands: 'm200,100,100,0,0,50,z',
|
||||
fill: '#fcc',
|
||||
stroke: '#333',
|
||||
strokeWidth: 2,
|
||||
shadow: {
|
||||
color: 'maroon',
|
||||
blur: 2,
|
||||
offset: [10, 10],
|
||||
alpha: 0.5
|
||||
},
|
||||
draggable: true
|
||||
});
|
||||
|
||||
path.on('mouseover', function() {
|
||||
this.setFill('red');
|
||||
layer.draw();
|
||||
});
|
||||
|
||||
path.on('mouseout', function() {
|
||||
this.setFill('#ccc');
|
||||
layer.draw();
|
||||
});
|
||||
|
||||
layer.add(path);
|
||||
|
||||
stage.add(layer);
|
||||
|
||||
test(path.getCommands() === 'm200,100,100,0,0,50,z', 'commands are incorrect');
|
||||
test(path.getCommandsArray().length === 4, 'commands array should have 4 elements');
|
||||
|
||||
test(path.getCommandsArray()[1].command === 'L', 'second command should be an implied lineTo');
|
||||
},
|
||||
'SHAPE - add map path': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
|
||||
Reference in New Issue
Block a user