Created
July 26, 2012 11:24
-
-
Save willmcneilly/3181555 to your computer and use it in GitHub Desktop.
Fabric consecutive 't' paths fix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @private | |
* @method _render | |
*/ | |
_render: function(ctx) { | |
var current, // current instruction | |
previous = null, | |
x = 0, // current x | |
y = 0, // current y | |
controlX = 0, // current control point x | |
controlY = 0, // current control point y | |
tempX, | |
tempY, | |
tempControlX, | |
tempControlY, | |
l = -(this.width / 2), | |
t = -(this.height / 2); | |
for (var i = 0, len = this.path.length; i < len; ++i) { | |
current = this.path[i]; | |
switch (current[0]) { // first letter | |
case 'l': // lineto, relative | |
x += current[1]; | |
y += current[2]; | |
ctx.lineTo(x + l, y + t); | |
break; | |
case 'L': // lineto, absolute | |
x = current[1]; | |
y = current[2]; | |
ctx.lineTo(x + l, y + t); | |
break; | |
case 'h': // horizontal lineto, relative | |
x += current[1]; | |
ctx.lineTo(x + l, y + t); | |
break; | |
case 'H': // horizontal lineto, absolute | |
x = current[1]; | |
ctx.lineTo(x + l, y + t); | |
break; | |
case 'v': // vertical lineto, relative | |
y += current[1]; | |
ctx.lineTo(x + l, y + t); | |
break; | |
case 'V': // verical lineto, absolute | |
y = current[1]; | |
ctx.lineTo(x + l, y + t); | |
break; | |
case 'm': // moveTo, relative | |
x += current[1]; | |
y += current[2]; | |
ctx.moveTo(x + l, y + t); | |
break; | |
case 'M': // moveTo, absolute | |
x = current[1]; | |
y = current[2]; | |
ctx.moveTo(x + l, y + t); | |
break; | |
case 'c': // bezierCurveTo, relative | |
tempX = x + current[5]; | |
tempY = y + current[6]; | |
controlX = x + current[3]; | |
controlY = y + current[4]; | |
ctx.bezierCurveTo( | |
x + current[1] + l, // x1 | |
y + current[2] + t, // y1 | |
controlX + l, // x2 | |
controlY + t, // y2 | |
tempX + l, | |
tempY + t | |
); | |
x = tempX; | |
y = tempY; | |
break; | |
case 'C': // bezierCurveTo, absolute | |
x = current[5]; | |
y = current[6]; | |
controlX = current[3]; | |
controlY = current[4]; | |
ctx.bezierCurveTo( | |
current[1] + l, | |
current[2] + t, | |
controlX + l, | |
controlY + t, | |
x + l, | |
y + t | |
); | |
break; | |
case 's': // shorthand cubic bezierCurveTo, relative | |
// transform to absolute x,y | |
tempX = x + current[3]; | |
tempY = y + current[4]; | |
// calculate reflection of previous control points | |
controlX = 2 * x - controlX; | |
controlY = 2 * y - controlY; | |
ctx.bezierCurveTo( | |
controlX + l, | |
controlY + t, | |
x + current[1] + l, | |
y + current[2] + t, | |
tempX + l, | |
tempY + t | |
); | |
// set control point to 2nd one of this command | |
// "... the first control point is assumed to be the reflection of the second control point on the previous command relative to the current point." | |
controlX = x + current[1]; | |
controlY = y + current[2]; | |
x = tempX; | |
y = tempY; | |
break; | |
case 'S': // shorthand cubic bezierCurveTo, absolute | |
tempX = current[3]; | |
tempY = current[4]; | |
// calculate reflection of previous control points | |
controlX = 2*x - controlX; | |
controlY = 2*y - controlY; | |
ctx.bezierCurveTo( | |
controlX + l, | |
controlY + t, | |
current[1] + l, | |
current[2] + t, | |
tempX + l, | |
tempY + t | |
); | |
x = tempX; | |
y = tempY; | |
// set control point to 2nd one of this command | |
// "... the first control point is assumed to be the reflection of the second control point on the previous command relative to the current point." | |
controlX = current[1]; | |
controlY = current[2]; | |
break; | |
case 'q': // quadraticCurveTo, relative | |
// transform to absolute x,y | |
tempX = x + current[3]; | |
tempY = y + current[4]; | |
controlX = x + current[1]; | |
controlY = y + current[2]; | |
ctx.quadraticCurveTo( | |
controlX + l, | |
controlY + t, | |
tempX + l, | |
tempY + t | |
); | |
x = tempX; | |
y = tempY; | |
break; | |
case 'Q': // quadraticCurveTo, absolute | |
tempX = current[3]; | |
tempY = current[4]; | |
ctx.quadraticCurveTo( | |
current[1] + l, | |
current[2] + t, | |
tempX + l, | |
tempY + t | |
); | |
x = tempX; | |
y = tempY; | |
controlX = current[1]; | |
controlY = current[2]; | |
break; | |
case 't': // shorthand quadraticCurveTo, relative | |
// transform to absolute x,y | |
tempX = x + current[1]; | |
tempY = y + current[2]; | |
if (previous === null || previous[0].match(/[QqTt]/) === null) { | |
// If there is no previous command or if the previous command was not a Q, q, T or t, | |
// assume the control point is coincident with the current poin | |
controlX = x; | |
controlY = y; | |
} | |
else if (previous[0] === 't') { | |
// calculate reflection of previous control points for t | |
controlX = 2 * x - tempControlX; | |
controlY = 2 * y - tempControlY; | |
} | |
else if (previous[0] === 'q') { | |
// calculate reflection of previous control points for q | |
controlX = 2 * x - controlX; | |
controlY = 2 * y - controlY; | |
} | |
tempControlX = controlX; | |
tempControlY = controlY; | |
ctx.quadraticCurveTo( | |
controlX + l, | |
controlY + t, | |
tempX + l, | |
tempY + t | |
); | |
x = tempX; | |
y = tempY; | |
controlX = x + current[1]; | |
controlY = y + current[2]; | |
break; | |
case 'T': | |
tempX = current[1]; | |
tempY = current[2]; | |
// calculate reflection of previous control points | |
controlX = 2 * x - controlX; | |
controlY = 2 * y - controlY; | |
ctx.quadraticCurveTo( | |
controlX + l, | |
controlY + t, | |
tempX + l, | |
tempY + t | |
); | |
x = tempX; | |
y = tempY; | |
break; | |
case 'a': | |
// TODO: optimize this | |
drawArc(ctx, x + l, y + t, [ | |
current[1], | |
current[2], | |
current[3], | |
current[4], | |
current[5], | |
current[6] + x + l, | |
current[7] + y + t | |
]); | |
x += current[6]; | |
y += current[7]; | |
break; | |
case 'A': | |
// TODO: optimize this | |
drawArc(ctx, x + l, y + t, [ | |
current[1], | |
current[2], | |
current[3], | |
current[4], | |
current[5], | |
current[6] + l, | |
current[7] + t | |
]); | |
x = current[6]; | |
y = current[7]; | |
break; | |
case 'z': | |
case 'Z': | |
ctx.closePath(); | |
break; | |
} | |
previous = current | |
} | |
}, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment