Commit 6e919dec by Dmitry Baranovskiy

Added support for angle of rotation in arc implementation, fixed various little…

Added support for angle of rotation in arc implementation, fixed various little bugs, added parameters support to path method.
parent a5da5534
...@@ -168,7 +168,7 @@ window.Raphael = (function () { ...@@ -168,7 +168,7 @@ window.Raphael = (function () {
var red, var red,
green, green,
blue, blue,
rgb = (colour + "").match(/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgb\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|rgb\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\)|hsb\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|hsb\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\))\s*$/i); rgb = (colour + "").match(/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgb\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|rgb\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\)|hs[bl]\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|hs[bl]\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\))\s*$/i);
if (rgb) { if (rgb) {
if (rgb[2]) { if (rgb[2]) {
blue = parseInt(rgb[2].substring(5), 16); blue = parseInt(rgb[2].substring(5), 16);
...@@ -244,7 +244,7 @@ window.Raphael = (function () { ...@@ -244,7 +244,7 @@ window.Raphael = (function () {
var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0}, var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0},
data = []; data = [];
if (R.isArray(pathString) && R.isArray(pathString[0])) { // rough assumption if (R.isArray(pathString) && R.isArray(pathString[0])) { // rough assumption
data = pathString; data = pathClone(pathString);
} }
if (!data.length) { if (!data.length) {
(pathString + "").replace(/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig, function (a, b, c) { (pathString + "").replace(/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig, function (a, b, c) {
...@@ -263,7 +263,7 @@ window.Raphael = (function () { ...@@ -263,7 +263,7 @@ window.Raphael = (function () {
} }
data.toString = R._path2string; data.toString = R._path2string;
return data; return data;
}, R); });
var pathDimensions = cacher(function (path) { var pathDimensions = cacher(function (path) {
path = path2curve(path); path = path2curve(path);
var x = 0, var x = 0,
...@@ -274,6 +274,8 @@ window.Raphael = (function () { ...@@ -274,6 +274,8 @@ window.Raphael = (function () {
if (path[i][0] == "M") { if (path[i][0] == "M") {
x = path[i][1]; x = path[i][1];
y = path[i][2]; y = path[i][2];
X.push(x);
Y.push(y);
} else { } else {
var dim = curveDim(x, y, path[i][1], path[i][2], path[i][3], path[i][4], path[i][5], path[i][6]); var dim = curveDim(x, y, path[i][1], path[i][2], path[i][3], path[i][4], path[i][5], path[i][6]);
X = X.concat(dim.min.x, dim.max.x); X = X.concat(dim.min.x, dim.max.x);
...@@ -289,6 +291,20 @@ window.Raphael = (function () { ...@@ -289,6 +291,20 @@ window.Raphael = (function () {
height: Math.max.apply(0, Y) - ymin height: Math.max.apply(0, Y) - ymin
}; };
}), }),
pathClone = function (pathArray) {
var res = [];
if (!R.isArray(pathArray) || !R.isArray(pathArray && pathArray[0])) { // rough assumption
pathArray = R.parsePathString(pathArray);
}
for (var i = 0, ii = pathArray.length; i < ii; i++) {
res[i] = [];
for (var j = 0, jj = pathArray[i].length; j < jj; j++) {
res[i][j] = pathArray[i][j];
}
}
res.toString = R._path2string;
return res;
},
pathToRelative = cacher(function (pathArray) { pathToRelative = cacher(function (pathArray) {
if (!R.isArray(pathArray) || !R.isArray(pathArray && pathArray[0])) { // rough assumption if (!R.isArray(pathArray) || !R.isArray(pathArray && pathArray[0])) { // rough assumption
pathArray = R.parsePathString(pathArray); pathArray = R.parsePathString(pathArray);
...@@ -362,21 +378,7 @@ window.Raphael = (function () { ...@@ -362,21 +378,7 @@ window.Raphael = (function () {
} }
res.toString = R._path2string; res.toString = R._path2string;
return res; return res;
}, null, pathClone), }, 0, pathClone),
pathClone = function (pathArray) {
var res = [];
if (!R.isArray(pathArray) || !R.isArray(pathArray && pathArray[0])) { // rough assumption
pathArray = R.parsePathString(pathArray);
}
for (var i = 0, ii = pathArray.length; i < ii; i++) {
res[i] = [];
for (var j = 0, jj = pathArray[i].length; j < jj; j++) {
res[i][j] = pathArray[i][j];
}
}
res.toString = R._path2string;
return res;
},
pathToAbsolute = cacher(function (pathArray) { pathToAbsolute = cacher(function (pathArray) {
if (!R.isArray(pathArray) || !R.isArray(pathArray && pathArray[0])) { // rough assumption if (!R.isArray(pathArray) || !R.isArray(pathArray && pathArray[0])) { // rough assumption
pathArray = R.parsePathString(pathArray); pathArray = R.parsePathString(pathArray);
...@@ -465,14 +467,31 @@ window.Raphael = (function () { ...@@ -465,14 +467,31 @@ window.Raphael = (function () {
// for more information of where this math came from visit: // for more information of where this math came from visit:
// http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
var _120 = Math.PI * 120 / 180, var _120 = Math.PI * 120 / 180,
res = []; rad = Math.PI / 180 * (+angle || 0),
res = [],
xy,
rotate = cacher(function (x, y, rad) {
var X = x * Math.cos(rad) - y * Math.sin(rad),
Y = x * Math.sin(rad) + y * Math.cos(rad);
return {x: X, y: Y};
});
if (!recursive) { if (!recursive) {
var x = (x1 - x2) / 2, xy = rotate(x1, y1, -rad);
y = (y1 - y2) / 2, x1 = xy.x;
rx2 = rx * rx, y1 = xy.y;
xy = rotate(x2, y2, -rad);
x2 = xy.x;
y2 = xy.y;
var cos = Math.cos(Math.PI / 180 * angle),
sin = Math.sin(Math.PI / 180 * angle),
x = (x1 - x2) / 2,
y = (y1 - y2) / 2;
rx = Math.max(rx, Math.abs(x));
ry = Math.max(ry, Math.abs(y));
var rx2 = rx * rx,
ry2 = ry * ry, ry2 = ry * ry,
k = (large_arc_flag == sweep_flag ? -1 : 1) * k = (large_arc_flag == sweep_flag ? -1 : 1) *
Math.sqrt(Math.abs(rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x)), Math.sqrt((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x)),
cx = k * rx * y / ry + (x1 + x2) / 2, cx = k * rx * y / ry + (x1 + x2) / 2,
cy = k * -ry * x / rx + (y1 + y2) / 2, cy = k * -ry * x / rx + (y1 + y2) / 2,
f1 = Math.asin((y1 - cy) / ry), f1 = Math.asin((y1 - cy) / ry),
...@@ -502,7 +521,7 @@ window.Raphael = (function () { ...@@ -502,7 +521,7 @@ window.Raphael = (function () {
f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1); f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
x2 = cx + rx * Math.cos(f2); x2 = cx + rx * Math.cos(f2);
y2 = cy + ry * Math.sin(f2); y2 = cy + ry * Math.sin(f2);
res = arguments.callee(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);
} }
var c1 = Math.cos(f1), var c1 = Math.cos(f1),
s1 = Math.sin(f1), s1 = Math.sin(f1),
...@@ -522,10 +541,11 @@ window.Raphael = (function () { ...@@ -522,10 +541,11 @@ window.Raphael = (function () {
return [m2, m3, m4].concat(res); return [m2, m3, m4].concat(res);
} else { } else {
res = [m2, m3, m4].concat(res).join(",").split(","); res = [m2, m3, m4].concat(res).join(",").split(",");
for (var i = res.length; i--;) { var newres = [];
res[i] = +res[i]; for (var i = 0, ii = res.length; i < ii; i++) {
newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;
} }
return res; return newres;
} }
}, },
findDotAtSegment = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { findDotAtSegment = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
...@@ -654,7 +674,7 @@ window.Raphael = (function () { ...@@ -654,7 +674,7 @@ window.Raphael = (function () {
attrs2.y = p2 && seg2[seg2len - 1]; attrs2.y = p2 && seg2[seg2len - 1];
} }
return p2 ? [p, p2] : p; return p2 ? [p, p2] : p;
}), }, null, pathClone),
toGradient = cacher(function (gradient) { toGradient = cacher(function (gradient) {
if (typeof gradient == "string") { if (typeof gradient == "string") {
gradient = gradient.split(/\s*\-\s*/); gradient = gradient.split(/\s*\-\s*/);
...@@ -679,10 +699,10 @@ window.Raphael = (function () { ...@@ -679,10 +699,10 @@ window.Raphael = (function () {
grobj.vector[1] = -grobj.vector[3]; grobj.vector[1] = -grobj.vector[3];
grobj.vector[3] = 0; grobj.vector[3] = 0;
} }
grobj.vector[0] = grobj.vector[0].toFixed(3); grobj.vector[0] = grobj.vector[0];
grobj.vector[1] = grobj.vector[1].toFixed(3); grobj.vector[1] = grobj.vector[1];
grobj.vector[2] = grobj.vector[2].toFixed(3); grobj.vector[2] = grobj.vector[2];
grobj.vector[3] = grobj.vector[3].toFixed(3); grobj.vector[3] = grobj.vector[3];
for (var i = 0, ii = gradient.length; i < ii; i++) { for (var i = 0, ii = gradient.length; i < ii; i++) {
var dot = {}, var dot = {},
par = gradient[i].match(/^([^:]*):?([\d\.]*)/); par = gradient[i].match(/^([^:]*):?([\d\.]*)/);
...@@ -787,13 +807,10 @@ window.Raphael = (function () { ...@@ -787,13 +807,10 @@ window.Raphael = (function () {
}; };
var thePath = function (pathString, SVG) { var thePath = function (pathString, SVG) {
var el = doc.createElementNS(SVG.svgns, "path"); var el = doc.createElementNS(SVG.svgns, "path");
if (SVG.canvas) { SVG.canvas && SVG.canvas.appendChild(el);
SVG.canvas.appendChild(el);
}
var p = new Element(el, SVG); var p = new Element(el, SVG);
p.type = "path"; p.type = "path";
pathString && (p.attrs.path = roundPath(pathToAbsolute(pathString))) && p.node.setAttribute("d", p.attrs.path); setFillAndStroke(p, {fill: "none", stroke: "#000", path: pathString});
setFillAndStroke(p, {fill: "none", stroke: "#000"});
return p; return p;
}; };
var addGradientFill = function (o, gradient, SVG) { var addGradientFill = function (o, gradient, SVG) {
...@@ -885,7 +902,7 @@ window.Raphael = (function () { ...@@ -885,7 +902,7 @@ window.Raphael = (function () {
pn.setAttributeNS(o.paper.xlink, att, value); pn.setAttributeNS(o.paper.xlink, att, value);
break; break;
case "path": case "path":
if (o.type == "path") { if (value && o.type == "path") {
attrs.path = roundPath(pathToAbsolute(value)); attrs.path = roundPath(pathToAbsolute(value));
node.setAttribute("d", attrs.path); node.setAttribute("d", attrs.path);
} }
...@@ -1132,6 +1149,9 @@ window.Raphael = (function () { ...@@ -1132,6 +1149,9 @@ window.Raphael = (function () {
this.node.parentNode.removeChild(this.node); this.node.parentNode.removeChild(this.node);
}; };
Element.prototype.getBBox = function () { Element.prototype.getBBox = function () {
if (this.type == "path") {
return pathDimensions(this.attrs.path);
}
if (this.node.style.display == "none") { if (this.node.style.display == "none") {
this.show(); this.show();
var hide = true; var hide = true;
...@@ -1556,8 +1576,7 @@ window.Raphael = (function () { ...@@ -1556,8 +1576,7 @@ window.Raphael = (function () {
a["font-size"] && (s.fontSize = a["font-size"]); a["font-size"] && (s.fontSize = a["font-size"]);
a["font-weight"] && (s.fontWeight = a["font-weight"]); a["font-weight"] && (s.fontWeight = a["font-weight"]);
a["font-style"] && (s.fontStyle = a["font-style"]); a["font-style"] && (s.fontStyle = a["font-style"]);
paper.span.innerHTML = ""; paper.span.innerHTML = res.node.string.replace(/</g, "&#60;").replace(/&/g, "&#38;").replace(/\n/g, "<br>");
paper.span.appendChild(doc.createTextNode(res.node.string));
res.W = a.w = paper.span.offsetWidth; res.W = a.w = paper.span.offsetWidth;
res.H = a.h = paper.span.offsetHeight; res.H = a.h = paper.span.offsetHeight;
res.X = a.x; res.X = a.x;
...@@ -1734,7 +1753,7 @@ window.Raphael = (function () { ...@@ -1734,7 +1753,7 @@ window.Raphael = (function () {
w = this.paper.width; w = this.paper.width;
h = this.paper.height; h = this.paper.height;
} else { } else {
var dim = pathDimensions(this.attrs.path), var dim = pathDimensions(this.attrs.path);
x = dim.x; x = dim.x;
y = dim.y; y = dim.y;
w = dim.width; w = dim.width;
...@@ -2023,9 +2042,7 @@ window.Raphael = (function () { ...@@ -2023,9 +2042,7 @@ window.Raphael = (function () {
}; };
doc.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)"); doc.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)");
try { try {
if (!doc.namespaces.rvml) { !doc.namespaces.rvml && doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml");
doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml");
}
var createNode = function (tagName) { var createNode = function (tagName) {
return doc.createElement('<rvml:' + tagName + ' class="rvml">'); return doc.createElement('<rvml:' + tagName + ' class="rvml">');
}; };
...@@ -2037,11 +2054,11 @@ window.Raphael = (function () { ...@@ -2037,11 +2054,11 @@ window.Raphael = (function () {
var create = function () { var create = function () {
var con = getContainer.apply(null, arguments), var con = getContainer.apply(null, arguments),
container = con.container, container = con.container,
x = con.x, height = con.height,
y = con.y,
width = con.width,
s, s,
height = con.height; width = con.width,
x = con.x,
y = con.y;
if (!container) { if (!container) {
throw new Error("VML container not found."); throw new Error("VML container not found.");
} }
...@@ -2179,6 +2196,10 @@ window.Raphael = (function () { ...@@ -2179,6 +2196,10 @@ window.Raphael = (function () {
return theEllipse(this, x, y, rx, ry); return theEllipse(this, x, y, rx, ry);
}; };
paper.path = function (pathString) { paper.path = function (pathString) {
var args = arguments;
pathString && args.length - 1 && (pathString = pathString.replace(/\{(\d+)\}/g, function (str, i) {
return args[++i] || 0;
}));
return thePath(pathString, this); return thePath(pathString, this);
}; };
paper.image = function (src, x, y, w, h) { paper.image = function (src, x, y, w, h) {
...@@ -2309,6 +2330,7 @@ window.Raphael = (function () { ...@@ -2309,6 +2330,7 @@ window.Raphael = (function () {
return this; return this;
}; };
// animation easing formulas
R.easing_formulas = { R.easing_formulas = {
linear: function (n) { linear: function (n) {
return n; return n;
...@@ -2329,12 +2351,12 @@ window.Raphael = (function () { ...@@ -2329,12 +2351,12 @@ window.Raphael = (function () {
}, },
backIn: function (n) { backIn: function (n) {
var s = 1.70158; var s = 1.70158;
return Math.pow(n, 2) * ((s + 1) * n - s); return n * n * ((s + 1) * n - s);
}, },
backOut: function (n) { backOut: function (n) {
n = n - 1; n = n - 1;
var s = 1.70158; var s = 1.70158;
return Math.pow(n, 2) * ((s + 1) * n + s) + 1; return n * n * ((s + 1) * n + s) + 1;
}, },
elastic: function (n) { elastic: function (n) {
if (n == 0 || n == 1) { if (n == 0 || n == 1) {
...@@ -2349,18 +2371,18 @@ window.Raphael = (function () { ...@@ -2349,18 +2371,18 @@ window.Raphael = (function () {
p = 2.75, p = 2.75,
l; l;
if (n < (1 / p)) { if (n < (1 / p)) {
l = s * Math.pow(n, 2); l = s * n * n;
} else { } else {
if (n < (2 / p)) { if (n < (2 / p)) {
n -= (1.5 / p); n -= (1.5 / p);
l = s * Math.pow(n, 2) + .75; l = s * n * n + .75;
} else { } else {
if (n < (2.5 / p)) { if (n < (2.5 / p)) {
n -= (2.25 / p); n -= (2.25 / p);
l = s * Math.pow(n, 2) + .9375; l = s * n * n + .9375;
} else { } else {
n -= (2.625 / p); n -= (2.625 / p);
l = s * Math.pow(n, 2) + .984375; l = s * n * n + .984375;
} }
} }
} }
...@@ -2368,11 +2390,6 @@ window.Raphael = (function () { ...@@ -2368,11 +2390,6 @@ window.Raphael = (function () {
} }
}; };
// animation easing formulas
R.easing = function(easing, n) {
return R.easing_formulas[easing] ? R.easing_formulas[easing](n) : n;
};
Element.prototype.animate = function (params, ms, easing, callback) { Element.prototype.animate = function (params, ms, easing, callback) {
clearTimeout(this.animation_in_progress); clearTimeout(this.animation_in_progress);
if (typeof easing == "function" || !easing) { if (typeof easing == "function" || !easing) {
...@@ -2444,7 +2461,7 @@ window.Raphael = (function () { ...@@ -2444,7 +2461,7 @@ window.Raphael = (function () {
set = {}, set = {},
now; now;
if (time < ms) { if (time < ms) {
var pos = R.easing(easing, time / ms); var pos = R.easing_formulas[easing] ? R.easing_formulas[easing](time / ms) : time / ms;
for (var attr in from) { for (var attr in from) {
switch (availableAnimAttrs[attr]) { switch (availableAnimAttrs[attr]) {
case "number": case "number":
...@@ -2554,15 +2571,6 @@ window.Raphael = (function () { ...@@ -2554,15 +2571,6 @@ window.Raphael = (function () {
} }
return this; return this;
}; };
Set.prototype.pop = function (id) {
var res = this.items.splice(id, 1)[0];
for (var j = id, jj = this.items.length; j < jj; j++) {
this[j] = this[j + 1];
}
delete this[jj + 1];
this.length--;
return res;
};
for (var method in Element.prototype) { for (var method in Element.prototype) {
Set.prototype[method] = (function (methodname) { Set.prototype[method] = (function (methodname) {
return function () { return function () {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment