Commit 89046d5b by Dmitry Baranovskiy

Add pattern support and rewrite dashed lines support. Move closer to VML implementation.

parent e41b27fb
...@@ -271,7 +271,15 @@ var Raphael = (function (type) { ...@@ -271,7 +271,15 @@ var Raphael = (function (type) {
fill.on = false; fill.on = false;
} }
if (fill.on && params.fill) { if (fill.on && params.fill) {
fill.color = params.fill; var isURL = params.fill.match(/^url\(([^\)]+)\)$/i);
if (isURL) {
fill.src = isURL[1];
fill.type = "tile";
} else {
fill.color = params.fill;
fill.src = "";
fill.type = "solid";
}
} }
o.appendChild(fill); o.appendChild(fill);
var stroke = (o.getElementsByTagName("stroke") && o.getElementsByTagName("stroke")[0]) || document.createElement("rvml:stroke"); var stroke = (o.getElementsByTagName("stroke") && o.getElementsByTagName("stroke")[0]) || document.createElement("rvml:stroke");
...@@ -290,16 +298,19 @@ var Raphael = (function (type) { ...@@ -290,16 +298,19 @@ var Raphael = (function (type) {
params["stroke-linecap"] && (stroke.endcap = {butt: "flat", square: "square", round: "round"}[params["stroke-linecap"]] || "miter"); params["stroke-linecap"] && (stroke.endcap = {butt: "flat", square: "square", round: "round"}[params["stroke-linecap"]] || "miter");
params["stroke-width"] && (stroke.weight = (parseFloat(params["stroke-width"], 10) || 1) * 12 / 16); params["stroke-width"] && (stroke.weight = (parseFloat(params["stroke-width"], 10) || 1) * 12 / 16);
if (params["stroke-dasharray"]) { if (params["stroke-dasharray"]) {
var dashes = params["stroke-dasharray"].replace(" ", ",").split(","), var dasharray = {
dashesn = [], "-": "shortdash",
str = stroke.weight; ".": "shortdot",
for (var i = 0, ii = dashes.length; i < ii; i++) { "-.": "shortdashdot",
var res = dashes[i] / str; "-..": "shortdashdotdot",
if (!isNaN(res)) { ". ": "dot",
dashesn.push(res); "- ": "dash",
} "--": "longdash",
"- .": "dashdot",
"--.": "longdashdot",
"--..": "longdashdotdot"
}; };
stroke.dashstyle = dashesn.join(" "); stroke.dashstyle = dasharray[params["stroke-dasharray"]] || "";
} }
o.appendChild(stroke); o.appendChild(stroke);
} }
...@@ -316,37 +327,37 @@ var Raphael = (function (type) { ...@@ -316,37 +327,37 @@ var Raphael = (function (type) {
} }
if (gradient.dots.length) { if (gradient.dots.length) {
fill.on = true; fill.on = true;
fill.type = (gradient.type.toLowerCase() == "linear") ? "gradient" : "gradientradial"; fill.method = "none";
fill.type = (gradient.type.toLowerCase() == "linear") ? "gradient" : "gradientTitle";
if (typeof gradient.dots[0].color != "undefined") { if (typeof gradient.dots[0].color != "undefined") {
fill.color = gradient.dots[0].color || "#000"; fill.color = gradient.dots[0].color || "#000";
} }
if (typeof gradient.dots[0].opacity != "undefined") {
fill.opacity = gradient.dots[0].opacity;
}
if (typeof gradient.dots[gradient.dots.length - 1].opacity != "undefined") {
fill.opacity2 = gradient.dots[gradient.dots.length - 1].opacity;
}
if (typeof gradient.dots[gradient.dots.length - 1].color != "undefined") { if (typeof gradient.dots[gradient.dots.length - 1].color != "undefined") {
fill.color2 = gradient.dots[gradient.dots.length - 1].color || "#000"; fill.color2 = gradient.dots[gradient.dots.length - 1].color || "#000";
} }
var colors = ""; var colors = [];
for (var i = 1, ii = gradient.dots.length - 1; i < ii; i++) { for (var i = 0, ii = gradient.dots.length; i < ii; i++) {
colors += gradient.dots[i].offset + " " + gradient.dots[i].color; if (gradient.dots[i].offset) {
if (i != ii - 1) { colors.push(gradient.dots[i].offset + " " + gradient.dots[i].color);
colors += ",";
} }
}; };
var fillOpacity = gradient.dots[0].opacity || 1;
var fillOpacity2 = gradient.dots[gradient.dots.length - 1].opacity || 1;
if (colors) { if (colors) {
fill.colors = colors; fill.colors.value = colors.join(",");
fillOpacity2 += fillOpacity;
fillOpacity = fillOpacity2 - fillOpacity;
fillOpacity2 -= fillOpacity;
} }
fill.setAttribute("opacity", fillOpacity);
fill.setAttribute("opacity2", fillOpacity2);
if (gradient.vector) { if (gradient.vector) {
var angle = Math.round(Math.atan((parseInt(gradient.vector[3], 10) - parseInt(gradient.vector[1], 10)) / (parseInt(gradient.vector[2], 10) - parseInt(gradient.vector[0], 10))) * 57.29) + 180; var angle = Math.round(Math.atan((parseFloat(gradient.vector[3], 10) - parseFloat(gradient.vector[1], 10)) / (parseFloat(gradient.vector[2], 10) - parseFloat(gradient.vector[0], 10))) * 57.29) || 0;
fill.angle = angle + 90; fill.angle = 270 - angle;
} }
if (gradient.type.toLowerCase() == "radial") { if (gradient.type.toLowerCase() == "radial") {
fill.focusposition = "0.5, 0.5"; fill.focus = "100%";
fill.focussize = "0, 0"; fill.focusposition = "0.5 0.5";
fill.method = "none";
} }
} }
}; };
...@@ -762,22 +773,23 @@ var Raphael = (function (type) { ...@@ -762,22 +773,23 @@ var Raphael = (function (type) {
var thePath = function (params, pathString, SVG) { var thePath = function (params, pathString, SVG) {
var el = document.createElementNS(SVG.svgns, "path"); var el = document.createElementNS(SVG.svgns, "path");
el.setAttribute("fill", "none"); el.setAttribute("fill", "none");
if (params) {
for (var attr in params) {
if (params.gradient) {
addGrdientFill(el, params.gradient, SVG);
} else {
el.setAttribute(attr, params[attr]);
}
}
}
if (SVG.canvas) { if (SVG.canvas) {
SVG.canvas.appendChild(el); SVG.canvas.appendChild(el);
} }
var p = new Element(el, SVG); var p = new Element(el, SVG);
for (var attr in params) { if (params) {
p.attrs[attr] = params[attr]; setFillAndStroke(p, params);
// for (var attr in params) {
// if (params.gradient) {
// addGrdientFill(el, params.gradient, SVG);
// } else {
// el.setAttribute(attr, params[attr]);
// }
// }
} }
// for (var attr in params) {
// p.attrs[attr] = params[attr];
// }
p.isAbsolute = true; p.isAbsolute = true;
p.path = []; p.path = [];
p.last = {x: 0, y: 0, bx: 0, by: 0}; p.last = {x: 0, y: 0, bx: 0, by: 0};
...@@ -982,6 +994,104 @@ var Raphael = (function (type) { ...@@ -982,6 +994,104 @@ var Raphael = (function (type) {
}; };
o.setAttribute("fill", "url(#" + el.id + ")"); o.setAttribute("fill", "url(#" + el.id + ")");
}; };
var setFillAndStroke = function (o, params) {
var dasharray = {
"-": [3, 1],
".": [1, 1],
"-.": [3, 1, 1, 1],
"-..": [3, 1, 1, 1, 1, 1],
". ": [1, 3],
"- ": [4, 3],
"--": [8, 3],
"- .": [4, 3, 1, 3],
"--.": [8, 3, 1, 3],
"--..": [8, 3, 1, 3, 1, 3]
};
for (var att in params) {
var value = params[att];
o.attrs[att] = value;
switch (att) {
case "rx":
case "cx":
case "x":
o[0].setAttribute(att, o.svg._getX(value));
break;
case "ry":
case "cy":
case "y":
o[0].setAttribute(att, o.svg._getY(value));
break;
case "width":
o[0].setAttribute(att, o.svg._getW(value));
break;
case "height":
o[0].setAttribute(att, o.svg._getH(value));
break;
case "gradient":
addGrdientFill(o[0], value, o.svg);
break;
case "stroke-dasharray":
value = dasharray[value.toLowerCase()];
if (value) {
var width = params["stroke-width"] || o.attr("stroke-width") || "1",
butt = {round: width, square: width, butt: 0}[o.attr("stroke-linecap")] || 0,
dashes = [];
for (var i = 0, ii = value.length; i < ii; i++) {
dashes.push(value[i] * width + ((i % 2) ? 1 : -1) * butt);
}
value = dashes.join(",");
o[0].setAttribute(att, value);
}
break;
case "text":
if (o.type == "text") {
o[0].childNodes.length && o[0].removeChild(o[0].firstChild);
o[0].appendChild(document.createTextNode(value));
}
break;
case "fill":
var isURL = value.match(/^url\(([^\)]+)\)$/i);
if (isURL) {
var el = document.createElementNS(o.svg.svgns, "pattern");
var ig = document.createElementNS(o.svg.svgns, "image");
console.log(isURL);
el.id = "raphael-pattern-" + o.svg.gradients++;
el.setAttribute("x", 0);
el.setAttribute("y", 0);
el.setAttribute("patternUnits", "userSpaceOnUse");
ig.setAttribute("x", 0);
ig.setAttribute("y", 0);
ig.setAttributeNS(o.svg.xlink, "href", isURL[1]);
el.appendChild(ig);
var img = document.createElement("img");
img.src = isURL[1];
img.style.position = "absolute";
img.style.top = "-9999em";
img.style.left = "-9999em";
img.onload = function () {
el.setAttribute("width", this.offsetWidth);
el.setAttribute("height", this.offsetHeight);
ig.setAttribute("width", this.offsetWidth);
ig.setAttribute("height", this.offsetHeight);
document.body.removeChild(this);
};
document.body.appendChild(img);
o.svg.defs.appendChild(el);
o[0].style.fill = "url(#" + el.id + ")";
o[0].setAttribute("fill", "url(#" + el.id + ")");
break;
}
default :
var cssrule = att.replace(/(\-.)/g, function (w) {
return w.substring(1).toUpperCase();
});
o[0].style[cssrule] = value;
// Need following line for Firefox
o[0].setAttribute(att, value);
break;
}
}
};
var Element = function (node, svg) { var Element = function (node, svg) {
var X = 0, var X = 0,
Y = 0, Y = 0,
...@@ -1014,7 +1124,7 @@ var Raphael = (function (type) { ...@@ -1014,7 +1124,7 @@ var Raphael = (function (type) {
} }
X += x; X += x;
Y += y; Y += y;
if (X && Y) { if (X || Y) {
this.transformations[1] = "translate(" + X + "," + Y + ")"; this.transformations[1] = "translate(" + X + "," + Y + ")";
} else { } else {
this.transformations[1] = ""; this.transformations[1] = "";
...@@ -1075,70 +1185,11 @@ var Raphael = (function (type) { ...@@ -1075,70 +1185,11 @@ var Raphael = (function (type) {
return values; return values;
} }
if (arguments.length == 2) { if (arguments.length == 2) {
var att = arguments[0], var params = {};
value = arguments[1]; params[arguments[0]] = arguments[1];
this[att] = value; setFillAndStroke(this, params);
this.attrs[att] = value;
switch (att) {
case "rx":
case "cx":
case "x":
this[0].setAttribute(att, this.svg._getX(value));
break;
case "ry":
case "cy":
case "y":
this[0].setAttribute(att, this.svg._getY(value));
break;
case "width":
this[0].setAttribute(att, this.svg._getW(value));
break;
case "height":
this[0].setAttribute(att, this.svg._getH(value));
break;
case "gradient":
addGrdientFill(this[0], value, this.svg);
break;
case "stroke-dasharray":
this[0].setAttribute(att, value.replace(" ", ","));
break;
case "text":
if (this.type == "text") {
this[0].removeChild(this[0].firstChild);
this[0].appendChild(document.createTextNode(value));
}
break;
default :
var cssrule = att.replace(/(\-.)/g, function (w) {
return w.substring(1).toUpperCase();
});
this[0].style[cssrule] = value;
// Need following line for Firefox
this[0].setAttribute(att, value);
break;
}
} else if (arguments.length == 1 && typeof arguments[0] == "object") { } else if (arguments.length == 1 && typeof arguments[0] == "object") {
var params = arguments[0]; setFillAndStroke(this, arguments[0]);
for (var attr in params) {
this.attrs[attr] = params[attr];
if (attr == "stroke-dasharray") {
this[0].setAttribute(attr, params[attr].replace(" ", ","));
} else if (attr == "text" && this.type == "text") {
this[0].childNodes.length && this[0].removeChild(this[0].firstChild);
this[0].appendChild(document.createTextNode(params.text));
} else {
var cssrule = attr.replace(/(\-.)/g, function (w) {
return w.substring(1).toUpperCase();
});
this[0].style[cssrule] = params[attr];
// Need following line for Firefox
this[0].setAttribute(attr, params[attr]);
}
}
if (params.gradient) {
this.attrs.gradient = params.gradient;
addGrdientFill(this[0], params.gradient, this.svg);
}
} }
return this; return this;
}; };
......
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