Added gradients. Changed plugin architecture.
parent
c22245fc56
commit
2270a96f12
48
demojs.html
48
demojs.html
|
@ -3,6 +3,11 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Savage</title>
|
<title>Savage</title>
|
||||||
|
<style media="screen">
|
||||||
|
body {
|
||||||
|
background: #030 url("bg.png");
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<script src="eve/eve.js"></script>
|
<script src="eve/eve.js"></script>
|
||||||
<script src="mina.js"></script>
|
<script src="mina.js"></script>
|
||||||
<script src="elemental.js"></script>
|
<script src="elemental.js"></script>
|
||||||
|
@ -25,31 +30,31 @@
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
// // 1
|
// 1
|
||||||
var s = Savage("100%", 600);
|
var s = Savage("100%", 600);
|
||||||
// // 2
|
// 2
|
||||||
var c = s.circle(100, 100, 50);
|
var c = s.circle(100, 100, 50);
|
||||||
// // 3
|
// 3
|
||||||
c.attr({
|
c.attr({
|
||||||
fill: "#bada55",
|
fill: "#bada55",
|
||||||
stroke: "#000",
|
stroke: "#000",
|
||||||
"stroke-width": 5
|
"stroke-width": 5
|
||||||
});
|
});
|
||||||
// // 4
|
// 4
|
||||||
var c2 = s.circle(70, 100, 40);
|
var c2 = s.circle(70, 100, 40);
|
||||||
var g = s.g(c2, s.circle(130, 100, 40));
|
var g = s.group(c2, s.circle(130, 100, 40));
|
||||||
g.attr({
|
g.attr({
|
||||||
fill: "#fff"
|
fill: "#fff"
|
||||||
});
|
});
|
||||||
// // 5
|
// 5
|
||||||
c.attr({
|
c.attr({
|
||||||
mask: g
|
mask: g
|
||||||
});
|
});
|
||||||
// // 6
|
// 6
|
||||||
c2.animate({r: 25}, 1000);
|
c2.animate({r: 25}, 1000);
|
||||||
// // 7
|
// 7
|
||||||
g.select("circle:nth-child(2)").animate({r: 25}, 1000);
|
g.select("circle:nth-child(2)").animate({r: 25}, 1000);
|
||||||
// // 8
|
// 8
|
||||||
var p = s.path("M10-5-10,15M15,0,0,15M0-5-20,15").attr({
|
var p = s.path("M10-5-10,15M15,0,0,15M0-5-20,15").attr({
|
||||||
fill: "none",
|
fill: "none",
|
||||||
stroke: "#bada55",
|
stroke: "#bada55",
|
||||||
|
@ -58,26 +63,33 @@
|
||||||
c.attr({
|
c.attr({
|
||||||
fill: p
|
fill: p
|
||||||
});
|
});
|
||||||
// // 9
|
// 9
|
||||||
g.attr({
|
g.attr({
|
||||||
fill: Savage(document.getElementById("pattern"))
|
fill: Savage(document.getElementById("pattern"))
|
||||||
});
|
});
|
||||||
// // 10
|
// 10
|
||||||
|
g.attr({fill: "r()#fff-#000"});
|
||||||
|
// 11
|
||||||
|
g.attr({fill: "R(100, 100, 50)#fff-#000"});
|
||||||
|
// 12
|
||||||
var svg = document.getElementById("svg").text;
|
var svg = document.getElementById("svg").text;
|
||||||
var f = Savage.fragment(svg);
|
var f = Savage.fragment(svg);
|
||||||
f.select("path[fill='#D40000']").attr({fill: "#bada55"});
|
f.select("path[fill='#D40000']").attr({fill: "#bada55"});
|
||||||
g = s.g(f.selectAll("path"));
|
g = s.group(f.selectAll("path"));
|
||||||
s.append(g);
|
s.append(g);
|
||||||
// // 11
|
// 13
|
||||||
g.attr({
|
g.attr({
|
||||||
transform: "r45t100,0s.5"
|
transform: "r45t100,0s.5"
|
||||||
});
|
});
|
||||||
console.log(g.attr("transform"));
|
// console.log(g.attr("transform"));
|
||||||
// // 12
|
// 14
|
||||||
s.text(200, 100, "SAVAGE");
|
s.text(200, 100, "SAVAGE");
|
||||||
// // 13
|
// 15
|
||||||
var t = s.text(200, 120, ["S","A","V","A","G","E"]);
|
var t = s.text(200, 120, "SAVAGE".split(""));
|
||||||
t.selectAll("tspan tspan:nth-child(odd)").attr({fill: "red"});
|
t.selectAll("tspan tspan:nth-child(odd)").attr({
|
||||||
|
fill: "#900",
|
||||||
|
"font-size": "20px"
|
||||||
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
(function () {
|
Savage.plugin(function (Savage, Element, Paper, glob) {
|
||||||
var mmax = Math.max,
|
var mmax = Math.max,
|
||||||
mmin = Math.min,
|
mmin = Math.min;
|
||||||
g = eve("savage.globals")[0];
|
|
||||||
|
|
||||||
// Set
|
// Set
|
||||||
var Set = function (items) {
|
var Set = function (items) {
|
||||||
|
@ -71,9 +70,9 @@
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
setproto.attr = function (name, value) {
|
setproto.attr = function (value) {
|
||||||
for (var i = 0, ii = this.items.length; i < ii; i++) {
|
for (var i = 0, ii = this.items.length; i < ii; i++) {
|
||||||
this.items[i].attr(name, value);
|
this.items[i].attr(value);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
@ -190,11 +189,11 @@
|
||||||
};
|
};
|
||||||
setproto.type = "set";
|
setproto.type = "set";
|
||||||
// export
|
// export
|
||||||
g.savage.set = function () {
|
Savage.set = function () {
|
||||||
var set = new Set;
|
var set = new Set;
|
||||||
if (arguments.length) {
|
if (arguments.length) {
|
||||||
set.push.apply(set, Array.prototype.slice.call(arguments, 0));
|
set.push.apply(set, Array.prototype.slice.call(arguments, 0));
|
||||||
}
|
}
|
||||||
return set;
|
return set;
|
||||||
};
|
};
|
||||||
})();
|
});
|
192
svg.js
192
svg.js
|
@ -11,6 +11,8 @@ var Savage = function (w, h) {
|
||||||
return new Element(glob.doc.querySelector(w));
|
return new Element(glob.doc.querySelector(w));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
w = w == null ? "100%" : w;
|
||||||
|
h = h == null ? "100%" : h;
|
||||||
return new Paper(w, h);
|
return new Paper(w, h);
|
||||||
};
|
};
|
||||||
var glob = {
|
var glob = {
|
||||||
|
@ -38,13 +40,12 @@ var has = "hasOwnProperty",
|
||||||
spaces = "\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029",
|
spaces = "\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029",
|
||||||
separator = new RegExp("[," + spaces + "]+"),
|
separator = new RegExp("[," + spaces + "]+"),
|
||||||
whitespace = new RegExp("[" + spaces + "]", "g"),
|
whitespace = new RegExp("[" + spaces + "]", "g"),
|
||||||
commaSpaces = new RegExp("[" + spaces + "]*,[" + spaces + "*]"),
|
commaSpaces = new RegExp("[" + spaces + "]*,[" + spaces + "]*"),
|
||||||
hsrg = {hs: 1, rg: 1},
|
hsrg = {hs: 1, rg: 1},
|
||||||
p2s = /,?([a-z]),?/gi,
|
p2s = /,?([a-z]),?/gi,
|
||||||
pathCommand = new RegExp("([a-z])[" + spaces + ",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[" + spaces + "]*,?[" + spaces + "]*)+)", "ig"),
|
pathCommand = new RegExp("([a-z])[" + spaces + ",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[" + spaces + "]*,?[" + spaces + "]*)+)", "ig"),
|
||||||
tCommand = new RegExp("([rstm])[" + spaces + ",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[" + spaces + "]*,?[" + spaces + "]*)+)", "ig"),
|
tCommand = new RegExp("([rstm])[" + spaces + ",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[" + spaces + "]*,?[" + spaces + "]*)+)", "ig"),
|
||||||
pathValues = new RegExp("(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[" + spaces + "]*,?[" + spaces + "]*", "ig"),
|
pathValues = new RegExp("(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[" + spaces + "]*,?[" + spaces + "]*", "ig"),
|
||||||
radial_gradient = new RegExp("^r(?:\\(([^,]+?)[" + spaces + "]*,[" + spaces + "]*([^\\)]+?)\\))?"),
|
|
||||||
idgen = 0,
|
idgen = 0,
|
||||||
idprefix = "S" + (+new Date).toString(36),
|
idprefix = "S" + (+new Date).toString(36),
|
||||||
ID = function () {
|
ID = function () {
|
||||||
|
@ -109,6 +110,24 @@ function is(o, type) {
|
||||||
(type == "array" && Array.isArray && Array.isArray(o)) ||
|
(type == "array" && Array.isArray && Array.isArray(o)) ||
|
||||||
objectToString.call(o).slice(8, -1).toLowerCase() == type;
|
objectToString.call(o).slice(8, -1).toLowerCase() == type;
|
||||||
}
|
}
|
||||||
|
var preload = (function () {
|
||||||
|
function onerror() {
|
||||||
|
this.parentNode.removeChild(this);
|
||||||
|
}
|
||||||
|
return function (src, f) {
|
||||||
|
var img = glob.doc.createElement("img"),
|
||||||
|
body = glob.doc.body;
|
||||||
|
img.style.cssText = "position:absolute;left:-9999em;top:-9999em";
|
||||||
|
img.onload = function () {
|
||||||
|
f.call(img);
|
||||||
|
img.onload = img.onerror = null;
|
||||||
|
body.removeChild(img);
|
||||||
|
};
|
||||||
|
img.onerror = onerror;
|
||||||
|
body.appendChild(img);
|
||||||
|
img.src = src;
|
||||||
|
};
|
||||||
|
}());
|
||||||
function clone(obj) {
|
function clone(obj) {
|
||||||
if (typeof obj == "function" || Object(obj) !== obj) {
|
if (typeof obj == "function" || Object(obj) !== obj) {
|
||||||
return obj;
|
return obj;
|
||||||
|
@ -425,7 +444,7 @@ Savage.Matrix = Matrix;
|
||||||
# <li>Colour name (“<code>red</code>”, “<code>green</code>”, “<code>cornflowerblue</code>”, etc)</li>
|
# <li>Colour name (“<code>red</code>”, “<code>green</code>”, “<code>cornflowerblue</code>”, etc)</li>
|
||||||
# <li>#••• — shortened HTML colour: (“<code>#000</code>”, “<code>#fc0</code>”, etc)</li>
|
# <li>#••• — shortened HTML colour: (“<code>#000</code>”, “<code>#fc0</code>”, etc)</li>
|
||||||
# <li>#•••••• — full length HTML colour: (“<code>#000000</code>”, “<code>#bd2300</code>”)</li>
|
# <li>#•••••• — full length HTML colour: (“<code>#000000</code>”, “<code>#bd2300</code>”)</li>
|
||||||
# <li>rgb(•••, •••, •••) — red, green and blue channels’ values: (“<code>rgb(200, 100, 0)</code>”)</li>
|
# <li>rgb(•••, •••, •••) — red, green and blue channels values: (“<code>rgb(200, 100, 0)</code>”)</li>
|
||||||
# <li>rgb(•••%, •••%, •••%) — same as above, but in %: (“<code>rgb(100%, 175%, 0%)</code>”)</li>
|
# <li>rgb(•••%, •••%, •••%) — same as above, but in %: (“<code>rgb(100%, 175%, 0%)</code>”)</li>
|
||||||
# <li>hsb(•••, •••, •••) — hue, saturation and brightness values: (“<code>hsb(0.5, 0.25, 1)</code>”)</li>
|
# <li>hsb(•••, •••, •••) — hue, saturation and brightness values: (“<code>hsb(0.5, 0.25, 1)</code>”)</li>
|
||||||
# <li>hsb(•••%, •••%, •••%) — same as above, but in %</li>
|
# <li>hsb(•••%, •••%, •••%) — same as above, but in %</li>
|
||||||
|
@ -438,7 +457,7 @@ Savage.Matrix = Matrix;
|
||||||
o g (number) green,
|
o g (number) green,
|
||||||
o b (number) blue
|
o b (number) blue
|
||||||
o hex (string) color in HTML/CSS format: #••••••,
|
o hex (string) color in HTML/CSS format: #••••••,
|
||||||
o error (boolean) true if string can’t be parsed
|
o error (boolean) true if string cant be parsed
|
||||||
o }
|
o }
|
||||||
\*/
|
\*/
|
||||||
Savage.getRGB = cacher(function (colour) {
|
Savage.getRGB = cacher(function (colour) {
|
||||||
|
@ -571,7 +590,9 @@ hsltoString = function () {
|
||||||
return "hsl(" + [this.h, this.s, this.l] + ")";
|
return "hsl(" + [this.h, this.s, this.l] + ")";
|
||||||
},
|
},
|
||||||
rgbtoString = function () {
|
rgbtoString = function () {
|
||||||
return this.hex;
|
return this.opacity == 1 || this.opacity == null ?
|
||||||
|
this.hex :
|
||||||
|
"rgba(" + [this.r, this.g, this.b, this.opacity] + ")";
|
||||||
},
|
},
|
||||||
prepareRGB = function (r, g, b) {
|
prepareRGB = function (r, g, b) {
|
||||||
if (g == null && is(r, "object") && "r" in r && "g" in r && "b" in r) {
|
if (g == null && is(r, "object") && "r" in r && "g" in r && "b" in r) {
|
||||||
|
@ -594,9 +615,9 @@ prepareRGB = function (r, g, b) {
|
||||||
return [r, g, b];
|
return [r, g, b];
|
||||||
},
|
},
|
||||||
packageRGB = function (r, g, b, o) {
|
packageRGB = function (r, g, b, o) {
|
||||||
r *= 255;
|
r = math.round(r * 255);
|
||||||
g *= 255;
|
g = math.round(g * 255);
|
||||||
b *= 255;
|
b = math.round(b * 255);
|
||||||
var rgb = {
|
var rgb = {
|
||||||
r: r,
|
r: r,
|
||||||
g: g,
|
g: g,
|
||||||
|
@ -621,7 +642,7 @@ packageRGB = function (r, g, b, o) {
|
||||||
o g (number) green,
|
o g (number) green,
|
||||||
o b (number) blue,
|
o b (number) blue,
|
||||||
o hex (string) color in HTML/CSS format: #••••••,
|
o hex (string) color in HTML/CSS format: #••••••,
|
||||||
o error (boolean) `true` if string can’t be parsed,
|
o error (boolean) `true` if string cant be parsed,
|
||||||
o h (number) hue,
|
o h (number) hue,
|
||||||
o s (number) saturation,
|
o s (number) saturation,
|
||||||
o v (number) value (brightness),
|
o v (number) value (brightness),
|
||||||
|
@ -1696,11 +1717,20 @@ function Element(el) {
|
||||||
el.savage = id;
|
el.savage = id;
|
||||||
hub[id] = this;
|
hub[id] = this;
|
||||||
}
|
}
|
||||||
|
function arrayFirstValue(arr) {
|
||||||
|
var res;
|
||||||
|
for (var i = 0, ii = arr.length; i < ii; i++) {
|
||||||
|
res = res || arr[i];
|
||||||
|
if (res) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
(function (elproto) {
|
(function (elproto) {
|
||||||
elproto.attr = function (params) {
|
elproto.attr = function (params) {
|
||||||
var node = this.node;
|
var node = this.node;
|
||||||
if (is(params, "string")) {
|
if (is(params, "string")) {
|
||||||
return eve("savage.util.getattr." + params, this)[0];
|
return arrayFirstValue(eve("savage.util.getattr." + params, this));
|
||||||
}
|
}
|
||||||
for (var att in params) {
|
for (var att in params) {
|
||||||
if (params[has](att)) {
|
if (params[has](att)) {
|
||||||
|
@ -1883,6 +1913,31 @@ function Element(el) {
|
||||||
p.node.appendChild(this.node);
|
p.node.appendChild(this.node);
|
||||||
return p;
|
return p;
|
||||||
};
|
};
|
||||||
|
elproto.marker = function (x, y, width, height, refX, refY) {
|
||||||
|
var p = make("marker", this.paper.defs);
|
||||||
|
if (x == null) {
|
||||||
|
x = this.getBBox();
|
||||||
|
}
|
||||||
|
if (x && "x" in x) {
|
||||||
|
y = x.y;
|
||||||
|
width = x.width;
|
||||||
|
height = x.height;
|
||||||
|
refX = x.refX;
|
||||||
|
refY = x.refY;
|
||||||
|
x = x.x;
|
||||||
|
}
|
||||||
|
$(p.node, {
|
||||||
|
viewBox: [x, y, width, height].join(S),
|
||||||
|
markerWidth: width,
|
||||||
|
markerHeight: height,
|
||||||
|
orient: "auto",
|
||||||
|
refX: refX || 0,
|
||||||
|
refY: refY || 0,
|
||||||
|
id: p.id
|
||||||
|
});
|
||||||
|
p.node.appendChild(this.node);
|
||||||
|
return p;
|
||||||
|
};
|
||||||
// animation
|
// animation
|
||||||
function applyAttr(el, key) {
|
function applyAttr(el, key) {
|
||||||
var at = {};
|
var at = {};
|
||||||
|
@ -2026,6 +2081,38 @@ function wrap(dom) {
|
||||||
}
|
}
|
||||||
return el;
|
return el;
|
||||||
};
|
};
|
||||||
|
proto.image = function (src, x, y, width, height) {
|
||||||
|
var el = make("image", this.node);
|
||||||
|
if (is(src, "object") && "src" in src) {
|
||||||
|
el.attr(src);
|
||||||
|
} else if (src != null) {
|
||||||
|
var set = {
|
||||||
|
"xlink:href": src,
|
||||||
|
preserveAspectRatio: "none"
|
||||||
|
};
|
||||||
|
if (x != null && y != null) {
|
||||||
|
set.x = x;
|
||||||
|
set.y = y;
|
||||||
|
}
|
||||||
|
if (width != null && height != null) {
|
||||||
|
set.width = width;
|
||||||
|
set.height = height;
|
||||||
|
} else {
|
||||||
|
preload(src, function () {
|
||||||
|
$(el.node, {
|
||||||
|
width: this.offsetWidth,
|
||||||
|
height: this.offsetHeight
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$(el.node, set);
|
||||||
|
}
|
||||||
|
return el;
|
||||||
|
};
|
||||||
|
proto.custom = function (name) {
|
||||||
|
var el = make(name, this.node);
|
||||||
|
return el;
|
||||||
|
};
|
||||||
proto.ellipse = function (cx, cy, rx, ry) {
|
proto.ellipse = function (cx, cy, rx, ry) {
|
||||||
var el = make("ellipse", this.node);
|
var el = make("ellipse", this.node);
|
||||||
if (is(cx, "object") && "cx" in cx) {
|
if (is(cx, "object") && "cx" in cx) {
|
||||||
|
@ -2139,7 +2226,7 @@ function wrap(dom) {
|
||||||
// gradients
|
// gradients
|
||||||
(function () {
|
(function () {
|
||||||
proto.gradient = function (str) {
|
proto.gradient = function (str) {
|
||||||
var grad = eve("savage.util.grad.parse", null, str)[0],
|
var grad = arrayFirstValue(eve("savage.util.grad.parse", null, str)),
|
||||||
el;
|
el;
|
||||||
if (grad.type.toLowerCase() == "l") {
|
if (grad.type.toLowerCase() == "l") {
|
||||||
el = this.gradientLinear.apply(this, grad.params);
|
el = this.gradientLinear.apply(this, grad.params);
|
||||||
|
@ -2147,7 +2234,7 @@ function wrap(dom) {
|
||||||
el = this.gradientRadial.apply(this, grad.params);
|
el = this.gradientRadial.apply(this, grad.params);
|
||||||
}
|
}
|
||||||
if (grad.type != grad.type.toLowerCase()) {
|
if (grad.type != grad.type.toLowerCase()) {
|
||||||
el.attr({
|
$(el.node, {
|
||||||
gradientUnits: "userSpaceOnUse"
|
gradientUnits: "userSpaceOnUse"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2195,9 +2282,9 @@ function wrap(dom) {
|
||||||
y2 = $(this.node, "y2") || 0;
|
y2 = $(this.node, "y2") || 0;
|
||||||
return box(x1, y1, math.abs(x2 - x1), math.abs(y2 - y1));
|
return box(x1, y1, math.abs(x2 - x1), math.abs(y2 - y1));
|
||||||
} else {
|
} else {
|
||||||
var cx = this.node.cx,
|
var cx = this.node.cx || .5,
|
||||||
cy = this.node.cy,
|
cy = this.node.cy || .5,
|
||||||
r = this.node.r;
|
r = this.node.r || 0;
|
||||||
return box(cx - r, cy - r, r * 2, r * 2);
|
return box(cx - r, cy - r, r * 2, r * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2216,6 +2303,26 @@ function wrap(dom) {
|
||||||
}
|
}
|
||||||
return el;
|
return el;
|
||||||
};
|
};
|
||||||
|
proto.gradientRadial = function (cx, cy, r, fx, fy) {
|
||||||
|
var el = make("radialGradient", this.node);
|
||||||
|
el.stops = stops;
|
||||||
|
el.addStop = addStop;
|
||||||
|
el.getBBox = getBBox;
|
||||||
|
if (cx != null) {
|
||||||
|
$(el.node, {
|
||||||
|
cx: cx,
|
||||||
|
cy: cy,
|
||||||
|
r: r
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (fx != null && fy != null) {
|
||||||
|
$(el.node, {
|
||||||
|
fx: fx,
|
||||||
|
fy: fy
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return el;
|
||||||
|
};
|
||||||
}());
|
}());
|
||||||
}(Paper.prototype));
|
}(Paper.prototype));
|
||||||
// Attributes event handlers
|
// Attributes event handlers
|
||||||
|
@ -2351,6 +2458,15 @@ eve.on("savage.util.attr.transform", function (value) {
|
||||||
this.transform(value);
|
this.transform(value);
|
||||||
eve.stop();
|
eve.stop();
|
||||||
});
|
});
|
||||||
|
eve.on("savage.util.attr.r", function (value) {
|
||||||
|
if (this.type == "rect") {
|
||||||
|
eve.stop();
|
||||||
|
$(this.node, {
|
||||||
|
rx: value,
|
||||||
|
ry: value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
eve.on("savage.util.attr.text", function (value) {
|
eve.on("savage.util.attr.text", function (value) {
|
||||||
if (this.type == "text") {
|
if (this.type == "text") {
|
||||||
var i = 0,
|
var i = 0,
|
||||||
|
@ -2376,15 +2492,24 @@ eve.on("savage.util.attr.text", function (value) {
|
||||||
});
|
});
|
||||||
// default
|
// default
|
||||||
var availableAttributes = {
|
var availableAttributes = {
|
||||||
rect: {x: 0, y: 0, width: 0, height: 0, rx: 0, ry: 0},
|
rect: {x: 0, y: 0, width: 0, height: 0, rx: 0, ry: 0, "class": 0},
|
||||||
circle: {cx: 0, cy: 0, r: 0},
|
circle: {cx: 0, cy: 0, r: 0, "class": 0},
|
||||||
ellipse: {cx: 0, cy: 0, rx: 0, ry: 0},
|
ellipse: {cx: 0, cy: 0, rx: 0, ry: 0, "class": 0},
|
||||||
line: {x1: 0, y1: 0, x2: 0, y2: 0},
|
line: {x1: 0, y1: 0, x2: 0, y2: 0, "class": 0},
|
||||||
polyline: {points: ""},
|
polyline: {points: "", "class": 0},
|
||||||
polygon: {points: ""},
|
polygon: {points: "", "class": 0},
|
||||||
text: {x: 0, y: 0, dx: 0, dy: 0, rotate: 0, textLength: 0},
|
text: {x: 0, y: 0, dx: 0, dy: 0, rotate: 0, textLength: 0, lengthAdjust: 0, "class": 0},
|
||||||
tspan: {x: 0, y: 0, dx: 0, dy: 0, rotate: 0, textLength: 0},
|
tspan: {x: 0, y: 0, dx: 0, dy: 0, rotate: 0, textLength: 0, lengthAdjust: 0, "class": 0},
|
||||||
path: {d: ""}
|
textPath: {"xlink:href": 0, startOffset: 0, method: 0, spacing: 0, "class": 0},
|
||||||
|
marker: {viewBox: 0, preserveAspectRatio: 0, refX: 0, refY: 0, markerUnits: 0, markerWidth: 0, markerHeight: 0, orient: 0, "class": 0},
|
||||||
|
linearGradient: {x1: 0, y1: 0, x2: 0, y2: 0, gradientUnits: 0, gradientTransform: 0, spreadMethod: 0, "xlink:href": 0, "class": 0},
|
||||||
|
radialGradient: {cx: 0, cy: 0, r: 0, fx: 0, fy: 0, gradientUnits: 0, gradientTransform: 0, spreadMethod: 0, "xlink:href": 0, "class": 0},
|
||||||
|
stop: {offset: 0, "class": 0},
|
||||||
|
pattern: {viewBox: 0, preserveAspectRatio: 0, x: 0, y: 0, width: 0, height: 0, patternUnits: 0, patternContentUnits: 0, patternTransform: 0, "xlink:href": 0, "class": 0},
|
||||||
|
clipPath: {transform: 0, clipPathUnits: 0, "class": 0},
|
||||||
|
mask: {x: 0, y: 0, width: 0, height: 0, maskUnits: 0, maskContentUnits: 0, "class": 0},
|
||||||
|
image: {preserveAspectRatio: 0, transform: 0, x: 0, y: 0, width: 0, height: 0, "xlink:href": 0, "class": 0},
|
||||||
|
path: {d: "", "class": 0}
|
||||||
};
|
};
|
||||||
eve.on("savage.util.attr", function (value) {
|
eve.on("savage.util.attr", function (value) {
|
||||||
var att = eve.nt();
|
var att = eve.nt();
|
||||||
|
@ -2403,6 +2528,12 @@ eve.on("savage.util.getattr.transform", function () {
|
||||||
eve.stop();
|
eve.stop();
|
||||||
return this.transform();
|
return this.transform();
|
||||||
})(-1);
|
})(-1);
|
||||||
|
eve.on("savage.util.getattr.r", function () {
|
||||||
|
if (this.type == "rect" && $(this.node, "rx") == $(this.node, "ry")) {
|
||||||
|
eve.stop();
|
||||||
|
return $(this.node, "rx");
|
||||||
|
}
|
||||||
|
})(-1);
|
||||||
eve.on("savage.util.getattr.viewBox", function () {
|
eve.on("savage.util.getattr.viewBox", function () {
|
||||||
eve.stop();
|
eve.stop();
|
||||||
var vb = $(this.node, "viewBox").split(separator);
|
var vb = $(this.node, "viewBox").split(separator);
|
||||||
|
@ -2424,16 +2555,11 @@ eve.on("savage.util.getattr", function () {
|
||||||
if (availableAttributes[has](this.type) && availableAttributes[this.type][has](att)) {
|
if (availableAttributes[has](this.type) && availableAttributes[this.type][has](att)) {
|
||||||
return this.node.getAttribute(att);
|
return this.node.getAttribute(att);
|
||||||
} else {
|
} else {
|
||||||
return document.defaultView.getComputedStyle(this.node, null).getPropertyValue(style);
|
return glob.doc.defaultView.getComputedStyle(this.node, null).getPropertyValue(style);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
eve.on("savage.globals", function () {
|
Savage.plugin = function (f) {
|
||||||
return {
|
f(Savage, Element, Paper, glob);
|
||||||
savage: Savage,
|
};
|
||||||
element: Element,
|
|
||||||
paper: Paper,
|
|
||||||
glob: glob
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return Savage;
|
return Savage;
|
||||||
}());
|
}());
|
202
test/test.html
202
test/test.html
|
@ -3,19 +3,25 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Savage Tests</title>
|
<title>Savage Tests</title>
|
||||||
<link rel="stylesheet" href="mocha.css" />
|
<style media="screen">
|
||||||
<script src="../mywork/eve/eve.js"></script>
|
svg {
|
||||||
<script src="mina.js"></script>
|
position: absolute;
|
||||||
<script src="elemental.js"></script>
|
top: -999em;
|
||||||
<script src="svg.js"></script>
|
left: -999em;
|
||||||
<script src="savage.set.js"></script>
|
}
|
||||||
|
</style>
|
||||||
|
<link rel="stylesheet" href="mocha/mocha.css">
|
||||||
|
<script src="../eve/eve.js"></script>
|
||||||
|
<script src="../mina.js"></script>
|
||||||
|
<script src="../elemental.js"></script>
|
||||||
|
<script src="../svg.js"></script>
|
||||||
|
<script src="../savage.set.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="mocha"></div>
|
<div id="mocha"></div>
|
||||||
|
<script src="expect/expect.js"></script>
|
||||||
<script src="expect.js"></script>
|
<script src="mocha/mocha.js"></script>
|
||||||
<script src="mocha.js"></script>
|
<script>mocha.setup("bdd");</script>
|
||||||
<script>mocha.setup('bdd');</script>
|
|
||||||
<script>
|
<script>
|
||||||
describe("System check", function () {
|
describe("System check", function () {
|
||||||
it("Savage exists", function () {
|
it("Savage exists", function () {
|
||||||
|
@ -161,6 +167,182 @@
|
||||||
expect(C.textContent).to.be("test");
|
expect(C.textContent).to.be("test");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe("Colours", function () {
|
||||||
|
it("parses hex colour", function () {
|
||||||
|
expect(Savage.color("#fC0").hex).to.be("#ffcc00");
|
||||||
|
});
|
||||||
|
it("parses RGB", function () {
|
||||||
|
var c = Savage.color("rgb(255, 204, 0)");
|
||||||
|
expect(c.hex).to.be("#ffcc00");
|
||||||
|
expect(c.r).to.be(255);
|
||||||
|
expect(c.g).to.be(204);
|
||||||
|
expect(c.b).to.be(0);
|
||||||
|
});
|
||||||
|
it("parses HSL", function () {
|
||||||
|
var c = Savage.color("hsl(0.1333, 1, .5)");
|
||||||
|
expect(c.hex).to.be("#ffcc00");
|
||||||
|
expect(c.h.toFixed(3)).to.be("0.133");
|
||||||
|
expect(c.s).to.be(1);
|
||||||
|
expect(c.l).to.be(.5);
|
||||||
|
});
|
||||||
|
it("parses HSB", function () {
|
||||||
|
var c = Savage.color("hsb(0.1333, 1, 1)");
|
||||||
|
expect(c.hex).to.be("#ffcc00");
|
||||||
|
expect(c.h.toFixed(3)).to.be("0.133");
|
||||||
|
expect(c.s).to.be(1);
|
||||||
|
expect(c.v).to.be(1);
|
||||||
|
});
|
||||||
|
it("parses RGBA", function () {
|
||||||
|
var c = Savage.color("rgba(255, 204, 0, .75)");
|
||||||
|
expect(c.hex).to.be("#ffcc00");
|
||||||
|
expect(c.r).to.be(255);
|
||||||
|
expect(c.g).to.be(204);
|
||||||
|
expect(c.b).to.be(0);
|
||||||
|
expect(c.opacity).to.be(.75);
|
||||||
|
});
|
||||||
|
it("parses HSLA", function () {
|
||||||
|
var c = Savage.color("hsla(0.1333, 1, .5, .5)");
|
||||||
|
expect(c.hex).to.be("#ffcc00");
|
||||||
|
expect(c.r).to.be(255);
|
||||||
|
expect(c.g).to.be(204);
|
||||||
|
expect(c.b).to.be(0);
|
||||||
|
expect(c.opacity).to.be(.5);
|
||||||
|
});
|
||||||
|
it("parses HSBA", function () {
|
||||||
|
var c = Savage.color("hsba(0.1333, 1, 1, .5)");
|
||||||
|
expect(c.hex).to.be("#ffcc00");
|
||||||
|
expect(c.r).to.be(255);
|
||||||
|
expect(c.g).to.be(204);
|
||||||
|
expect(c.b).to.be(0);
|
||||||
|
expect(c.opacity).to.be(.5);
|
||||||
|
});
|
||||||
|
it("parses names", function () {
|
||||||
|
var c = Savage.color("DodgerBlue");
|
||||||
|
expect(c.hex).to.be("#1e90ff");
|
||||||
|
c = Savage.color("FireBrick");
|
||||||
|
expect(c.hex).to.be("#b22222");
|
||||||
|
c = Savage.color("MintCream");
|
||||||
|
expect(c.hex).to.be("#f5fffa");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe("Attributes", function () {
|
||||||
|
var s, r;
|
||||||
|
beforeEach(function () {
|
||||||
|
s = Savage(100, 100);
|
||||||
|
r = s.rect(10, 10, 50, 50);
|
||||||
|
});
|
||||||
|
afterEach(function () {
|
||||||
|
s.remove();
|
||||||
|
});
|
||||||
|
function colorTestProp(key) {
|
||||||
|
var o = {};
|
||||||
|
return function () {
|
||||||
|
o[key] = "#fc0";
|
||||||
|
r.attr(o);
|
||||||
|
expect(r.node.getAttribute(key)).to.be("#ffcc00");
|
||||||
|
o[key] = "rgb(255, 204, 0)";
|
||||||
|
r.attr(o);
|
||||||
|
expect(r.node.getAttribute(key)).to.be("#ffcc00");
|
||||||
|
o[key] = "hsl(0.1333, 1, .5)";
|
||||||
|
r.attr(o);
|
||||||
|
expect(r.node.getAttribute(key)).to.be("#ffcc00");
|
||||||
|
o[key] = "hsb(0.1333, 1, 1)";
|
||||||
|
r.attr(o);
|
||||||
|
expect(r.node.getAttribute(key)).to.be("#ffcc00");
|
||||||
|
o[key] = "rgba(255, 204, 0, .5)";
|
||||||
|
r.attr(o);
|
||||||
|
expect(r.node.getAttribute(key)).to.be("rgba(255,204,0,0.5)");
|
||||||
|
o[key] = "hsla(0.1333, 1, .5, .5)";
|
||||||
|
r.attr(o);
|
||||||
|
expect(r.node.getAttribute(key)).to.be("rgba(255,204,0,0.5)");
|
||||||
|
o[key] = "hsba(0.1333, 1, 1, .5)";
|
||||||
|
r.attr(o);
|
||||||
|
expect(r.node.getAttribute(key)).to.be("rgba(255,204,0,0.5)");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function colorTestStyle(key) {
|
||||||
|
var o = {};
|
||||||
|
return function () {
|
||||||
|
function val() {
|
||||||
|
return Savage.color(r.node.style[key]).hex;
|
||||||
|
}
|
||||||
|
o[key] = "#fc0";
|
||||||
|
r.attr(o);
|
||||||
|
expect(val()).to.be("#ffcc00");
|
||||||
|
o[key] = "rgb(255, 204, 0)";
|
||||||
|
r.attr(o);
|
||||||
|
expect(val()).to.be("#ffcc00");
|
||||||
|
o[key] = "hsl(0.1333, 1, .5)";
|
||||||
|
r.attr(o);
|
||||||
|
expect(val()).to.be("#ffcc00");
|
||||||
|
o[key] = "hsb(0.1333, 1, 1)";
|
||||||
|
r.attr(o);
|
||||||
|
expect(val()).to.be("#ffcc00");
|
||||||
|
o[key] = "rgba(255, 204, 0, .5)";
|
||||||
|
r.attr(o);
|
||||||
|
expect(val()).to.be("#ffcc00");
|
||||||
|
o[key] = "hsla(0.1333, 1, .5, .5)";
|
||||||
|
r.attr(o);
|
||||||
|
expect(val()).to.be("#ffcc00");
|
||||||
|
o[key] = "hsba(0.1333, 1, 1, .5)";
|
||||||
|
r.attr(o);
|
||||||
|
expect(val()).to.be("#ffcc00");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
it("sets fill", colorTestProp("fill"));
|
||||||
|
it("sets stroke", colorTestStyle("stroke"));
|
||||||
|
it("circle core attributes", function () {
|
||||||
|
var c = s.circle(10, 20, 30);
|
||||||
|
expect(c.node.getAttribute("cx")).to.be("10");
|
||||||
|
expect(c.node.getAttribute("cy")).to.be("20");
|
||||||
|
expect(c.node.getAttribute("r")).to.be("30");
|
||||||
|
c.attr({
|
||||||
|
cx: 40,
|
||||||
|
cy: 50,
|
||||||
|
r: "5%"
|
||||||
|
});
|
||||||
|
expect(c.node.getAttribute("cx")).to.be("40");
|
||||||
|
expect(c.node.getAttribute("cy")).to.be("50");
|
||||||
|
expect(c.node.getAttribute("r")).to.be("5%");
|
||||||
|
});
|
||||||
|
it("rect core attributes", function () {
|
||||||
|
var c = s.rect(10, 20, 30, 40);
|
||||||
|
expect(c.node.getAttribute("x")).to.be("10");
|
||||||
|
expect(c.node.getAttribute("y")).to.be("20");
|
||||||
|
expect(c.node.getAttribute("width")).to.be("30");
|
||||||
|
expect(c.node.getAttribute("height")).to.be("40");
|
||||||
|
c.attr({
|
||||||
|
x: 40,
|
||||||
|
y: 50,
|
||||||
|
width: "5%",
|
||||||
|
height: "6%",
|
||||||
|
r: 10
|
||||||
|
});
|
||||||
|
expect(c.node.getAttribute("x")).to.be("40");
|
||||||
|
expect(c.node.getAttribute("y")).to.be("50");
|
||||||
|
expect(c.node.getAttribute("width")).to.be("5%");
|
||||||
|
expect(c.node.getAttribute("height")).to.be("6%");
|
||||||
|
expect(c.node.getAttribute("rx")).to.be("10");
|
||||||
|
expect(c.node.getAttribute("ry")).to.be("10");
|
||||||
|
});
|
||||||
|
it("ellipse core attributes", function () {
|
||||||
|
var c = s.ellipse(10, 20, 30, 40);
|
||||||
|
expect(c.node.getAttribute("cx")).to.be("10");
|
||||||
|
expect(c.node.getAttribute("cy")).to.be("20");
|
||||||
|
expect(c.node.getAttribute("rx")).to.be("30");
|
||||||
|
expect(c.node.getAttribute("ry")).to.be("40");
|
||||||
|
c.attr({
|
||||||
|
cx: 40,
|
||||||
|
cy: 50,
|
||||||
|
rx: "5%",
|
||||||
|
ry: "6%"
|
||||||
|
});
|
||||||
|
expect(c.node.getAttribute("cx")).to.be("40");
|
||||||
|
expect(c.node.getAttribute("cy")).to.be("50");
|
||||||
|
expect(c.node.getAttribute("rx")).to.be("5%");
|
||||||
|
expect(c.node.getAttribute("ry")).to.be("6%");
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
mocha.checkLeaks();
|
mocha.checkLeaks();
|
||||||
|
|
Loading…
Reference in New Issue