Markers, Animation of colour, transform and path, mouse and touch events
parent
2270a96f12
commit
8766ae2c79
142
demojs.html
142
demojs.html
|
@ -13,6 +13,8 @@
|
||||||
<script src="elemental.js"></script>
|
<script src="elemental.js"></script>
|
||||||
<script src="svg.js"></script>
|
<script src="svg.js"></script>
|
||||||
<script src="savage.set.js"></script>
|
<script src="savage.set.js"></script>
|
||||||
|
<script src="savage.equal.js"></script>
|
||||||
|
<script src="savage.mouse.js"></script>
|
||||||
<script type="text/x-svg" id="svg">
|
<script type="text/x-svg" id="svg">
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
@ -30,66 +32,88 @@
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
// 1
|
// 1;
|
||||||
var s = Savage("100%", 600);
|
// var s = Savage("100%", 600);
|
||||||
// 2
|
//
|
||||||
var c = s.circle(100, 100, 50);
|
// 2;
|
||||||
// 3
|
// var c = s.circle(100, 100, 50);
|
||||||
c.attr({
|
//
|
||||||
fill: "#bada55",
|
// 3;
|
||||||
stroke: "#000",
|
// c.attr({
|
||||||
"stroke-width": 5
|
// fill: "#bada55",
|
||||||
});
|
// stroke: "#000",
|
||||||
// 4
|
// "stroke-width": 5
|
||||||
var c2 = s.circle(70, 100, 40);
|
// });
|
||||||
var g = s.group(c2, s.circle(130, 100, 40));
|
//
|
||||||
g.attr({
|
// 4;
|
||||||
fill: "#fff"
|
// var c2 = s.circle(70, 100, 40);
|
||||||
});
|
// var g = s.group(c2, s.circle(130, 100, 40));
|
||||||
// 5
|
// g.attr({
|
||||||
c.attr({
|
// fill: "#fff"
|
||||||
mask: g
|
// });
|
||||||
});
|
//
|
||||||
// 6
|
// 5;
|
||||||
c2.animate({r: 25}, 1000);
|
// c.attr({
|
||||||
// 7
|
// mask: g
|
||||||
g.select("circle:nth-child(2)").animate({r: 25}, 1000);
|
// });
|
||||||
// 8
|
//
|
||||||
var p = s.path("M10-5-10,15M15,0,0,15M0-5-20,15").attr({
|
// 6;
|
||||||
fill: "none",
|
// c2.animate({r: 25}, 1000);
|
||||||
stroke: "#bada55",
|
//
|
||||||
strokeWidth: 5
|
// 7;
|
||||||
}).pattern(0, 0, 10, 10);
|
// g.select("circle:nth-child(2)").animate({r: 25}, 1000);
|
||||||
c.attr({
|
//
|
||||||
fill: p
|
// 8;
|
||||||
});
|
// var p = s.path("M10-5-10,15M15,0,0,15M0-5-20,15").attr({
|
||||||
// 9
|
// fill: "none",
|
||||||
g.attr({
|
// stroke: "#bada55",
|
||||||
fill: Savage(document.getElementById("pattern"))
|
// strokeWidth: 5
|
||||||
});
|
// }).pattern(0, 0, 10, 10);
|
||||||
// 10
|
// c.attr({
|
||||||
g.attr({fill: "r()#fff-#000"});
|
// fill: p
|
||||||
// 11
|
// });
|
||||||
g.attr({fill: "R(100, 100, 50)#fff-#000"});
|
//
|
||||||
// 12
|
// 9;
|
||||||
var svg = document.getElementById("svg").text;
|
// g.attr({
|
||||||
var f = Savage.fragment(svg);
|
// fill: Savage(document.getElementById("pattern"))
|
||||||
f.select("path[fill='#D40000']").attr({fill: "#bada55"});
|
// });
|
||||||
g = s.group(f.selectAll("path"));
|
//
|
||||||
s.append(g);
|
// 10;
|
||||||
// 13
|
// g.attr({fill: "r()#fff-#000"});
|
||||||
g.attr({
|
//
|
||||||
transform: "r45t100,0s.5"
|
// 11;
|
||||||
});
|
// g.attr({fill: "R(100, 100, 50)#fff-#000"});
|
||||||
|
//
|
||||||
|
// 12;
|
||||||
|
// p.select("path").animate({stroke: "#f00"}, 1000);
|
||||||
|
//
|
||||||
|
// 13;
|
||||||
|
// var svg = document.getElementById("svg").text;
|
||||||
|
// var f = Savage.fragment(svg);
|
||||||
|
// // f.select("path[fill='#D40000']").attr({fill: "#bada55"});
|
||||||
|
// g = s.group(f.selectAll("path"));
|
||||||
|
// s.append(g);
|
||||||
|
//
|
||||||
|
// 14;
|
||||||
|
// g.attr({
|
||||||
|
// transform: "r45t100,0s.5"
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// 15;
|
||||||
// console.log(g.attr("transform"));
|
// console.log(g.attr("transform"));
|
||||||
// 14
|
//
|
||||||
s.text(200, 100, "SAVAGE");
|
// 16;
|
||||||
// 15
|
// g.drag();
|
||||||
var t = s.text(200, 120, "SAVAGE".split(""));
|
//
|
||||||
t.selectAll("tspan tspan:nth-child(odd)").attr({
|
// 17;
|
||||||
fill: "#900",
|
// s.text(200, 100, "SAVAGE");
|
||||||
"font-size": "20px"
|
//
|
||||||
});
|
// 18;
|
||||||
|
// var t = s.text(200, 120, "SAVAGE".split(""));
|
||||||
|
// t.selectAll("tspan tspan:nth-child(odd)").attr({
|
||||||
|
// fill: "#900",
|
||||||
|
// "font-size": "20px"
|
||||||
|
// });
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
27
mina.js
27
mina.js
|
@ -21,7 +21,18 @@ window.mina = (function () {
|
||||||
function (callback) {
|
function (callback) {
|
||||||
setTimeout(callback, 16);
|
setTimeout(callback, 16);
|
||||||
},
|
},
|
||||||
|
isArray = Array.isArray || function (a) {
|
||||||
|
return a instanceof Array ||
|
||||||
|
Object.prototype.toString.call(a) == "[object Array]";
|
||||||
|
},
|
||||||
diff = function (a, b, A, B) {
|
diff = function (a, b, A, B) {
|
||||||
|
if (isArray(a)) {
|
||||||
|
res = [];
|
||||||
|
for (var i = 0, ii = a.length; i < ii; i++) {
|
||||||
|
res[i] = diff(a[i], b, A[i], B);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
var dif = (A - a) / (B - b);
|
var dif = (A - a) / (B - b);
|
||||||
return function (bb) {
|
return function (bb) {
|
||||||
return a + dif * (bb - b);
|
return a + dif * (bb - b);
|
||||||
|
@ -31,12 +42,24 @@ window.mina = (function () {
|
||||||
return +new Date;
|
return +new Date;
|
||||||
},
|
},
|
||||||
frame = function () {
|
frame = function () {
|
||||||
|
var value, one;
|
||||||
for (var i = 0; i < animations.length; i++) {
|
for (var i = 0; i < animations.length; i++) {
|
||||||
var a = animations[i],
|
var a = animations[i],
|
||||||
gen = a.b + (a.gen() - a.b) * a["*"] + a["+"],
|
gen = a.b + (a.gen() - a.b) * a["*"] + a["+"];
|
||||||
value = a.dif(gen),
|
if (isArray(a.a)) {
|
||||||
|
value = [];
|
||||||
|
for (var j = 0, jj = a.a.length; j < jj; j++) {
|
||||||
|
value[j] = a.dif[j](gen);
|
||||||
|
one = a.A[j] - a.a[j];
|
||||||
|
value[j] = one ?
|
||||||
|
a.a[j] + a.easing((value[j] - a.a[j]) / one) * one :
|
||||||
|
a.a[j];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = a.dif(gen);
|
||||||
one = a.A - a.a;
|
one = a.A - a.a;
|
||||||
value = a.a + a.easing((value - a.a) / one) * one;
|
value = a.a + a.easing((value - a.a) / one) * one;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (a.stopper(gen)) {
|
if (a.stopper(gen)) {
|
||||||
if (--a.iterations) {
|
if (--a.iterations) {
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
Savage.plugin(function (Savage, Element, Paper, glob) {
|
||||||
|
var names = {},
|
||||||
|
reUnit = /[a-z]+$/i,
|
||||||
|
Str = String;
|
||||||
|
names.stroke = names.fill = "colour";
|
||||||
|
function getEmpty(item) {
|
||||||
|
var l = item[0];
|
||||||
|
switch (l.toLowerCase()) {
|
||||||
|
case "t": return [l, 0, 0];
|
||||||
|
case "m": return [l, 1, 0, 0, 1, 0, 0];
|
||||||
|
case "r": if (item.length == 4) {
|
||||||
|
return [l, 0, item[2], item[3]];
|
||||||
|
} else {
|
||||||
|
return [l, 0];
|
||||||
|
}
|
||||||
|
case "s": if (item.length == 5) {
|
||||||
|
return [l, 1, 1, item[3], item[4]];
|
||||||
|
} else if (item.length == 3) {
|
||||||
|
return [l, 1, 1];
|
||||||
|
} else {
|
||||||
|
return [l, 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function equaliseTransform(t1, t2) {
|
||||||
|
t2 = Str(t2).replace(/\.{3}|\u2026/g, t1);
|
||||||
|
t1 = Savage.parseTransformString(t1) || [];
|
||||||
|
t2 = Savage.parseTransformString(t2) || [];
|
||||||
|
var maxlength = Math.max(t1.length, t2.length),
|
||||||
|
from = [],
|
||||||
|
to = [],
|
||||||
|
i = 0, j, jj,
|
||||||
|
tt1, tt2;
|
||||||
|
for (; i < maxlength; i++) {
|
||||||
|
tt1 = t1[i] || getEmpty(t2[i]);
|
||||||
|
tt2 = t2[i] || getEmpty(tt1);
|
||||||
|
if ((tt1[0] != tt2[0]) ||
|
||||||
|
(tt1[0].toLowerCase() == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3])) ||
|
||||||
|
(tt1[0].toLowerCase() == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4]))
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
from[i] = [];
|
||||||
|
to[i] = [];
|
||||||
|
for (j = 0, jj = Math.max(tt1.length, tt2.length); j < jj; j++) {
|
||||||
|
j in tt1 && (from[i][j] = tt1[j]);
|
||||||
|
j in tt2 && (to[i][j] = tt2[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
from: path2array(from),
|
||||||
|
to: path2array(to),
|
||||||
|
f: getPath(from)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getNumber(val) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
function getUnit(unit) {
|
||||||
|
return function (val) {
|
||||||
|
return +val.toFixed(3) + unit;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getColour(clr) {
|
||||||
|
return Savage.rgb(clr[0], clr[1], clr[2]);
|
||||||
|
}
|
||||||
|
function getPath(path) {
|
||||||
|
var k = 0, i, ii, j, jj, out, a, b = [];
|
||||||
|
for (i = 0, ii = path.length; i < ii; i++) {
|
||||||
|
out = "[";
|
||||||
|
a = ['"' + path[i][0] + '"'];
|
||||||
|
for (j = 1, jj = path[i].length; j < jj; j++) {
|
||||||
|
a[j] = "val[" + (k++) + "]";
|
||||||
|
}
|
||||||
|
out += a + "]";
|
||||||
|
b[i] = out;
|
||||||
|
}
|
||||||
|
return Function("val", "return Savage.path2string.call([" + b + "]);");
|
||||||
|
}
|
||||||
|
function path2array(path) {
|
||||||
|
var out = [];
|
||||||
|
for (var i = 0, ii = path.length; i < ii; i++) {
|
||||||
|
for (var j = 1, jj = path[i].length; j < jj; j++) {
|
||||||
|
out.push(path[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
Element.prototype.equal = function (name, b) {
|
||||||
|
var A, B, a = Str(this.attr(name) || "");
|
||||||
|
if (a == +a && b == +b) {
|
||||||
|
return {
|
||||||
|
from: +a,
|
||||||
|
to: +b,
|
||||||
|
f: getNumber
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (names[name] == "colour") {
|
||||||
|
A = Savage.color(a);
|
||||||
|
B = Savage.color(b);
|
||||||
|
return {
|
||||||
|
from: [A.r, A.g, A.b],
|
||||||
|
to: [B.r, B.g, B.b],
|
||||||
|
f: getColour
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (name == "transform" || name == "gradientTransform" || name == "patternTransform") {
|
||||||
|
// TODO: b could be an SVG transform string or matrix
|
||||||
|
return equaliseTransform(a.local, b);
|
||||||
|
}
|
||||||
|
if (name == "d" || name == "path") {
|
||||||
|
A = Savage.path2curve(a, b);
|
||||||
|
return {
|
||||||
|
from: path2array(A[0]),
|
||||||
|
to: path2array(A[1]),
|
||||||
|
f: getPath(A[0])
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var aUnit = a.match(reUnit),
|
||||||
|
bUnit = b.match(reUnit);
|
||||||
|
if (aUnit && aUnit == bUnit) {
|
||||||
|
return {
|
||||||
|
from: parseFloat(a),
|
||||||
|
to: parseFloat(b),
|
||||||
|
f: getUnit(aUnit)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
from: this.asPX(name),
|
||||||
|
to: this.asPX(name, b),
|
||||||
|
f: getNumber
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
|
@ -0,0 +1,540 @@
|
||||||
|
Savage.plugin(function (Savage, Element, Paper, glob) {
|
||||||
|
var elproto = Element.prototype,
|
||||||
|
has = "hasOwnProperty",
|
||||||
|
supportsTouch = "createTouch" in glob.doc,
|
||||||
|
events = [
|
||||||
|
"click", "dblclick", "mousedown", "mousemove", "mouseout",
|
||||||
|
"mouseover", "mouseup", "touchstart", "touchmove", "touchend",
|
||||||
|
"touchcancel"
|
||||||
|
],
|
||||||
|
touchMap = {
|
||||||
|
mousedown: "touchstart",
|
||||||
|
mousemove: "touchmove",
|
||||||
|
mouseup: "touchend"
|
||||||
|
},
|
||||||
|
getScroll = function (xy) {
|
||||||
|
var name = xy == "y" ? "scrollTop" : "scrollLeft";
|
||||||
|
return glob.doc.documentElement[name] || glob.doc.body[name];
|
||||||
|
},
|
||||||
|
preventDefault = function () {
|
||||||
|
this.returnValue = false;
|
||||||
|
},
|
||||||
|
preventTouch = function () {
|
||||||
|
return this.originalEvent.preventDefault();
|
||||||
|
},
|
||||||
|
stopPropagation = function () {
|
||||||
|
this.cancelBubble = true;
|
||||||
|
},
|
||||||
|
stopTouch = function () {
|
||||||
|
return this.originalEvent.stopPropagation();
|
||||||
|
},
|
||||||
|
addEvent = (function () {
|
||||||
|
if (glob.doc.addEventListener) {
|
||||||
|
return function (obj, type, fn, element) {
|
||||||
|
var realName = supportsTouch && touchMap[type] ? touchMap[type] : type,
|
||||||
|
f = function (e) {
|
||||||
|
var scrollY = getScroll("y"),
|
||||||
|
scrollX = getScroll("x"),
|
||||||
|
x = e.clientX + scrollX,
|
||||||
|
y = e.clientY + scrollY;
|
||||||
|
if (supportsTouch && touchMap[has](type)) {
|
||||||
|
for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) {
|
||||||
|
if (e.targetTouches[i].target == obj) {
|
||||||
|
var olde = e;
|
||||||
|
e = e.targetTouches[i];
|
||||||
|
e.originalEvent = olde;
|
||||||
|
e.preventDefault = preventTouch;
|
||||||
|
e.stopPropagation = stopTouch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fn.call(element, e, x, y);
|
||||||
|
};
|
||||||
|
obj.addEventListener(realName, f, false);
|
||||||
|
return function () {
|
||||||
|
obj.removeEventListener(realName, f, false);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} else if (glob.doc.attachEvent) {
|
||||||
|
return function (obj, type, fn, element) {
|
||||||
|
var f = function (e) {
|
||||||
|
e = e || glob.win.event;
|
||||||
|
var scrollY = getScroll("y"),
|
||||||
|
scrollX = getScroll("x"),
|
||||||
|
x = e.clientX + scrollX,
|
||||||
|
y = e.clientY + scrollY;
|
||||||
|
e.preventDefault = e.preventDefault || preventDefault;
|
||||||
|
e.stopPropagation = e.stopPropagation || stopPropagation;
|
||||||
|
return fn.call(element, e, x, y);
|
||||||
|
};
|
||||||
|
obj.attachEvent("on" + type, f);
|
||||||
|
var detacher = function () {
|
||||||
|
obj.detachEvent("on" + type, f);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
return detacher;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})(),
|
||||||
|
drag = [],
|
||||||
|
dragMove = function (e) {
|
||||||
|
var x = e.clientX,
|
||||||
|
y = e.clientY,
|
||||||
|
scrollY = getScroll("y"),
|
||||||
|
scrollX = getScroll("x"),
|
||||||
|
dragi,
|
||||||
|
j = drag.length;
|
||||||
|
while (j--) {
|
||||||
|
dragi = drag[j];
|
||||||
|
if (supportsTouch) {
|
||||||
|
var i = e.touches.length,
|
||||||
|
touch;
|
||||||
|
while (i--) {
|
||||||
|
touch = e.touches[i];
|
||||||
|
if (touch.identifier == dragi.el._drag.id) {
|
||||||
|
x = touch.clientX;
|
||||||
|
y = touch.clientY;
|
||||||
|
(e.originalEvent ? e.originalEvent : e).preventDefault();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
var node = dragi.el.node,
|
||||||
|
o,
|
||||||
|
next = node.nextSibling,
|
||||||
|
parent = node.parentNode,
|
||||||
|
display = node.style.display;
|
||||||
|
// glob.win.opera && parent.removeChild(node);
|
||||||
|
// node.style.display = "none";
|
||||||
|
// o = dragi.el.paper.getElementByPoint(x, y);
|
||||||
|
// node.style.display = display;
|
||||||
|
// glob.win.opera && (next ? parent.insertBefore(node, next) : parent.appendChild(node));
|
||||||
|
// o && eve("savage.drag.over." + dragi.el.id, dragi.el, o);
|
||||||
|
x += scrollX;
|
||||||
|
y += scrollY;
|
||||||
|
eve("savage.drag.move." + dragi.el.id, dragi.move_scope || dragi.el, x - dragi.el._drag.x, y - dragi.el._drag.y, x, y, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dragUp = function (e) {
|
||||||
|
Savage.unmousemove(dragMove).unmouseup(dragUp);
|
||||||
|
var i = drag.length,
|
||||||
|
dragi;
|
||||||
|
while (i--) {
|
||||||
|
dragi = drag[i];
|
||||||
|
dragi.el._drag = {};
|
||||||
|
eve("savage.drag.end." + dragi.el.id, dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e);
|
||||||
|
}
|
||||||
|
drag = [];
|
||||||
|
};
|
||||||
|
/*\
|
||||||
|
* Element.click
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Adds event handler for click for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
/*\
|
||||||
|
* Element.unclick
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Removes event handler for click for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
|
||||||
|
/*\
|
||||||
|
* Element.dblclick
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Adds event handler for double click for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
/*\
|
||||||
|
* Element.undblclick
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Removes event handler for double click for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
|
||||||
|
/*\
|
||||||
|
* Element.mousedown
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Adds event handler for mousedown for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
/*\
|
||||||
|
* Element.unmousedown
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Removes event handler for mousedown for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
|
||||||
|
/*\
|
||||||
|
* Element.mousemove
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Adds event handler for mousemove for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
/*\
|
||||||
|
* Element.unmousemove
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Removes event handler for mousemove for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
|
||||||
|
/*\
|
||||||
|
* Element.mouseout
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Adds event handler for mouseout for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
/*\
|
||||||
|
* Element.unmouseout
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Removes event handler for mouseout for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
|
||||||
|
/*\
|
||||||
|
* Element.mouseover
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Adds event handler for mouseover for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
/*\
|
||||||
|
* Element.unmouseover
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Removes event handler for mouseover for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
|
||||||
|
/*\
|
||||||
|
* Element.mouseup
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Adds event handler for mouseup for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
/*\
|
||||||
|
* Element.unmouseup
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Removes event handler for mouseup for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
|
||||||
|
/*\
|
||||||
|
* Element.touchstart
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Adds event handler for touchstart for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
/*\
|
||||||
|
* Element.untouchstart
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Removes event handler for touchstart for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
|
||||||
|
/*\
|
||||||
|
* Element.touchmove
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Adds event handler for touchmove for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
/*\
|
||||||
|
* Element.untouchmove
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Removes event handler for touchmove for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
|
||||||
|
/*\
|
||||||
|
* Element.touchend
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Adds event handler for touchend for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
/*\
|
||||||
|
* Element.untouchend
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Removes event handler for touchend for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
|
||||||
|
/*\
|
||||||
|
* Element.touchcancel
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Adds event handler for touchcancel for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
/*\
|
||||||
|
* Element.untouchcancel
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Removes event handler for touchcancel for the element.
|
||||||
|
> Parameters
|
||||||
|
- handler (function) handler for the event
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
for (var i = events.length; i--;) {
|
||||||
|
(function (eventName) {
|
||||||
|
Savage[eventName] = elproto[eventName] = function (fn, scope) {
|
||||||
|
if (Savage.is(fn, "function")) {
|
||||||
|
this.events = this.events || [];
|
||||||
|
this.events.push({
|
||||||
|
name: eventName,
|
||||||
|
f: fn,
|
||||||
|
unbind: addEvent(this.shape || this.node || glob.doc, eventName, fn, scope || this)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
Savage["un" + eventName] = elproto["un" + eventName] = function (fn) {
|
||||||
|
var events = this.events || [],
|
||||||
|
l = events.length;
|
||||||
|
while (l--) if (events[l].name == eventName && events[l].f == fn) {
|
||||||
|
events[l].unbind();
|
||||||
|
events.splice(l, 1);
|
||||||
|
!events.length && delete this.events;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
})(events[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*\
|
||||||
|
* Element.data
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Adds or retrieves given value asociated with given key.
|
||||||
|
**
|
||||||
|
* See also @Element.removeData
|
||||||
|
> Parameters
|
||||||
|
- key (string) key to store data
|
||||||
|
- value (any) #optional value to store
|
||||||
|
= (object) @Element
|
||||||
|
* or, if value is not specified:
|
||||||
|
= (any) value
|
||||||
|
> Usage
|
||||||
|
| for (var i = 0, i < 5, i++) {
|
||||||
|
| paper.circle(10 + 15 * i, 10, 10)
|
||||||
|
| .attr({fill: "#000"})
|
||||||
|
| .data("i", i)
|
||||||
|
| .click(function () {
|
||||||
|
| alert(this.data("i"));
|
||||||
|
| });
|
||||||
|
| }
|
||||||
|
\*/
|
||||||
|
elproto.data = function (key, value) {
|
||||||
|
var data = eldata[this.id] = eldata[this.id] || {};
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
if (Savage.is(key, "object")) {
|
||||||
|
for (var i in key) if (key[has](i)) {
|
||||||
|
this.data(i, key[i]);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
eve("savage.data.get." + this.id, this, data[key], key);
|
||||||
|
return data[key];
|
||||||
|
}
|
||||||
|
data[key] = value;
|
||||||
|
eve("savage.data.set." + this.id, this, value, key);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
/*\
|
||||||
|
* Element.removeData
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Removes value associated with an element by given key.
|
||||||
|
* If key is not provided, removes all the data of the element.
|
||||||
|
> Parameters
|
||||||
|
- key (string) #optional key
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
elproto.removeData = function (key) {
|
||||||
|
if (key == null) {
|
||||||
|
eldata[this.id] = {};
|
||||||
|
} else {
|
||||||
|
eldata[this.id] && delete eldata[this.id][key];
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
/*\
|
||||||
|
* Element.hover
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Adds event handlers for hover for the element.
|
||||||
|
> Parameters
|
||||||
|
- f_in (function) handler for hover in
|
||||||
|
- f_out (function) handler for hover out
|
||||||
|
- icontext (object) #optional context for hover in handler
|
||||||
|
- ocontext (object) #optional context for hover out handler
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
elproto.hover = function (f_in, f_out, scope_in, scope_out) {
|
||||||
|
return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in);
|
||||||
|
};
|
||||||
|
/*\
|
||||||
|
* Element.unhover
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Removes event handlers for hover for the element.
|
||||||
|
> Parameters
|
||||||
|
- f_in (function) handler for hover in
|
||||||
|
- f_out (function) handler for hover out
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
elproto.unhover = function (f_in, f_out) {
|
||||||
|
return this.unmouseover(f_in).unmouseout(f_out);
|
||||||
|
};
|
||||||
|
var draggable = [];
|
||||||
|
/*\
|
||||||
|
* Element.drag
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Adds event handlers for drag of the element.
|
||||||
|
> Parameters
|
||||||
|
- onmove (function) handler for moving
|
||||||
|
- onstart (function) handler for drag start
|
||||||
|
- onend (function) handler for drag end
|
||||||
|
- mcontext (object) #optional context for moving handler
|
||||||
|
- scontext (object) #optional context for drag start handler
|
||||||
|
- econtext (object) #optional context for drag end handler
|
||||||
|
* Additionaly following `drag` events will be triggered: `drag.start.<id>` on start,
|
||||||
|
* `drag.end.<id>` on end and `drag.move.<id>` on every move. When element will be dragged over another element
|
||||||
|
* `drag.over.<id>` will be fired as well.
|
||||||
|
*
|
||||||
|
* Start event and start handler will be called in specified context or in context of the element with following parameters:
|
||||||
|
o x (number) x position of the mouse
|
||||||
|
o y (number) y position of the mouse
|
||||||
|
o event (object) DOM event object
|
||||||
|
* Move event and move handler will be called in specified context or in context of the element with following parameters:
|
||||||
|
o dx (number) shift by x from the start point
|
||||||
|
o dy (number) shift by y from the start point
|
||||||
|
o x (number) x position of the mouse
|
||||||
|
o y (number) y position of the mouse
|
||||||
|
o event (object) DOM event object
|
||||||
|
* End event and end handler will be called in specified context or in context of the element with following parameters:
|
||||||
|
o event (object) DOM event object
|
||||||
|
= (object) @Element
|
||||||
|
\*/
|
||||||
|
elproto.drag = function (onmove, onstart, onend, move_scope, start_scope, end_scope) {
|
||||||
|
if (!arguments.length) {
|
||||||
|
var origTransform;
|
||||||
|
return this.drag(function (dx, dy) {
|
||||||
|
this.attr({
|
||||||
|
transform: origTransform + (origTransform ? "T" : "t") + [dx, dy]
|
||||||
|
});
|
||||||
|
}, function () {
|
||||||
|
origTransform = this.transform().local;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function start(e) {
|
||||||
|
(e.originalEvent || e).preventDefault();
|
||||||
|
var scrollY = getScroll("y"),
|
||||||
|
scrollX = getScroll("x");
|
||||||
|
this._drag.x = e.clientX + scrollX;
|
||||||
|
this._drag.y = e.clientY + scrollY;
|
||||||
|
this._drag.id = e.identifier;
|
||||||
|
!drag.length && Savage.mousemove(dragMove).mouseup(dragUp);
|
||||||
|
drag.push({el: this, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope});
|
||||||
|
onstart && eve.on("savage.drag.start." + this.id, onstart);
|
||||||
|
onmove && eve.on("savage.drag.move." + this.id, onmove);
|
||||||
|
onend && eve.on("savage.drag.end." + this.id, onend);
|
||||||
|
eve("savage.drag.start." + this.id, start_scope || move_scope || this, e.clientX + scrollX, e.clientY + scrollY, e);
|
||||||
|
}
|
||||||
|
this._drag = {};
|
||||||
|
draggable.push({el: this, start: start});
|
||||||
|
this.mousedown(start);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
/*\
|
||||||
|
* Element.onDragOver
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Shortcut for assigning event handler for `drag.over.<id>` event, where id is id of the element (see @Element.id).
|
||||||
|
> Parameters
|
||||||
|
- f (function) handler for event, first argument would be the element you are dragging over
|
||||||
|
\*/
|
||||||
|
elproto.onDragOver = function (f) {
|
||||||
|
f ? eve.on("savage.drag.over." + this.id, f) : eve.unbind("savage.drag.over." + this.id);
|
||||||
|
};
|
||||||
|
/*\
|
||||||
|
* Element.undrag
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Removes all drag event handlers from given element.
|
||||||
|
\*/
|
||||||
|
elproto.undrag = function () {
|
||||||
|
var i = draggable.length;
|
||||||
|
while (i--) if (draggable[i].el == this) {
|
||||||
|
this.unmousedown(draggable[i].start);
|
||||||
|
draggable.splice(i, 1);
|
||||||
|
eve.unbind("savage.drag.*." + this.id);
|
||||||
|
}
|
||||||
|
!draggable.length && Savage.unmousemove(dragMove).unmouseup(dragUp);
|
||||||
|
};
|
||||||
|
});
|
243
svg.js
243
svg.js
|
@ -37,6 +37,7 @@ var has = "hasOwnProperty",
|
||||||
colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,
|
colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,
|
||||||
isnan = {"NaN": 1, "Infinity": 1, "-Infinity": 1},
|
isnan = {"NaN": 1, "Infinity": 1, "-Infinity": 1},
|
||||||
bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,
|
bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,
|
||||||
|
reURLValue = /^url\(#?([^)]+)\)$/,
|
||||||
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"),
|
||||||
|
@ -860,15 +861,105 @@ function box(x, y, width, height) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// Transformations
|
// Transformations
|
||||||
function path2string() {
|
var path2string = Savage.path2string = function () {
|
||||||
return this.join(",").replace(p2s, "$1");
|
return this.join(",").replace(p2s, "$1");
|
||||||
}
|
};
|
||||||
function pathClone(pathArray) {
|
function pathClone(pathArray) {
|
||||||
var res = clone(pathArray);
|
var res = clone(pathArray);
|
||||||
res.toString = path2string;
|
res.toString = path2string;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
function parseTransformString(TString) {
|
|
||||||
|
// http://schepers.cc/getting-to-the-point
|
||||||
|
function catmullRom2bezier(crp, z) {
|
||||||
|
var d = [];
|
||||||
|
for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) {
|
||||||
|
var p = [
|
||||||
|
{x: +crp[i - 2], y: +crp[i - 1]},
|
||||||
|
{x: +crp[i], y: +crp[i + 1]},
|
||||||
|
{x: +crp[i + 2], y: +crp[i + 3]},
|
||||||
|
{x: +crp[i + 4], y: +crp[i + 5]}
|
||||||
|
];
|
||||||
|
if (z) {
|
||||||
|
if (!i) {
|
||||||
|
p[0] = {x: +crp[iLen - 2], y: +crp[iLen - 1]};
|
||||||
|
} else if (iLen - 4 == i) {
|
||||||
|
p[3] = {x: +crp[0], y: +crp[1]};
|
||||||
|
} else if (iLen - 2 == i) {
|
||||||
|
p[2] = {x: +crp[0], y: +crp[1]};
|
||||||
|
p[3] = {x: +crp[2], y: +crp[3]};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (iLen - 4 == i) {
|
||||||
|
p[3] = p[2];
|
||||||
|
} else if (!i) {
|
||||||
|
p[0] = {x: +crp[i], y: +crp[i + 1]};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d.push(["C",
|
||||||
|
(-p[0].x + 6 * p[1].x + p[2].x) / 6,
|
||||||
|
(-p[0].y + 6 * p[1].y + p[2].y) / 6,
|
||||||
|
(p[1].x + 6 * p[2].x - p[3].x) / 6,
|
||||||
|
(p[1].y + 6*p[2].y - p[3].y) / 6,
|
||||||
|
p[2].x,
|
||||||
|
p[2].y
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
/*\
|
||||||
|
* Savage.parsePathString
|
||||||
|
[ method ]
|
||||||
|
**
|
||||||
|
* Utility method
|
||||||
|
**
|
||||||
|
* Parses given path string into an array of arrays of path segments.
|
||||||
|
> Parameters
|
||||||
|
- pathString (string|array) path string or array of segments (in the last case it will be returned straight away)
|
||||||
|
= (array) array of segments.
|
||||||
|
\*/
|
||||||
|
Savage.parsePathString = function (pathString) {
|
||||||
|
if (!pathString) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var pth = paths(pathString);
|
||||||
|
if (pth.arr) {
|
||||||
|
return pathClone(pth.arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0},
|
||||||
|
data = [];
|
||||||
|
if (is(pathString, "array") && is(pathString[0], "array")) { // rough assumption
|
||||||
|
data = pathClone(pathString);
|
||||||
|
}
|
||||||
|
if (!data.length) {
|
||||||
|
Str(pathString).replace(pathCommand, function (a, b, c) {
|
||||||
|
var params = [],
|
||||||
|
name = b.toLowerCase();
|
||||||
|
c.replace(pathValues, function (a, b) {
|
||||||
|
b && params.push(+b);
|
||||||
|
});
|
||||||
|
if (name == "m" && params.length > 2) {
|
||||||
|
data.push([b].concat(params.splice(0, 2)));
|
||||||
|
name = "l";
|
||||||
|
b = b == "m" ? "l" : "L";
|
||||||
|
}
|
||||||
|
if (name == "r") {
|
||||||
|
data.push([b].concat(params));
|
||||||
|
} else while (params.length >= paramCounts[name]) {
|
||||||
|
data.push([b].concat(params.splice(0, paramCounts[name])));
|
||||||
|
if (!paramCounts[name]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
data.toString = path2string;
|
||||||
|
pth.arr = pathClone(data);
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
var parseTransformString = Savage.parseTransformString = function (TString) {
|
||||||
if (!TString) {
|
if (!TString) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -889,7 +980,7 @@ function parseTransformString(TString) {
|
||||||
}
|
}
|
||||||
data.toString = path2string;
|
data.toString = path2string;
|
||||||
return data;
|
return data;
|
||||||
}
|
};
|
||||||
function svgTransform2string(tstr) {
|
function svgTransform2string(tstr) {
|
||||||
var res = [];
|
var res = [];
|
||||||
tstr = tstr.replace(/(?:^|\s)(\w+)\(([^)]+)\)/g, function (all, name, params) {
|
tstr = tstr.replace(/(?:^|\s)(\w+)\(([^)]+)\)/g, function (all, name, params) {
|
||||||
|
@ -1086,7 +1177,7 @@ function ellipsePath(x, y, rx, ry, a) {
|
||||||
res.toString = path2string;
|
res.toString = path2string;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
function unit2px(el) {
|
function unit2px(el, name, value) {
|
||||||
var defs = el.paper.defs,
|
var defs = el.paper.defs,
|
||||||
out = {},
|
out = {},
|
||||||
mgr = el.paper.measurer;
|
mgr = el.paper.measurer;
|
||||||
|
@ -1115,28 +1206,57 @@ function unit2px(el) {
|
||||||
$(mgr, {height: val});
|
$(mgr, {height: val});
|
||||||
return mgr.getBBox().height;
|
return mgr.getBBox().height;
|
||||||
}
|
}
|
||||||
|
function set(nam, f) {
|
||||||
|
if (name == null) {
|
||||||
|
out[nam] = f(el.attr(nam));
|
||||||
|
} else if (nam == name) {
|
||||||
|
out = f(value == null ? el.attr(nam) : value);
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (el.type) {
|
switch (el.type) {
|
||||||
case "rect":
|
case "rect":
|
||||||
out.rx = getW(el.attr("rx"));
|
set("rx", getW);
|
||||||
out.ry = getH(el.attr("ry"));
|
set("ry", getH);
|
||||||
case "image":
|
case "image":
|
||||||
out.width = getW(el.attr("width"));
|
set("width", getW);
|
||||||
out.height = getH(el.attr("height"));
|
set("height", getH);
|
||||||
case "text":
|
case "text":
|
||||||
out.x = getW(el.attr("x"));
|
set("x", getW);
|
||||||
out.y = getH(el.attr("y"));
|
set("y", getH);
|
||||||
break;
|
break;
|
||||||
case "circle":
|
case "circle":
|
||||||
out.cx = getW(el.attr("cx"));
|
set("cx", getW);
|
||||||
out.cy = getH(el.attr("cy"));
|
set("cy", getH);
|
||||||
out.r = getW(el.attr("r"));
|
set("r", getW);
|
||||||
break;
|
break;
|
||||||
case "ellipse":
|
case "ellipse":
|
||||||
out.cx = getW(el.attr("cx"));
|
set("cx", getW);
|
||||||
out.cy = getH(el.attr("cy"));
|
set("cy", getH);
|
||||||
out.rx = getW(el.attr("rx"));
|
set("rx", getW);
|
||||||
out.ry = getH(el.attr("ry"));
|
set("ry", getH);
|
||||||
break;
|
break;
|
||||||
|
case "line":
|
||||||
|
set("x1", getW);
|
||||||
|
set("x2", getW);
|
||||||
|
set("y1", getH);
|
||||||
|
set("y2", getH);
|
||||||
|
break;
|
||||||
|
case "marker":
|
||||||
|
set("refX", getW);
|
||||||
|
set("markerWidth", getW);
|
||||||
|
set("refY", getH);
|
||||||
|
set("markerHeight", getH);
|
||||||
|
break;
|
||||||
|
case "radialGradient":
|
||||||
|
set("fx", getW);
|
||||||
|
set("fy", getH);
|
||||||
|
break;
|
||||||
|
case "tspan":
|
||||||
|
set("dx", getW);
|
||||||
|
set("dy", getH);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
out = null;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -1223,7 +1343,7 @@ var pathDimensions = function (path) {
|
||||||
return pathClone(pth.rel);
|
return pathClone(pth.rel);
|
||||||
}
|
}
|
||||||
if (!is(pathArray, array) || !is(pathArray && pathArray[0], array)) { // rough assumption
|
if (!is(pathArray, array) || !is(pathArray && pathArray[0], array)) { // rough assumption
|
||||||
pathArray = parsePathString(pathArray);
|
pathArray = Savage.parsePathString(pathArray);
|
||||||
}
|
}
|
||||||
var res = [],
|
var res = [],
|
||||||
x = 0,
|
x = 0,
|
||||||
|
@ -1302,7 +1422,7 @@ var pathDimensions = function (path) {
|
||||||
return pathClone(pth.abs);
|
return pathClone(pth.abs);
|
||||||
}
|
}
|
||||||
if (!is(pathArray, "array") || !is(pathArray && pathArray[0], "array")) { // rough assumption
|
if (!is(pathArray, "array") || !is(pathArray && pathArray[0], "array")) { // rough assumption
|
||||||
pathArray = parsePathString(pathArray);
|
pathArray = Savage.parsePathString(pathArray);
|
||||||
}
|
}
|
||||||
if (!pathArray || !pathArray.length) {
|
if (!pathArray || !pathArray.length) {
|
||||||
return [["M", 0, 0]];
|
return [["M", 0, 0]];
|
||||||
|
@ -1565,7 +1685,7 @@ var pathDimensions = function (path) {
|
||||||
max: {x: mmax.apply(0, x), y: mmax.apply(0, y)}
|
max: {x: mmax.apply(0, x), y: mmax.apply(0, y)}
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
path2curve = cacher(function (path, path2) {
|
path2curve = Savage.path2curve = cacher(function (path, path2) {
|
||||||
var pth = !path2 && paths(path);
|
var pth = !path2 && paths(path);
|
||||||
if (!path2 && pth.curve) {
|
if (!path2 && pth.curve) {
|
||||||
return pathClone(pth.curve);
|
return pathClone(pth.curve);
|
||||||
|
@ -1764,17 +1884,9 @@ function arrayFirstValue(arr) {
|
||||||
}
|
}
|
||||||
return box(_.bbox);
|
return box(_.bbox);
|
||||||
};
|
};
|
||||||
function prop(name) {
|
var propString = function () {
|
||||||
return function () {
|
return this.local;
|
||||||
return this[name];
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
function always(x) {
|
|
||||||
return function () {
|
|
||||||
return x;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
var propString = prop("string");
|
|
||||||
elproto.transform = function (tstr) {
|
elproto.transform = function (tstr) {
|
||||||
var _ = this._;
|
var _ = this._;
|
||||||
if (tstr == null) {
|
if (tstr == null) {
|
||||||
|
@ -1864,6 +1976,9 @@ function arrayFirstValue(arr) {
|
||||||
}
|
}
|
||||||
return set;
|
return set;
|
||||||
};
|
};
|
||||||
|
elproto.asPX = function (attr, value) {
|
||||||
|
return unit2px(this, attr, value);
|
||||||
|
};
|
||||||
elproto.use = function () {
|
elproto.use = function () {
|
||||||
var use,
|
var use,
|
||||||
id = this.node.id;
|
id = this.node.id;
|
||||||
|
@ -1939,18 +2054,23 @@ function arrayFirstValue(arr) {
|
||||||
return p;
|
return p;
|
||||||
};
|
};
|
||||||
// animation
|
// animation
|
||||||
function applyAttr(el, key) {
|
function applyAttr(el, key, f) {
|
||||||
var at = {};
|
var at = {};
|
||||||
return function (value) {
|
return function (value) {
|
||||||
at[key] = value;
|
at[key] = f ? f(value) : value;
|
||||||
el.attr(at);
|
el.attr(at);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
elproto.animate = function (attrs, ms, callback) {
|
elproto.animate = function (attrs, ms, callback) {
|
||||||
var anims = [];
|
var anims = [], eq;
|
||||||
for (var key in attrs) if (attrs[has](key)) {
|
for (var key in attrs) if (attrs[has](key)) {
|
||||||
|
if (this.equal) {
|
||||||
|
eq = this.equal(key, Str(attrs[key]));
|
||||||
|
anims.push(mina(eq.from, eq.to, ms, applyAttr(this, key, eq.f)));
|
||||||
|
} else {
|
||||||
anims.push(mina(+this.attr(key), +attrs[key], ms, applyAttr(this, key)));
|
anims.push(mina(+this.attr(key), +attrs[key], ms, applyAttr(this, key)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}(Element.prototype));
|
}(Element.prototype));
|
||||||
Savage.parse = function (svg) {
|
Savage.parse = function (svg) {
|
||||||
|
@ -2436,6 +2556,17 @@ eve.on("savage.util.grad.parse", function parseGrad(string) {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
eve.on("savage.util.attr.d", function (value) {
|
||||||
|
if (is(value, "array") && is(value[0], "array")) {
|
||||||
|
value = path2string.call(value);
|
||||||
|
}
|
||||||
|
value = Str(value);
|
||||||
|
if (value.match(/[ruo]/i)) {
|
||||||
|
value = pathToAbsolute(value);
|
||||||
|
}
|
||||||
|
$(this.node, {d: value});
|
||||||
|
eve.stop();
|
||||||
|
});
|
||||||
eve.on("savage.util.attr.path", function (value) {
|
eve.on("savage.util.attr.path", function (value) {
|
||||||
this.attr({d: value});
|
this.attr({d: value});
|
||||||
eve.stop();
|
eve.stop();
|
||||||
|
@ -2528,6 +2659,50 @@ eve.on("savage.util.getattr.transform", function () {
|
||||||
eve.stop();
|
eve.stop();
|
||||||
return this.transform();
|
return this.transform();
|
||||||
})(-1);
|
})(-1);
|
||||||
|
// Markers
|
||||||
|
(function () {
|
||||||
|
function getter(end) {
|
||||||
|
return function () {
|
||||||
|
eve.stop();
|
||||||
|
var style = glob.doc.defaultView.getComputedStyle(this.node, null).getPropertyValue("marker-" + end);
|
||||||
|
if (style == "none") {
|
||||||
|
return style;
|
||||||
|
} else {
|
||||||
|
return Savage(glob.doc.getElementById(style.match(reURLValue)[1]));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function setter(end) {
|
||||||
|
return function (value) {
|
||||||
|
eve.stop();
|
||||||
|
var name = "marker" + end.charAt(0).toUpperCase() + end.substring(1);
|
||||||
|
if (value == "" || !value) {
|
||||||
|
this.node.style[name] = "none";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (value.type == "marker") {
|
||||||
|
var id = value.node.id;
|
||||||
|
if (!id) {
|
||||||
|
$(value.node, {id: value.id});
|
||||||
|
}
|
||||||
|
this.node.style[name] = "url(#" + id + ")";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
eve.on("savage.util.getattr.marker-end", getter("end"))(-1);
|
||||||
|
eve.on("savage.util.getattr.markerEnd", getter("end"))(-1);
|
||||||
|
eve.on("savage.util.getattr.marker-start", getter("start"))(-1);
|
||||||
|
eve.on("savage.util.getattr.markerStart", getter("start"))(-1);
|
||||||
|
eve.on("savage.util.getattr.marker-mid", getter("mid"))(-1);
|
||||||
|
eve.on("savage.util.getattr.markerMid", getter("mid"))(-1);
|
||||||
|
eve.on("savage.util.attr.marker-end", setter("end"))(-1);
|
||||||
|
eve.on("savage.util.attr.markerEnd", setter("end"))(-1);
|
||||||
|
eve.on("savage.util.attr.marker-start", setter("start"))(-1);
|
||||||
|
eve.on("savage.util.attr.markerStart", setter("start"))(-1);
|
||||||
|
eve.on("savage.util.attr.marker-mid", setter("mid"))(-1);
|
||||||
|
eve.on("savage.util.attr.markerMid", setter("mid"))(-1);
|
||||||
|
}());
|
||||||
eve.on("savage.util.getattr.r", function () {
|
eve.on("savage.util.getattr.r", function () {
|
||||||
if (this.type == "rect" && $(this.node, "rx") == $(this.node, "ry")) {
|
if (this.type == "rect" && $(this.node, "rx") == $(this.node, "ry")) {
|
||||||
eve.stop();
|
eve.stop();
|
||||||
|
|
Loading…
Reference in New Issue