Added toDataURL() methods to paper and element. Extracted element methods as module.
parent
28b7a7a753
commit
59e4a15cda
|
@ -31,6 +31,7 @@ module.exports = function(grunt) {
|
|||
"./src/amd-banner.js",
|
||||
"./src/mina.js",
|
||||
"./src/svg.js",
|
||||
"./src/element.js",
|
||||
"./src/matrix.js",
|
||||
"./src/attr.js",
|
||||
"./src/class.js",
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
1208
doc/reference.html
1208
doc/reference.html
File diff suppressed because it is too large
Load Diff
3
dr.json
3
dr.json
|
@ -5,6 +5,9 @@
|
|||
"files": [{
|
||||
"url": "src/svg.js",
|
||||
"link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/svg.js"
|
||||
}, {
|
||||
"url": "src/element.js",
|
||||
"link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/element.js"
|
||||
}, {
|
||||
"url": "src/matrix.js",
|
||||
"link": "https://github.com/adobe-webplatform/Snap.svg/blob/master/src/matrix.js"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Snap.svg @VERSION
|
||||
//
|
||||
// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
|
||||
// Copyright (c) 2013 – 2014 Adobe Systems Incorporated. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -0,0 +1,986 @@
|
|||
// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
|
||||
var elproto = Element.prototype,
|
||||
is = Snap.is,
|
||||
Str = String,
|
||||
unit2px = Snap._unit2px,
|
||||
$ = Snap._.$,
|
||||
make = Snap._.make,
|
||||
getSomeDefs = Snap._.getSomeDefs,
|
||||
has = "hasOwnProperty",
|
||||
wrap = Snap._.wrap;
|
||||
/*\
|
||||
* Element.getBBox
|
||||
[ method ]
|
||||
**
|
||||
* Returns the bounding box descriptor for the given element
|
||||
**
|
||||
= (object) bounding box descriptor:
|
||||
o {
|
||||
o cx: (number) x of the center,
|
||||
o cy: (number) x of the center,
|
||||
o h: (number) height,
|
||||
o height: (number) height,
|
||||
o path: (string) path command for the box,
|
||||
o r0: (number) radius of a circle that fully encloses the box,
|
||||
o r1: (number) radius of the smallest circle that can be enclosed,
|
||||
o r2: (number) radius of the largest circle that can be enclosed,
|
||||
o vb: (string) box as a viewbox command,
|
||||
o w: (number) width,
|
||||
o width: (number) width,
|
||||
o x2: (number) x of the right side,
|
||||
o x: (number) x of the left side,
|
||||
o y2: (number) y of the bottom edge,
|
||||
o y: (number) y of the top edge
|
||||
o }
|
||||
\*/
|
||||
elproto.getBBox = function (isWithoutTransform) {
|
||||
if (!Snap.Matrix || !Snap.path) {
|
||||
return this.node.getBBox();
|
||||
}
|
||||
var el = this,
|
||||
m = new Snap.Matrix;
|
||||
if (el.removed) {
|
||||
return Snap._.box();
|
||||
}
|
||||
while (el.type == "use") {
|
||||
if (!isWithoutTransform) {
|
||||
m = m.add(el.transform().localMatrix.translate(el.attr("x") || 0, el.attr("y") || 0));
|
||||
}
|
||||
if (el.original) {
|
||||
el = el.original;
|
||||
} else {
|
||||
var href = el.attr("xlink:href");
|
||||
el = el.original = el.node.ownerDocument.getElementById(href.substring(href.indexOf("#") + 1));
|
||||
}
|
||||
}
|
||||
var _ = el._,
|
||||
pathfinder = Snap.path.get[el.type] || Snap.path.get.deflt;
|
||||
try {
|
||||
if (isWithoutTransform) {
|
||||
_.bboxwt = pathfinder ? Snap.path.getBBox(el.realPath = pathfinder(el)) : Snap._.box(el.node.getBBox());
|
||||
return Snap._.box(_.bboxwt);
|
||||
} else {
|
||||
el.realPath = pathfinder(el);
|
||||
el.matrix = el.transform().localMatrix;
|
||||
_.bbox = Snap.path.getBBox(Snap.path.map(el.realPath, m.add(el.matrix)));
|
||||
return Snap._.box(_.bbox);
|
||||
}
|
||||
} catch (e) {
|
||||
// Firefox doesn’t give you bbox of hidden element
|
||||
return Snap._.box();
|
||||
}
|
||||
};
|
||||
var propString = function () {
|
||||
return this.string;
|
||||
};
|
||||
function extractTransform(el, tstr) {
|
||||
if (tstr == null) {
|
||||
var doReturn = true;
|
||||
if (el.type == "linearGradient" || el.type == "radialGradient") {
|
||||
tstr = el.node.getAttribute("gradientTransform");
|
||||
} else if (el.type == "pattern") {
|
||||
tstr = el.node.getAttribute("patternTransform");
|
||||
} else {
|
||||
tstr = el.node.getAttribute("transform");
|
||||
}
|
||||
if (!tstr) {
|
||||
return new Snap.Matrix;
|
||||
}
|
||||
tstr = Snap._.svgTransform2string(tstr);
|
||||
} else {
|
||||
if (!Snap._.rgTransform.test(tstr)) {
|
||||
tstr = Snap._.svgTransform2string(tstr);
|
||||
} else {
|
||||
tstr = Str(tstr).replace(/\.{3}|\u2026/g, el._.transform || E);
|
||||
}
|
||||
if (is(tstr, "array")) {
|
||||
tstr = Snap.path ? Snap.path.toString.call(tstr) : Str(tstr);
|
||||
}
|
||||
el._.transform = tstr;
|
||||
}
|
||||
var m = Snap._.transform2matrix(tstr, el.getBBox(1));
|
||||
if (doReturn) {
|
||||
return m;
|
||||
} else {
|
||||
el.matrix = m;
|
||||
}
|
||||
}
|
||||
/*\
|
||||
* Element.transform
|
||||
[ method ]
|
||||
**
|
||||
* Gets or sets transformation of the element
|
||||
**
|
||||
- tstr (string) transform string in Snap or SVG format
|
||||
= (Element) the current element
|
||||
* or
|
||||
= (object) transformation descriptor:
|
||||
o {
|
||||
o string (string) transform string,
|
||||
o globalMatrix (Matrix) matrix of all transformations applied to element or its parents,
|
||||
o localMatrix (Matrix) matrix of transformations applied only to the element,
|
||||
o diffMatrix (Matrix) matrix of difference between global and local transformations,
|
||||
o global (string) global transformation as string,
|
||||
o local (string) local transformation as string,
|
||||
o toString (function) returns `string` property
|
||||
o }
|
||||
\*/
|
||||
elproto.transform = function (tstr) {
|
||||
var _ = this._;
|
||||
if (tstr == null) {
|
||||
var papa = this,
|
||||
global = new Snap.Matrix(this.node.getCTM()),
|
||||
local = extractTransform(this),
|
||||
ms = [local],
|
||||
m = new Snap.Matrix,
|
||||
i,
|
||||
localString = local.toTransformString(),
|
||||
string = Str(local) == Str(this.matrix) ?
|
||||
Str(_.transform) : localString;
|
||||
while (papa.type != "svg" && (papa = papa.parent())) {
|
||||
ms.push(extractTransform(papa));
|
||||
}
|
||||
i = ms.length;
|
||||
while (i--) {
|
||||
m.add(ms[i]);
|
||||
}
|
||||
return {
|
||||
string: string,
|
||||
globalMatrix: global,
|
||||
totalMatrix: m,
|
||||
localMatrix: local,
|
||||
diffMatrix: global.clone().add(local.invert()),
|
||||
global: global.toTransformString(),
|
||||
total: m.toTransformString(),
|
||||
local: localString,
|
||||
toString: propString
|
||||
};
|
||||
}
|
||||
if (tstr instanceof Snap.Matrix) {
|
||||
this.matrix = tstr;
|
||||
} else {
|
||||
extractTransform(this, tstr);
|
||||
}
|
||||
|
||||
if (this.node) {
|
||||
if (this.type == "linearGradient" || this.type == "radialGradient") {
|
||||
$(this.node, {gradientTransform: this.matrix});
|
||||
} else if (this.type == "pattern") {
|
||||
$(this.node, {patternTransform: this.matrix});
|
||||
} else {
|
||||
$(this.node, {transform: this.matrix});
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.parent
|
||||
[ method ]
|
||||
**
|
||||
* Returns the element's parent
|
||||
**
|
||||
= (Element) the parent element
|
||||
\*/
|
||||
elproto.parent = function () {
|
||||
return wrap(this.node.parentNode);
|
||||
};
|
||||
/*\
|
||||
* Element.append
|
||||
[ method ]
|
||||
**
|
||||
* Appends the given element to current one
|
||||
**
|
||||
- el (Element|Set) element to append
|
||||
= (Element) the parent element
|
||||
\*/
|
||||
/*\
|
||||
* Element.add
|
||||
[ method ]
|
||||
**
|
||||
* See @Element.append
|
||||
\*/
|
||||
elproto.append = elproto.add = function (el) {
|
||||
if (el) {
|
||||
if (el.type == "set") {
|
||||
var it = this;
|
||||
el.forEach(function (el) {
|
||||
it.add(el);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
el = wrap(el);
|
||||
this.node.appendChild(el.node);
|
||||
el.paper = this.paper;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.appendTo
|
||||
[ method ]
|
||||
**
|
||||
* Appends the current element to the given one
|
||||
**
|
||||
- el (Element) parent element to append to
|
||||
= (Element) the child element
|
||||
\*/
|
||||
elproto.appendTo = function (el) {
|
||||
if (el) {
|
||||
el = wrap(el);
|
||||
el.append(this);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.prepend
|
||||
[ method ]
|
||||
**
|
||||
* Prepends the given element to the current one
|
||||
**
|
||||
- el (Element) element to prepend
|
||||
= (Element) the parent element
|
||||
\*/
|
||||
elproto.prepend = function (el) {
|
||||
if (el) {
|
||||
if (el.type == "set") {
|
||||
var it = this,
|
||||
first;
|
||||
el.forEach(function (el) {
|
||||
if (first) {
|
||||
first.after(el);
|
||||
} else {
|
||||
it.prepend(el);
|
||||
}
|
||||
first = el;
|
||||
});
|
||||
return this;
|
||||
}
|
||||
el = wrap(el);
|
||||
var parent = el.parent();
|
||||
this.node.insertBefore(el.node, this.node.firstChild);
|
||||
this.add && this.add();
|
||||
el.paper = this.paper;
|
||||
this.parent() && this.parent().add();
|
||||
parent && parent.add();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.prependTo
|
||||
[ method ]
|
||||
**
|
||||
* Prepends the current element to the given one
|
||||
**
|
||||
- el (Element) parent element to prepend to
|
||||
= (Element) the child element
|
||||
\*/
|
||||
elproto.prependTo = function (el) {
|
||||
el = wrap(el);
|
||||
el.prepend(this);
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.before
|
||||
[ method ]
|
||||
**
|
||||
* Inserts given element before the current one
|
||||
**
|
||||
- el (Element) element to insert
|
||||
= (Element) the parent element
|
||||
\*/
|
||||
elproto.before = function (el) {
|
||||
if (el.type == "set") {
|
||||
var it = this;
|
||||
el.forEach(function (el) {
|
||||
var parent = el.parent();
|
||||
it.node.parentNode.insertBefore(el.node, it.node);
|
||||
parent && parent.add();
|
||||
});
|
||||
this.parent().add();
|
||||
return this;
|
||||
}
|
||||
el = wrap(el);
|
||||
var parent = el.parent();
|
||||
this.node.parentNode.insertBefore(el.node, this.node);
|
||||
this.parent() && this.parent().add();
|
||||
parent && parent.add();
|
||||
el.paper = this.paper;
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.after
|
||||
[ method ]
|
||||
**
|
||||
* Inserts given element after the current one
|
||||
**
|
||||
- el (Element) element to insert
|
||||
= (Element) the parent element
|
||||
\*/
|
||||
elproto.after = function (el) {
|
||||
el = wrap(el);
|
||||
var parent = el.parent();
|
||||
if (this.node.nextSibling) {
|
||||
this.node.parentNode.insertBefore(el.node, this.node.nextSibling);
|
||||
} else {
|
||||
this.node.parentNode.appendChild(el.node);
|
||||
}
|
||||
this.parent() && this.parent().add();
|
||||
parent && parent.add();
|
||||
el.paper = this.paper;
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.insertBefore
|
||||
[ method ]
|
||||
**
|
||||
* Inserts the element after the given one
|
||||
**
|
||||
- el (Element) element next to whom insert to
|
||||
= (Element) the parent element
|
||||
\*/
|
||||
elproto.insertBefore = function (el) {
|
||||
el = wrap(el);
|
||||
var parent = this.parent();
|
||||
el.node.parentNode.insertBefore(this.node, el.node);
|
||||
this.paper = el.paper;
|
||||
parent && parent.add();
|
||||
el.parent() && el.parent().add();
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.insertAfter
|
||||
[ method ]
|
||||
**
|
||||
* Inserts the element after the given one
|
||||
**
|
||||
- el (Element) element next to whom insert to
|
||||
= (Element) the parent element
|
||||
\*/
|
||||
elproto.insertAfter = function (el) {
|
||||
el = wrap(el);
|
||||
var parent = this.parent();
|
||||
el.node.parentNode.insertBefore(this.node, el.node.nextSibling);
|
||||
this.paper = el.paper;
|
||||
parent && parent.add();
|
||||
el.parent() && el.parent().add();
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.remove
|
||||
[ method ]
|
||||
**
|
||||
* Removes element from the DOM
|
||||
= (Element) the detached element
|
||||
\*/
|
||||
elproto.remove = function () {
|
||||
var parent = this.parent();
|
||||
this.node.parentNode && this.node.parentNode.removeChild(this.node);
|
||||
delete this.paper;
|
||||
this.removed = true;
|
||||
parent && parent.add();
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.select
|
||||
[ method ]
|
||||
**
|
||||
* Gathers the nested @Element matching the given set of CSS selectors
|
||||
**
|
||||
- query (string) CSS selector
|
||||
= (Element) result of query selection
|
||||
\*/
|
||||
elproto.select = function (query) {
|
||||
query = Str(query).replace(/([^\\]):/g, "$1\\:");
|
||||
return wrap(this.node.querySelector(query));
|
||||
};
|
||||
/*\
|
||||
* Element.selectAll
|
||||
[ method ]
|
||||
**
|
||||
* Gathers nested @Element objects matching the given set of CSS selectors
|
||||
**
|
||||
- query (string) CSS selector
|
||||
= (Set|array) result of query selection
|
||||
\*/
|
||||
elproto.selectAll = function (query) {
|
||||
var nodelist = this.node.querySelectorAll(query),
|
||||
set = (Snap.set || Array)();
|
||||
for (var i = 0; i < nodelist.length; i++) {
|
||||
set.push(wrap(nodelist[i]));
|
||||
}
|
||||
return set;
|
||||
};
|
||||
/*\
|
||||
* Element.asPX
|
||||
[ method ]
|
||||
**
|
||||
* Returns given attribute of the element as a `px` value (not %, em, etc.)
|
||||
**
|
||||
- attr (string) attribute name
|
||||
- value (string) #optional attribute value
|
||||
= (Element) result of query selection
|
||||
\*/
|
||||
elproto.asPX = function (attr, value) {
|
||||
if (value == null) {
|
||||
value = this.attr(attr);
|
||||
}
|
||||
return +unit2px(this, attr, value);
|
||||
};
|
||||
// SIERRA Element.use(): I suggest adding a note about how to access the original element the returned <use> instantiates. It's a part of SVG with which ordinary web developers may be least familiar.
|
||||
/*\
|
||||
* Element.use
|
||||
[ method ]
|
||||
**
|
||||
* Creates a `<use>` element linked to the current element
|
||||
**
|
||||
= (Element) the `<use>` element
|
||||
\*/
|
||||
elproto.use = function () {
|
||||
var use,
|
||||
id = this.node.id;
|
||||
if (!id) {
|
||||
id = this.id;
|
||||
$(this.node, {
|
||||
id: id
|
||||
});
|
||||
}
|
||||
if (this.type == "linearGradient" || this.type == "radialGradient" ||
|
||||
this.type == "pattern") {
|
||||
use = make(this.type, this.node.parentNode);
|
||||
} else {
|
||||
use = make("use", this.node.parentNode);
|
||||
}
|
||||
$(use.node, {
|
||||
"xlink:href": "#" + id
|
||||
});
|
||||
use.original = this;
|
||||
return use;
|
||||
};
|
||||
function fixids(el) {
|
||||
var els = el.selectAll("*"),
|
||||
it,
|
||||
url = /^\s*url\(("|'|)(.*)\1\)\s*$/,
|
||||
ids = [],
|
||||
uses = {};
|
||||
function urltest(it, name) {
|
||||
var val = $(it.node, name);
|
||||
val = val && val.match(url);
|
||||
val = val && val[2];
|
||||
if (val && val.charAt() == "#") {
|
||||
val = val.substring(1);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (val) {
|
||||
uses[val] = (uses[val] || []).concat(function (id) {
|
||||
var attr = {};
|
||||
attr[name] = URL(id);
|
||||
$(it.node, attr);
|
||||
});
|
||||
}
|
||||
}
|
||||
function linktest(it) {
|
||||
var val = $(it.node, "xlink:href");
|
||||
if (val && val.charAt() == "#") {
|
||||
val = val.substring(1);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (val) {
|
||||
uses[val] = (uses[val] || []).concat(function (id) {
|
||||
it.attr("xlink:href", "#" + id);
|
||||
});
|
||||
}
|
||||
}
|
||||
for (var i = 0, ii = els.length; i < ii; i++) {
|
||||
it = els[i];
|
||||
urltest(it, "fill");
|
||||
urltest(it, "stroke");
|
||||
urltest(it, "filter");
|
||||
urltest(it, "mask");
|
||||
urltest(it, "clip-path");
|
||||
linktest(it);
|
||||
var oldid = $(it.node, "id");
|
||||
if (oldid) {
|
||||
$(it.node, {id: it.id});
|
||||
ids.push({
|
||||
old: oldid,
|
||||
id: it.id
|
||||
});
|
||||
}
|
||||
}
|
||||
for (i = 0, ii = ids.length; i < ii; i++) {
|
||||
var fs = uses[ids[i].old];
|
||||
if (fs) {
|
||||
for (var j = 0, jj = fs.length; j < jj; j++) {
|
||||
fs[j](ids[i].id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*\
|
||||
* Element.clone
|
||||
[ method ]
|
||||
**
|
||||
* Creates a clone of the element and inserts it after the element
|
||||
**
|
||||
= (Element) the clone
|
||||
\*/
|
||||
elproto.clone = function () {
|
||||
var clone = wrap(this.node.cloneNode(true));
|
||||
if ($(clone.node, "id")) {
|
||||
$(clone.node, {id: clone.id});
|
||||
}
|
||||
fixids(clone);
|
||||
clone.insertAfter(this);
|
||||
return clone;
|
||||
};
|
||||
/*\
|
||||
* Element.toDefs
|
||||
[ method ]
|
||||
**
|
||||
* Moves element to the shared `<defs>` area
|
||||
**
|
||||
= (Element) the element
|
||||
\*/
|
||||
elproto.toDefs = function () {
|
||||
var defs = getSomeDefs(this);
|
||||
defs.appendChild(this.node);
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.pattern
|
||||
[ method ]
|
||||
**
|
||||
* Depricated. Use @Element.toPattern instead.
|
||||
\*/
|
||||
/*\
|
||||
* Element.toPattern
|
||||
[ method ]
|
||||
**
|
||||
* Creates a `<pattern>` element from the current element
|
||||
**
|
||||
* To create a pattern you have to specify the pattern rect:
|
||||
- x (string|number)
|
||||
- y (string|number)
|
||||
- width (string|number)
|
||||
- height (string|number)
|
||||
= (Element) the `<pattern>` element
|
||||
* You can use pattern later on as an argument for `fill` attribute:
|
||||
| var p = paper.path("M10-5-10,15M15,0,0,15M0-5-20,15").attr({
|
||||
| fill: "none",
|
||||
| stroke: "#bada55",
|
||||
| strokeWidth: 5
|
||||
| }).pattern(0, 0, 10, 10),
|
||||
| c = paper.circle(200, 200, 100);
|
||||
| c.attr({
|
||||
| fill: p
|
||||
| });
|
||||
\*/
|
||||
elproto.pattern = elproto.toPattern = function (x, y, width, height) {
|
||||
var p = make("pattern", getSomeDefs(this));
|
||||
if (x == null) {
|
||||
x = this.getBBox();
|
||||
}
|
||||
if (is(x, "object") && "x" in x) {
|
||||
y = x.y;
|
||||
width = x.width;
|
||||
height = x.height;
|
||||
x = x.x;
|
||||
}
|
||||
$(p.node, {
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: height,
|
||||
patternUnits: "userSpaceOnUse",
|
||||
id: p.id,
|
||||
viewBox: [x, y, width, height].join(" ")
|
||||
});
|
||||
p.node.appendChild(this.node);
|
||||
return p;
|
||||
};
|
||||
// SIERRA Element.marker(): clarify what a reference point is. E.g., helps you offset the object from its edge such as when centering it over a path.
|
||||
// SIERRA Element.marker(): I suggest the method should accept default reference point values. Perhaps centered with (refX = width/2) and (refY = height/2)? Also, couldn't it assume the element's current _width_ and _height_? And please specify what _x_ and _y_ mean: offsets? If so, from where? Couldn't they also be assigned default values?
|
||||
/*\
|
||||
* Element.marker
|
||||
[ method ]
|
||||
**
|
||||
* Creates a `<marker>` element from the current element
|
||||
**
|
||||
* To create a marker you have to specify the bounding rect and reference point:
|
||||
- x (number)
|
||||
- y (number)
|
||||
- width (number)
|
||||
- height (number)
|
||||
- refX (number)
|
||||
- refY (number)
|
||||
= (Element) the `<marker>` element
|
||||
* You can specify the marker later as an argument for `marker-start`, `marker-end`, `marker-mid`, and `marker` attributes. The `marker` attribute places the marker at every point along the path, and `marker-mid` places them at every point except the start and end.
|
||||
\*/
|
||||
// TODO add usage for markers
|
||||
elproto.marker = function (x, y, width, height, refX, refY) {
|
||||
var p = make("marker", getSomeDefs(this));
|
||||
if (x == null) {
|
||||
x = this.getBBox();
|
||||
}
|
||||
if (is(x, "object") && "x" in x) {
|
||||
y = x.y;
|
||||
width = x.width;
|
||||
height = x.height;
|
||||
refX = x.refX || x.cx;
|
||||
refY = x.refY || x.cy;
|
||||
x = x.x;
|
||||
}
|
||||
$(p.node, {
|
||||
viewBox: [x, y, width, height].join(" "),
|
||||
markerWidth: width,
|
||||
markerHeight: height,
|
||||
orient: "auto",
|
||||
refX: refX || 0,
|
||||
refY: refY || 0,
|
||||
id: p.id
|
||||
});
|
||||
p.node.appendChild(this.node);
|
||||
return p;
|
||||
};
|
||||
// animation
|
||||
function slice(from, to, f) {
|
||||
return function (arr) {
|
||||
var res = arr.slice(from, to);
|
||||
if (res.length == 1) {
|
||||
res = res[0];
|
||||
}
|
||||
return f ? f(res) : res;
|
||||
};
|
||||
}
|
||||
var Animation = function (attr, ms, easing, callback) {
|
||||
if (typeof easing == "function" && !easing.length) {
|
||||
callback = easing;
|
||||
easing = mina.linear;
|
||||
}
|
||||
this.attr = attr;
|
||||
this.dur = ms;
|
||||
easing && (this.easing = easing);
|
||||
callback && (this.callback = callback);
|
||||
};
|
||||
Snap._.Animation = Animation;
|
||||
/*\
|
||||
* Snap.animation
|
||||
[ method ]
|
||||
**
|
||||
* Creates an animation object
|
||||
**
|
||||
- attr (object) attributes of final destination
|
||||
- duration (number) duration of the animation, in milliseconds
|
||||
- easing (function) #optional one of easing functions of @mina or custom one
|
||||
- callback (function) #optional callback function that fires when animation ends
|
||||
= (object) animation object
|
||||
\*/
|
||||
Snap.animation = function (attr, ms, easing, callback) {
|
||||
return new Animation(attr, ms, easing, callback);
|
||||
};
|
||||
/*\
|
||||
* Element.inAnim
|
||||
[ method ]
|
||||
**
|
||||
* Returns a set of animations that may be able to manipulate the current element
|
||||
**
|
||||
= (object) in format:
|
||||
o {
|
||||
o anim (object) animation object,
|
||||
o mina (object) @mina object,
|
||||
o curStatus (number) 0..1 — status of the animation: 0 — just started, 1 — just finished,
|
||||
o status (function) gets or sets the status of the animation,
|
||||
o stop (function) stops the animation
|
||||
o }
|
||||
\*/
|
||||
elproto.inAnim = function () {
|
||||
var el = this,
|
||||
res = [];
|
||||
for (var id in el.anims) if (el.anims[has](id)) {
|
||||
(function (a) {
|
||||
res.push({
|
||||
anim: new Animation(a._attrs, a.dur, a.easing, a._callback),
|
||||
mina: a,
|
||||
curStatus: a.status(),
|
||||
status: function (val) {
|
||||
return a.status(val);
|
||||
},
|
||||
stop: function () {
|
||||
a.stop();
|
||||
}
|
||||
});
|
||||
}(el.anims[id]));
|
||||
}
|
||||
return res;
|
||||
};
|
||||
/*\
|
||||
* Snap.animate
|
||||
[ method ]
|
||||
**
|
||||
* Runs generic animation of one number into another with a caring function
|
||||
**
|
||||
- from (number|array) number or array of numbers
|
||||
- to (number|array) number or array of numbers
|
||||
- setter (function) caring function that accepts one number argument
|
||||
- duration (number) duration, in milliseconds
|
||||
- easing (function) #optional easing function from @mina or custom
|
||||
- callback (function) #optional callback function to execute when animation ends
|
||||
= (object) animation object in @mina format
|
||||
o {
|
||||
o id (string) animation id, consider it read-only,
|
||||
o duration (function) gets or sets the duration of the animation,
|
||||
o easing (function) easing,
|
||||
o speed (function) gets or sets the speed of the animation,
|
||||
o status (function) gets or sets the status of the animation,
|
||||
o stop (function) stops the animation
|
||||
o }
|
||||
| var rect = Snap().rect(0, 0, 10, 10);
|
||||
| Snap.animate(0, 10, function (val) {
|
||||
| rect.attr({
|
||||
| x: val
|
||||
| });
|
||||
| }, 1000);
|
||||
| // in given context is equivalent to
|
||||
| rect.animate({x: 10}, 1000);
|
||||
\*/
|
||||
Snap.animate = function (from, to, setter, ms, easing, callback) {
|
||||
if (typeof easing == "function" && !easing.length) {
|
||||
callback = easing;
|
||||
easing = mina.linear;
|
||||
}
|
||||
var now = mina.time(),
|
||||
anim = mina(from, to, now, now + ms, mina.time, setter, easing);
|
||||
callback && eve.once("mina.finish." + anim.id, callback);
|
||||
return anim;
|
||||
};
|
||||
/*\
|
||||
* Element.stop
|
||||
[ method ]
|
||||
**
|
||||
* Stops all the animations for the current element
|
||||
**
|
||||
= (Element) the current element
|
||||
\*/
|
||||
elproto.stop = function () {
|
||||
var anims = this.inAnim();
|
||||
for (var i = 0, ii = anims.length; i < ii; i++) {
|
||||
anims[i].stop();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.animate
|
||||
[ method ]
|
||||
**
|
||||
* Animates the given attributes of the element
|
||||
**
|
||||
- attrs (object) key-value pairs of destination attributes
|
||||
- duration (number) duration of the animation in milliseconds
|
||||
- easing (function) #optional easing function from @mina or custom
|
||||
- callback (function) #optional callback function that executes when the animation ends
|
||||
= (Element) the current element
|
||||
\*/
|
||||
elproto.animate = function (attrs, ms, easing, callback) {
|
||||
if (typeof easing == "function" && !easing.length) {
|
||||
callback = easing;
|
||||
easing = mina.linear;
|
||||
}
|
||||
if (attrs instanceof Animation) {
|
||||
callback = attrs.callback;
|
||||
easing = attrs.easing;
|
||||
ms = easing.dur;
|
||||
attrs = attrs.attr;
|
||||
}
|
||||
var fkeys = [], tkeys = [], keys = {}, from, to, f, eq,
|
||||
el = this;
|
||||
for (var key in attrs) if (attrs[has](key)) {
|
||||
if (el.equal) {
|
||||
eq = el.equal(key, Str(attrs[key]));
|
||||
from = eq.from;
|
||||
to = eq.to;
|
||||
f = eq.f;
|
||||
} else {
|
||||
from = +el.attr(key);
|
||||
to = +attrs[key];
|
||||
}
|
||||
var len = is(from, "array") ? from.length : 1;
|
||||
keys[key] = slice(fkeys.length, fkeys.length + len, f);
|
||||
fkeys = fkeys.concat(from);
|
||||
tkeys = tkeys.concat(to);
|
||||
}
|
||||
var now = mina.time(),
|
||||
anim = mina(fkeys, tkeys, now, now + ms, mina.time, function (val) {
|
||||
var attr = {};
|
||||
for (var key in keys) if (keys[has](key)) {
|
||||
attr[key] = keys[key](val);
|
||||
}
|
||||
el.attr(attr);
|
||||
}, easing);
|
||||
el.anims[anim.id] = anim;
|
||||
anim._attrs = attrs;
|
||||
anim._callback = callback;
|
||||
eve("snap.animcreated." + el.id, anim);
|
||||
eve.once("mina.finish." + anim.id, function () {
|
||||
delete el.anims[anim.id];
|
||||
callback && callback.call(el);
|
||||
});
|
||||
eve.once("mina.stop." + anim.id, function () {
|
||||
delete el.anims[anim.id];
|
||||
});
|
||||
return el;
|
||||
};
|
||||
var eldata = {};
|
||||
/*\
|
||||
* Element.data
|
||||
[ method ]
|
||||
**
|
||||
* Adds or retrieves given value associated with given key. (Don’t confuse
|
||||
* with `data-` attributes)
|
||||
*
|
||||
* See also @Element.removeData
|
||||
- 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 == 0){
|
||||
eve("snap.data.get." + this.id, this, data, null);
|
||||
return data;
|
||||
}
|
||||
if (arguments.length == 1) {
|
||||
if (Snap.is(key, "object")) {
|
||||
for (var i in key) if (key[has](i)) {
|
||||
this.data(i, key[i]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
eve("snap.data.get." + this.id, this, data[key], key);
|
||||
return data[key];
|
||||
}
|
||||
data[key] = value;
|
||||
eve("snap.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.
|
||||
- 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.outerSVG
|
||||
[ method ]
|
||||
**
|
||||
* Returns SVG code for the element, equivalent to HTML's `outerHTML`.
|
||||
*
|
||||
* See also @Element.innerSVG
|
||||
= (string) SVG code for the element
|
||||
\*/
|
||||
/*\
|
||||
* Element.toString
|
||||
[ method ]
|
||||
**
|
||||
* See @Element.outerSVG
|
||||
\*/
|
||||
elproto.outerSVG = elproto.toString = toString(1);
|
||||
/*\
|
||||
* Element.innerSVG
|
||||
[ method ]
|
||||
**
|
||||
* Returns SVG code for the element's contents, equivalent to HTML's `innerHTML`
|
||||
= (string) SVG code for the element
|
||||
\*/
|
||||
elproto.innerSVG = toString();
|
||||
function toString(type) {
|
||||
return function () {
|
||||
var res = type ? "<" + this.type : "",
|
||||
attr = this.node.attributes,
|
||||
chld = this.node.childNodes;
|
||||
if (type) {
|
||||
for (var i = 0, ii = attr.length; i < ii; i++) {
|
||||
res += " " + attr[i].name + '="' +
|
||||
attr[i].value.replace(/"/g, '\\"') + '"';
|
||||
}
|
||||
}
|
||||
if (chld.length) {
|
||||
type && (res += ">");
|
||||
for (i = 0, ii = chld.length; i < ii; i++) {
|
||||
if (chld[i].nodeType == 3) {
|
||||
res += chld[i].nodeValue;
|
||||
} else if (chld[i].nodeType == 1) {
|
||||
res += wrap(chld[i]).toString();
|
||||
}
|
||||
}
|
||||
type && (res += "</" + this.type + ">");
|
||||
} else {
|
||||
type && (res += "/>");
|
||||
}
|
||||
return res;
|
||||
};
|
||||
}
|
||||
elproto.toDataURL = function () {
|
||||
if (window && window.btoa) {
|
||||
var bb = this.getBBox(),
|
||||
svg = Snap.format('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="{width}" height="{height}" viewBox="{x} {y} {width} {height}">{contents}</svg>', {
|
||||
x: +bb.x.toFixed(3),
|
||||
y: +bb.y.toFixed(3),
|
||||
width: +bb.width.toFixed(3),
|
||||
height: +bb.height.toFixed(3),
|
||||
contents: this.outerSVG()
|
||||
});
|
||||
return "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(svg)));
|
||||
}
|
||||
};
|
||||
/*\
|
||||
* Fragment.select
|
||||
[ method ]
|
||||
**
|
||||
* See @Element.select
|
||||
\*/
|
||||
Fragment.prototype.select = elproto.select;
|
||||
/*\
|
||||
* Fragment.selectAll
|
||||
[ method ]
|
||||
**
|
||||
* See @Element.selectAll
|
||||
\*/
|
||||
Fragment.prototype.selectAll = elproto.selectAll;
|
||||
});
|
|
@ -18,7 +18,6 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
|
|||
Str = String,
|
||||
$ = Snap._.$;
|
||||
Snap.filter = {};
|
||||
// SIERRA Paper.filter(): I don't understand the note. Does that mean an HTML should dedicate a separate SVG region for a filter definition? What's the advantage over a DEFS?
|
||||
/*\
|
||||
* Paper.filter
|
||||
[ method ]
|
||||
|
|
12
src/paper.js
12
src/paper.js
|
@ -685,6 +685,18 @@ Snap.plugin(function (Snap, Element, Paper, glob, Fragment) {
|
|||
f.removeChild(f.firstChild);
|
||||
return res;
|
||||
};
|
||||
/*\
|
||||
* Paper.toDataURL
|
||||
[ method ]
|
||||
**
|
||||
* Returns SVG code for the @Paper as Data URI string.
|
||||
= (string) Data URI string
|
||||
\*/
|
||||
proto.toDataURL = function () {
|
||||
if (window && window.btoa) {
|
||||
return "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(this)));
|
||||
}
|
||||
};
|
||||
/*\
|
||||
* Paper.clear
|
||||
[ method ]
|
||||
|
|
|
@ -303,6 +303,7 @@ Snap.plugin(function (Snap, Element, Paper, glob) {
|
|||
};
|
||||
setproto.type = "set";
|
||||
// export
|
||||
Snap.Set = Set;
|
||||
Snap.set = function () {
|
||||
var set = new Set;
|
||||
if (arguments.length) {
|
||||
|
|
955
src/svg.js
955
src/svg.js
|
@ -942,38 +942,6 @@ function transform2matrix(tstr, bbox) {
|
|||
return m;
|
||||
}
|
||||
Snap._.transform2matrix = transform2matrix;
|
||||
function extractTransform(el, tstr) {
|
||||
if (tstr == null) {
|
||||
var doReturn = true;
|
||||
if (el.type == "linearGradient" || el.type == "radialGradient") {
|
||||
tstr = el.node.getAttribute("gradientTransform");
|
||||
} else if (el.type == "pattern") {
|
||||
tstr = el.node.getAttribute("patternTransform");
|
||||
} else {
|
||||
tstr = el.node.getAttribute("transform");
|
||||
}
|
||||
if (!tstr) {
|
||||
return new Snap.Matrix;
|
||||
}
|
||||
tstr = svgTransform2string(tstr);
|
||||
} else {
|
||||
if (!Snap._.rgTransform.test(tstr)) {
|
||||
tstr = svgTransform2string(tstr);
|
||||
} else {
|
||||
tstr = Str(tstr).replace(/\.{3}|\u2026/g, el._.transform || E);
|
||||
}
|
||||
if (is(tstr, "array")) {
|
||||
tstr = Snap.path ? Snap.path.toString.call(tstr) : Str(tstr);
|
||||
}
|
||||
el._.transform = tstr;
|
||||
}
|
||||
var m = transform2matrix(tstr, el.getBBox(1));
|
||||
if (doReturn) {
|
||||
return m;
|
||||
} else {
|
||||
el.matrix = m;
|
||||
}
|
||||
}
|
||||
Snap._unit2px = unit2px;
|
||||
var contains = glob.doc.contains || glob.doc.compareDocumentPosition ?
|
||||
function (a, b) {
|
||||
|
@ -1214,8 +1182,7 @@ function Element(el) {
|
|||
}
|
||||
}
|
||||
}
|
||||
(function (elproto) {
|
||||
/*\
|
||||
/*\
|
||||
* Element.attr
|
||||
[ method ]
|
||||
**
|
||||
|
@ -1240,7 +1207,7 @@ function Element(el) {
|
|||
* (`+`, `-`, `*` and `/`) could be used. Optionally you can use units for `+`
|
||||
* and `-`: `"+=2em"`.
|
||||
\*/
|
||||
elproto.attr = function (params, value) {
|
||||
Element.prototype.attr = function (params, value) {
|
||||
var el = this,
|
||||
node = el.node;
|
||||
if (!params) {
|
||||
|
@ -1262,910 +1229,6 @@ function Element(el) {
|
|||
}
|
||||
return el;
|
||||
};
|
||||
/*\
|
||||
* Element.getBBox
|
||||
[ method ]
|
||||
**
|
||||
* Returns the bounding box descriptor for the given element
|
||||
**
|
||||
= (object) bounding box descriptor:
|
||||
o {
|
||||
o cx: (number) x of the center,
|
||||
o cy: (number) x of the center,
|
||||
o h: (number) height,
|
||||
o height: (number) height,
|
||||
o path: (string) path command for the box,
|
||||
o r0: (number) radius of a circle that fully encloses the box,
|
||||
o r1: (number) radius of the smallest circle that can be enclosed,
|
||||
o r2: (number) radius of the largest circle that can be enclosed,
|
||||
o vb: (string) box as a viewbox command,
|
||||
o w: (number) width,
|
||||
o width: (number) width,
|
||||
o x2: (number) x of the right side,
|
||||
o x: (number) x of the left side,
|
||||
o y2: (number) y of the bottom edge,
|
||||
o y: (number) y of the top edge
|
||||
o }
|
||||
\*/
|
||||
elproto.getBBox = function (isWithoutTransform) {
|
||||
if (!Snap.Matrix || !Snap.path) {
|
||||
return this.node.getBBox();
|
||||
}
|
||||
var el = this,
|
||||
m = new Snap.Matrix;
|
||||
if (el.removed) {
|
||||
return Snap._.box();
|
||||
}
|
||||
while (el.type == "use") {
|
||||
if (!isWithoutTransform) {
|
||||
m = m.add(el.transform().localMatrix.translate(el.attr("x") || 0, el.attr("y") || 0));
|
||||
}
|
||||
if (el.original) {
|
||||
el = el.original;
|
||||
} else {
|
||||
var href = el.attr("xlink:href");
|
||||
el = el.original = el.node.ownerDocument.getElementById(href.substring(href.indexOf("#") + 1));
|
||||
}
|
||||
}
|
||||
var _ = el._,
|
||||
pathfinder = Snap.path.get[el.type] || Snap.path.get.deflt;
|
||||
try {
|
||||
if (isWithoutTransform) {
|
||||
_.bboxwt = pathfinder ? Snap.path.getBBox(el.realPath = pathfinder(el)) : Snap._.box(el.node.getBBox());
|
||||
return Snap._.box(_.bboxwt);
|
||||
} else {
|
||||
el.realPath = pathfinder(el);
|
||||
el.matrix = el.transform().localMatrix;
|
||||
_.bbox = Snap.path.getBBox(Snap.path.map(el.realPath, m.add(el.matrix)));
|
||||
return Snap._.box(_.bbox);
|
||||
}
|
||||
} catch (e) {
|
||||
// Firefox doesn’t give you bbox of hidden element
|
||||
return Snap._.box();
|
||||
}
|
||||
};
|
||||
var propString = function () {
|
||||
return this.string;
|
||||
};
|
||||
/*\
|
||||
* Element.transform
|
||||
[ method ]
|
||||
**
|
||||
* Gets or sets transformation of the element
|
||||
**
|
||||
- tstr (string) transform string in Snap or SVG format
|
||||
= (Element) the current element
|
||||
* or
|
||||
= (object) transformation descriptor:
|
||||
o {
|
||||
o string (string) transform string,
|
||||
o globalMatrix (Matrix) matrix of all transformations applied to element or its parents,
|
||||
o localMatrix (Matrix) matrix of transformations applied only to the element,
|
||||
o diffMatrix (Matrix) matrix of difference between global and local transformations,
|
||||
o global (string) global transformation as string,
|
||||
o local (string) local transformation as string,
|
||||
o toString (function) returns `string` property
|
||||
o }
|
||||
\*/
|
||||
elproto.transform = function (tstr) {
|
||||
var _ = this._;
|
||||
if (tstr == null) {
|
||||
var papa = this,
|
||||
global = new Snap.Matrix(this.node.getCTM()),
|
||||
local = extractTransform(this),
|
||||
ms = [local],
|
||||
m = new Snap.Matrix,
|
||||
i,
|
||||
localString = local.toTransformString(),
|
||||
string = Str(local) == Str(this.matrix) ?
|
||||
Str(_.transform) : localString;
|
||||
while (papa.type != "svg" && (papa = papa.parent())) {
|
||||
ms.push(extractTransform(papa));
|
||||
}
|
||||
i = ms.length;
|
||||
while (i--) {
|
||||
m.add(ms[i]);
|
||||
}
|
||||
return {
|
||||
string: string,
|
||||
globalMatrix: global,
|
||||
totalMatrix: m,
|
||||
localMatrix: local,
|
||||
diffMatrix: global.clone().add(local.invert()),
|
||||
global: global.toTransformString(),
|
||||
total: m.toTransformString(),
|
||||
local: localString,
|
||||
toString: propString
|
||||
};
|
||||
}
|
||||
if (tstr instanceof Snap.Matrix) {
|
||||
this.matrix = tstr;
|
||||
} else {
|
||||
extractTransform(this, tstr);
|
||||
}
|
||||
|
||||
if (this.node) {
|
||||
if (this.type == "linearGradient" || this.type == "radialGradient") {
|
||||
$(this.node, {gradientTransform: this.matrix});
|
||||
} else if (this.type == "pattern") {
|
||||
$(this.node, {patternTransform: this.matrix});
|
||||
} else {
|
||||
$(this.node, {transform: this.matrix});
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.parent
|
||||
[ method ]
|
||||
**
|
||||
* Returns the element's parent
|
||||
**
|
||||
= (Element) the parent element
|
||||
\*/
|
||||
elproto.parent = function () {
|
||||
return wrap(this.node.parentNode);
|
||||
};
|
||||
/*\
|
||||
* Element.append
|
||||
[ method ]
|
||||
**
|
||||
* Appends the given element to current one
|
||||
**
|
||||
- el (Element|Set) element to append
|
||||
= (Element) the parent element
|
||||
\*/
|
||||
/*\
|
||||
* Element.add
|
||||
[ method ]
|
||||
**
|
||||
* See @Element.append
|
||||
\*/
|
||||
elproto.append = elproto.add = function (el) {
|
||||
if (el) {
|
||||
if (el.type == "set") {
|
||||
var it = this;
|
||||
el.forEach(function (el) {
|
||||
it.add(el);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
el = wrap(el);
|
||||
this.node.appendChild(el.node);
|
||||
el.paper = this.paper;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.appendTo
|
||||
[ method ]
|
||||
**
|
||||
* Appends the current element to the given one
|
||||
**
|
||||
- el (Element) parent element to append to
|
||||
= (Element) the child element
|
||||
\*/
|
||||
elproto.appendTo = function (el) {
|
||||
if (el) {
|
||||
el = wrap(el);
|
||||
el.append(this);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.prepend
|
||||
[ method ]
|
||||
**
|
||||
* Prepends the given element to the current one
|
||||
**
|
||||
- el (Element) element to prepend
|
||||
= (Element) the parent element
|
||||
\*/
|
||||
elproto.prepend = function (el) {
|
||||
if (el) {
|
||||
if (el.type == "set") {
|
||||
var it = this,
|
||||
first;
|
||||
el.forEach(function (el) {
|
||||
if (first) {
|
||||
first.after(el);
|
||||
} else {
|
||||
it.prepend(el);
|
||||
}
|
||||
first = el;
|
||||
});
|
||||
return this;
|
||||
}
|
||||
el = wrap(el);
|
||||
var parent = el.parent();
|
||||
this.node.insertBefore(el.node, this.node.firstChild);
|
||||
this.add && this.add();
|
||||
el.paper = this.paper;
|
||||
this.parent() && this.parent().add();
|
||||
parent && parent.add();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.prependTo
|
||||
[ method ]
|
||||
**
|
||||
* Prepends the current element to the given one
|
||||
**
|
||||
- el (Element) parent element to prepend to
|
||||
= (Element) the child element
|
||||
\*/
|
||||
elproto.prependTo = function (el) {
|
||||
el = wrap(el);
|
||||
el.prepend(this);
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.before
|
||||
[ method ]
|
||||
**
|
||||
* Inserts given element before the current one
|
||||
**
|
||||
- el (Element) element to insert
|
||||
= (Element) the parent element
|
||||
\*/
|
||||
elproto.before = function (el) {
|
||||
if (el.type == "set") {
|
||||
var it = this;
|
||||
el.forEach(function (el) {
|
||||
var parent = el.parent();
|
||||
it.node.parentNode.insertBefore(el.node, it.node);
|
||||
parent && parent.add();
|
||||
});
|
||||
this.parent().add();
|
||||
return this;
|
||||
}
|
||||
el = wrap(el);
|
||||
var parent = el.parent();
|
||||
this.node.parentNode.insertBefore(el.node, this.node);
|
||||
this.parent() && this.parent().add();
|
||||
parent && parent.add();
|
||||
el.paper = this.paper;
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.after
|
||||
[ method ]
|
||||
**
|
||||
* Inserts given element after the current one
|
||||
**
|
||||
- el (Element) element to insert
|
||||
= (Element) the parent element
|
||||
\*/
|
||||
elproto.after = function (el) {
|
||||
el = wrap(el);
|
||||
var parent = el.parent();
|
||||
if (this.node.nextSibling) {
|
||||
this.node.parentNode.insertBefore(el.node, this.node.nextSibling);
|
||||
} else {
|
||||
this.node.parentNode.appendChild(el.node);
|
||||
}
|
||||
this.parent() && this.parent().add();
|
||||
parent && parent.add();
|
||||
el.paper = this.paper;
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.insertBefore
|
||||
[ method ]
|
||||
**
|
||||
* Inserts the element after the given one
|
||||
**
|
||||
- el (Element) element next to whom insert to
|
||||
= (Element) the parent element
|
||||
\*/
|
||||
elproto.insertBefore = function (el) {
|
||||
el = wrap(el);
|
||||
var parent = this.parent();
|
||||
el.node.parentNode.insertBefore(this.node, el.node);
|
||||
this.paper = el.paper;
|
||||
parent && parent.add();
|
||||
el.parent() && el.parent().add();
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.insertAfter
|
||||
[ method ]
|
||||
**
|
||||
* Inserts the element after the given one
|
||||
**
|
||||
- el (Element) element next to whom insert to
|
||||
= (Element) the parent element
|
||||
\*/
|
||||
elproto.insertAfter = function (el) {
|
||||
el = wrap(el);
|
||||
var parent = this.parent();
|
||||
el.node.parentNode.insertBefore(this.node, el.node.nextSibling);
|
||||
this.paper = el.paper;
|
||||
parent && parent.add();
|
||||
el.parent() && el.parent().add();
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.remove
|
||||
[ method ]
|
||||
**
|
||||
* Removes element from the DOM
|
||||
= (Element) the detached element
|
||||
\*/
|
||||
elproto.remove = function () {
|
||||
var parent = this.parent();
|
||||
this.node.parentNode && this.node.parentNode.removeChild(this.node);
|
||||
delete this.paper;
|
||||
this.removed = true;
|
||||
parent && parent.add();
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.select
|
||||
[ method ]
|
||||
**
|
||||
* Gathers the nested @Element matching the given set of CSS selectors
|
||||
**
|
||||
- query (string) CSS selector
|
||||
= (Element) result of query selection
|
||||
\*/
|
||||
elproto.select = function (query) {
|
||||
query = Str(query).replace(/([^\\]):/g, "$1\\:");
|
||||
return wrap(this.node.querySelector(query));
|
||||
};
|
||||
/*\
|
||||
* Element.selectAll
|
||||
[ method ]
|
||||
**
|
||||
* Gathers nested @Element objects matching the given set of CSS selectors
|
||||
**
|
||||
- query (string) CSS selector
|
||||
= (Set|array) result of query selection
|
||||
\*/
|
||||
elproto.selectAll = function (query) {
|
||||
var nodelist = this.node.querySelectorAll(query),
|
||||
set = (Snap.set || Array)();
|
||||
for (var i = 0; i < nodelist.length; i++) {
|
||||
set.push(wrap(nodelist[i]));
|
||||
}
|
||||
return set;
|
||||
};
|
||||
/*\
|
||||
* Element.asPX
|
||||
[ method ]
|
||||
**
|
||||
* Returns given attribute of the element as a `px` value (not %, em, etc.)
|
||||
**
|
||||
- attr (string) attribute name
|
||||
- value (string) #optional attribute value
|
||||
= (Element) result of query selection
|
||||
\*/
|
||||
elproto.asPX = function (attr, value) {
|
||||
if (value == null) {
|
||||
value = this.attr(attr);
|
||||
}
|
||||
return +unit2px(this, attr, value);
|
||||
};
|
||||
// SIERRA Element.use(): I suggest adding a note about how to access the original element the returned <use> instantiates. It's a part of SVG with which ordinary web developers may be least familiar.
|
||||
/*\
|
||||
* Element.use
|
||||
[ method ]
|
||||
**
|
||||
* Creates a `<use>` element linked to the current element
|
||||
**
|
||||
= (Element) the `<use>` element
|
||||
\*/
|
||||
elproto.use = function () {
|
||||
var use,
|
||||
id = this.node.id;
|
||||
if (!id) {
|
||||
id = this.id;
|
||||
$(this.node, {
|
||||
id: id
|
||||
});
|
||||
}
|
||||
if (this.type == "linearGradient" || this.type == "radialGradient" ||
|
||||
this.type == "pattern") {
|
||||
use = make(this.type, this.node.parentNode);
|
||||
} else {
|
||||
use = make("use", this.node.parentNode);
|
||||
}
|
||||
$(use.node, {
|
||||
"xlink:href": "#" + id
|
||||
});
|
||||
use.original = this;
|
||||
return use;
|
||||
};
|
||||
function fixids(el) {
|
||||
var els = el.selectAll("*"),
|
||||
it,
|
||||
url = /^\s*url\(("|'|)(.*)\1\)\s*$/,
|
||||
ids = [],
|
||||
uses = {};
|
||||
function urltest(it, name) {
|
||||
var val = $(it.node, name);
|
||||
val = val && val.match(url);
|
||||
val = val && val[2];
|
||||
if (val && val.charAt() == "#") {
|
||||
val = val.substring(1);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (val) {
|
||||
uses[val] = (uses[val] || []).concat(function (id) {
|
||||
var attr = {};
|
||||
attr[name] = URL(id);
|
||||
$(it.node, attr);
|
||||
});
|
||||
}
|
||||
}
|
||||
function linktest(it) {
|
||||
var val = $(it.node, "xlink:href");
|
||||
if (val && val.charAt() == "#") {
|
||||
val = val.substring(1);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (val) {
|
||||
uses[val] = (uses[val] || []).concat(function (id) {
|
||||
it.attr("xlink:href", "#" + id);
|
||||
});
|
||||
}
|
||||
}
|
||||
for (var i = 0, ii = els.length; i < ii; i++) {
|
||||
it = els[i];
|
||||
urltest(it, "fill");
|
||||
urltest(it, "stroke");
|
||||
urltest(it, "filter");
|
||||
urltest(it, "mask");
|
||||
urltest(it, "clip-path");
|
||||
linktest(it);
|
||||
var oldid = $(it.node, "id");
|
||||
if (oldid) {
|
||||
$(it.node, {id: it.id});
|
||||
ids.push({
|
||||
old: oldid,
|
||||
id: it.id
|
||||
});
|
||||
}
|
||||
}
|
||||
for (i = 0, ii = ids.length; i < ii; i++) {
|
||||
var fs = uses[ids[i].old];
|
||||
if (fs) {
|
||||
for (var j = 0, jj = fs.length; j < jj; j++) {
|
||||
fs[j](ids[i].id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*\
|
||||
* Element.clone
|
||||
[ method ]
|
||||
**
|
||||
* Creates a clone of the element and inserts it after the element
|
||||
**
|
||||
= (Element) the clone
|
||||
\*/
|
||||
elproto.clone = function () {
|
||||
var clone = wrap(this.node.cloneNode(true));
|
||||
if ($(clone.node, "id")) {
|
||||
$(clone.node, {id: clone.id});
|
||||
}
|
||||
fixids(clone);
|
||||
clone.insertAfter(this);
|
||||
return clone;
|
||||
};
|
||||
/*\
|
||||
* Element.toDefs
|
||||
[ method ]
|
||||
**
|
||||
* Moves element to the shared `<defs>` area
|
||||
**
|
||||
= (Element) the element
|
||||
\*/
|
||||
elproto.toDefs = function () {
|
||||
var defs = getSomeDefs(this);
|
||||
defs.appendChild(this.node);
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.pattern
|
||||
[ method ]
|
||||
**
|
||||
* Depricated. Use @Element.toPattern instead.
|
||||
\*/
|
||||
/*\
|
||||
* Element.toPattern
|
||||
[ method ]
|
||||
**
|
||||
* Creates a `<pattern>` element from the current element
|
||||
**
|
||||
* To create a pattern you have to specify the pattern rect:
|
||||
- x (string|number)
|
||||
- y (string|number)
|
||||
- width (string|number)
|
||||
- height (string|number)
|
||||
= (Element) the `<pattern>` element
|
||||
* You can use pattern later on as an argument for `fill` attribute:
|
||||
| var p = paper.path("M10-5-10,15M15,0,0,15M0-5-20,15").attr({
|
||||
| fill: "none",
|
||||
| stroke: "#bada55",
|
||||
| strokeWidth: 5
|
||||
| }).pattern(0, 0, 10, 10),
|
||||
| c = paper.circle(200, 200, 100);
|
||||
| c.attr({
|
||||
| fill: p
|
||||
| });
|
||||
\*/
|
||||
elproto.pattern = elproto.toPattern = function (x, y, width, height) {
|
||||
var p = make("pattern", getSomeDefs(this));
|
||||
if (x == null) {
|
||||
x = this.getBBox();
|
||||
}
|
||||
if (is(x, "object") && "x" in x) {
|
||||
y = x.y;
|
||||
width = x.width;
|
||||
height = x.height;
|
||||
x = x.x;
|
||||
}
|
||||
$(p.node, {
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: height,
|
||||
patternUnits: "userSpaceOnUse",
|
||||
id: p.id,
|
||||
viewBox: [x, y, width, height].join(" ")
|
||||
});
|
||||
p.node.appendChild(this.node);
|
||||
return p;
|
||||
};
|
||||
// SIERRA Element.marker(): clarify what a reference point is. E.g., helps you offset the object from its edge such as when centering it over a path.
|
||||
// SIERRA Element.marker(): I suggest the method should accept default reference point values. Perhaps centered with (refX = width/2) and (refY = height/2)? Also, couldn't it assume the element's current _width_ and _height_? And please specify what _x_ and _y_ mean: offsets? If so, from where? Couldn't they also be assigned default values?
|
||||
/*\
|
||||
* Element.marker
|
||||
[ method ]
|
||||
**
|
||||
* Creates a `<marker>` element from the current element
|
||||
**
|
||||
* To create a marker you have to specify the bounding rect and reference point:
|
||||
- x (number)
|
||||
- y (number)
|
||||
- width (number)
|
||||
- height (number)
|
||||
- refX (number)
|
||||
- refY (number)
|
||||
= (Element) the `<marker>` element
|
||||
* You can specify the marker later as an argument for `marker-start`, `marker-end`, `marker-mid`, and `marker` attributes. The `marker` attribute places the marker at every point along the path, and `marker-mid` places them at every point except the start and end.
|
||||
\*/
|
||||
// TODO add usage for markers
|
||||
elproto.marker = function (x, y, width, height, refX, refY) {
|
||||
var p = make("marker", getSomeDefs(this));
|
||||
if (x == null) {
|
||||
x = this.getBBox();
|
||||
}
|
||||
if (is(x, "object") && "x" in x) {
|
||||
y = x.y;
|
||||
width = x.width;
|
||||
height = x.height;
|
||||
refX = x.refX || x.cx;
|
||||
refY = x.refY || x.cy;
|
||||
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
|
||||
function slice(from, to, f) {
|
||||
return function (arr) {
|
||||
var res = arr.slice(from, to);
|
||||
if (res.length == 1) {
|
||||
res = res[0];
|
||||
}
|
||||
return f ? f(res) : res;
|
||||
};
|
||||
}
|
||||
var Animation = function (attr, ms, easing, callback) {
|
||||
if (typeof easing == "function" && !easing.length) {
|
||||
callback = easing;
|
||||
easing = mina.linear;
|
||||
}
|
||||
this.attr = attr;
|
||||
this.dur = ms;
|
||||
easing && (this.easing = easing);
|
||||
callback && (this.callback = callback);
|
||||
};
|
||||
Snap._.Animation = Animation;
|
||||
/*\
|
||||
* Snap.animation
|
||||
[ method ]
|
||||
**
|
||||
* Creates an animation object
|
||||
**
|
||||
- attr (object) attributes of final destination
|
||||
- duration (number) duration of the animation, in milliseconds
|
||||
- easing (function) #optional one of easing functions of @mina or custom one
|
||||
- callback (function) #optional callback function that fires when animation ends
|
||||
= (object) animation object
|
||||
\*/
|
||||
Snap.animation = function (attr, ms, easing, callback) {
|
||||
return new Animation(attr, ms, easing, callback);
|
||||
};
|
||||
/*\
|
||||
* Element.inAnim
|
||||
[ method ]
|
||||
**
|
||||
* Returns a set of animations that may be able to manipulate the current element
|
||||
**
|
||||
= (object) in format:
|
||||
o {
|
||||
o anim (object) animation object,
|
||||
o mina (object) @mina object,
|
||||
o curStatus (number) 0..1 — status of the animation: 0 — just started, 1 — just finished,
|
||||
o status (function) gets or sets the status of the animation,
|
||||
o stop (function) stops the animation
|
||||
o }
|
||||
\*/
|
||||
elproto.inAnim = function () {
|
||||
var el = this,
|
||||
res = [];
|
||||
for (var id in el.anims) if (el.anims[has](id)) {
|
||||
(function (a) {
|
||||
res.push({
|
||||
anim: new Animation(a._attrs, a.dur, a.easing, a._callback),
|
||||
mina: a,
|
||||
curStatus: a.status(),
|
||||
status: function (val) {
|
||||
return a.status(val);
|
||||
},
|
||||
stop: function () {
|
||||
a.stop();
|
||||
}
|
||||
});
|
||||
}(el.anims[id]));
|
||||
}
|
||||
return res;
|
||||
};
|
||||
/*\
|
||||
* Snap.animate
|
||||
[ method ]
|
||||
**
|
||||
* Runs generic animation of one number into another with a caring function
|
||||
**
|
||||
- from (number|array) number or array of numbers
|
||||
- to (number|array) number or array of numbers
|
||||
- setter (function) caring function that accepts one number argument
|
||||
- duration (number) duration, in milliseconds
|
||||
- easing (function) #optional easing function from @mina or custom
|
||||
- callback (function) #optional callback function to execute when animation ends
|
||||
= (object) animation object in @mina format
|
||||
o {
|
||||
o id (string) animation id, consider it read-only,
|
||||
o duration (function) gets or sets the duration of the animation,
|
||||
o easing (function) easing,
|
||||
o speed (function) gets or sets the speed of the animation,
|
||||
o status (function) gets or sets the status of the animation,
|
||||
o stop (function) stops the animation
|
||||
o }
|
||||
| var rect = Snap().rect(0, 0, 10, 10);
|
||||
| Snap.animate(0, 10, function (val) {
|
||||
| rect.attr({
|
||||
| x: val
|
||||
| });
|
||||
| }, 1000);
|
||||
| // in given context is equivalent to
|
||||
| rect.animate({x: 10}, 1000);
|
||||
\*/
|
||||
Snap.animate = function (from, to, setter, ms, easing, callback) {
|
||||
if (typeof easing == "function" && !easing.length) {
|
||||
callback = easing;
|
||||
easing = mina.linear;
|
||||
}
|
||||
var now = mina.time(),
|
||||
anim = mina(from, to, now, now + ms, mina.time, setter, easing);
|
||||
callback && eve.once("mina.finish." + anim.id, callback);
|
||||
return anim;
|
||||
};
|
||||
/*\
|
||||
* Element.stop
|
||||
[ method ]
|
||||
**
|
||||
* Stops all the animations for the current element
|
||||
**
|
||||
= (Element) the current element
|
||||
\*/
|
||||
elproto.stop = function () {
|
||||
var anims = this.inAnim();
|
||||
for (var i = 0, ii = anims.length; i < ii; i++) {
|
||||
anims[i].stop();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/*\
|
||||
* Element.animate
|
||||
[ method ]
|
||||
**
|
||||
* Animates the given attributes of the element
|
||||
**
|
||||
- attrs (object) key-value pairs of destination attributes
|
||||
- duration (number) duration of the animation in milliseconds
|
||||
- easing (function) #optional easing function from @mina or custom
|
||||
- callback (function) #optional callback function that executes when the animation ends
|
||||
= (Element) the current element
|
||||
\*/
|
||||
elproto.animate = function (attrs, ms, easing, callback) {
|
||||
if (typeof easing == "function" && !easing.length) {
|
||||
callback = easing;
|
||||
easing = mina.linear;
|
||||
}
|
||||
if (attrs instanceof Animation) {
|
||||
callback = attrs.callback;
|
||||
easing = attrs.easing;
|
||||
ms = easing.dur;
|
||||
attrs = attrs.attr;
|
||||
}
|
||||
var fkeys = [], tkeys = [], keys = {}, from, to, f, eq,
|
||||
el = this;
|
||||
for (var key in attrs) if (attrs[has](key)) {
|
||||
if (el.equal) {
|
||||
eq = el.equal(key, Str(attrs[key]));
|
||||
from = eq.from;
|
||||
to = eq.to;
|
||||
f = eq.f;
|
||||
} else {
|
||||
from = +el.attr(key);
|
||||
to = +attrs[key];
|
||||
}
|
||||
var len = is(from, "array") ? from.length : 1;
|
||||
keys[key] = slice(fkeys.length, fkeys.length + len, f);
|
||||
fkeys = fkeys.concat(from);
|
||||
tkeys = tkeys.concat(to);
|
||||
}
|
||||
var now = mina.time(),
|
||||
anim = mina(fkeys, tkeys, now, now + ms, mina.time, function (val) {
|
||||
var attr = {};
|
||||
for (var key in keys) if (keys[has](key)) {
|
||||
attr[key] = keys[key](val);
|
||||
}
|
||||
el.attr(attr);
|
||||
}, easing);
|
||||
el.anims[anim.id] = anim;
|
||||
anim._attrs = attrs;
|
||||
anim._callback = callback;
|
||||
eve("snap.animcreated." + el.id, anim);
|
||||
eve.once("mina.finish." + anim.id, function () {
|
||||
delete el.anims[anim.id];
|
||||
callback && callback.call(el);
|
||||
});
|
||||
eve.once("mina.stop." + anim.id, function () {
|
||||
delete el.anims[anim.id];
|
||||
});
|
||||
return el;
|
||||
};
|
||||
var eldata = {};
|
||||
/*\
|
||||
* Element.data
|
||||
[ method ]
|
||||
**
|
||||
* Adds or retrieves given value associated with given key. (Don’t confuse
|
||||
* with `data-` attributes)
|
||||
*
|
||||
* See also @Element.removeData
|
||||
- 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 == 0){
|
||||
eve("snap.data.get." + this.id, this, data, null);
|
||||
return data;
|
||||
}
|
||||
if (arguments.length == 1) {
|
||||
if (Snap.is(key, "object")) {
|
||||
for (var i in key) if (key[has](i)) {
|
||||
this.data(i, key[i]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
eve("snap.data.get." + this.id, this, data[key], key);
|
||||
return data[key];
|
||||
}
|
||||
data[key] = value;
|
||||
eve("snap.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.
|
||||
- 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.outerSVG
|
||||
[ method ]
|
||||
**
|
||||
* Returns SVG code for the element, equivalent to HTML's `outerHTML`.
|
||||
*
|
||||
* See also @Element.innerSVG
|
||||
= (string) SVG code for the element
|
||||
\*/
|
||||
/*\
|
||||
* Element.toString
|
||||
[ method ]
|
||||
**
|
||||
* See @Element.outerSVG
|
||||
\*/
|
||||
elproto.outerSVG = elproto.toString = toString(1);
|
||||
/*\
|
||||
* Element.innerSVG
|
||||
[ method ]
|
||||
**
|
||||
* Returns SVG code for the element's contents, equivalent to HTML's `innerHTML`
|
||||
= (string) SVG code for the element
|
||||
\*/
|
||||
elproto.innerSVG = toString();
|
||||
function toString(type) {
|
||||
return function () {
|
||||
var res = type ? "<" + this.type : "",
|
||||
attr = this.node.attributes,
|
||||
chld = this.node.childNodes;
|
||||
if (type) {
|
||||
for (var i = 0, ii = attr.length; i < ii; i++) {
|
||||
res += " " + attr[i].name + '="' +
|
||||
attr[i].value.replace(/"/g, '\\"') + '"';
|
||||
}
|
||||
}
|
||||
if (chld.length) {
|
||||
type && (res += ">");
|
||||
for (i = 0, ii = chld.length; i < ii; i++) {
|
||||
if (chld[i].nodeType == 3) {
|
||||
res += chld[i].nodeValue;
|
||||
} else if (chld[i].nodeType == 1) {
|
||||
res += wrap(chld[i]).toString();
|
||||
}
|
||||
}
|
||||
type && (res += "</" + this.type + ">");
|
||||
} else {
|
||||
type && (res += "/>");
|
||||
}
|
||||
return res;
|
||||
};
|
||||
}
|
||||
}(Element.prototype));
|
||||
/*\
|
||||
* Snap.parse
|
||||
[ method ]
|
||||
|
@ -2201,20 +1264,6 @@ Snap.parse = function (svg) {
|
|||
function Fragment(frag) {
|
||||
this.node = frag;
|
||||
}
|
||||
/*\
|
||||
* Fragment.select
|
||||
[ method ]
|
||||
**
|
||||
* See @Element.select
|
||||
\*/
|
||||
Fragment.prototype.select = Element.prototype.select;
|
||||
/*\
|
||||
* Fragment.selectAll
|
||||
[ method ]
|
||||
**
|
||||
* See @Element.selectAll
|
||||
\*/
|
||||
Fragment.prototype.selectAll = Element.prototype.selectAll;
|
||||
// SIERRA Snap.fragment() could especially use a code example
|
||||
/*\
|
||||
* Snap.fragment
|
||||
|
|
Loading…
Reference in New Issue