1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
// ### A module used for container elements like SVG.Doc, SVG.Group, SVG.Defs, ...
//
SVG.Container = {
// Add given element at a position
add: function(element, index) {
if (!this.has(element)) {
index = index == null ? this.children().length : index;
this.children().splice(index, 0, element);
this.node.insertBefore(element.node, this.node.childNodes[index] || null);
element.parent = this;
}
return this;
},
// Basically does the same as `add()` but returns the added element
put: function(element, index) {
this.add(element, index);
return element;
},
// Checks if the given element is a child
has: function(element) {
return this.children().indexOf(element) >= 0;
},
// Returns all child elements
children: function() {
return this._children || (this._children = []);
},
// Iterates over all children and invokes a given block
each: function(block) {
var index,
children = this.children();
for (index = 0, length = children.length; index < length; index++)
if (children[index] instanceof SVG.Shape)
block.apply(children[index], [index, children]);
return this;
},
// Remove a given child element
remove: function(element) {
return this.removeAt(this.children().indexOf(element));
},
// Remove a child element at a given position
removeAt: function(index) {
if (0 <= index && index < this.children().length) {
var element = this.children()[index];
this.children().splice(index, 1);
this.node.removeChild(element.node);
element.parent = null;
}
return this;
},
// Returns defs element
defs: function() {
return this._defs || (this._defs = this.put(new SVG.Defs(), 0));
},
// Re-level defs to first positon in element stack
level: function() {
return this.remove(this.defs()).put(this.defs(), 0);
},
// Create a group element
group: function() {
return this.put(new SVG.G());
},
// Create a rect element
rect: function(width, height) {
return this.put(new SVG.Rect().size(width, height));
},
// Create circle element, based on ellipse
circle: function(diameter) {
return this.ellipse(diameter);
},
// Create an ellipse
ellipse: function(width, height) {
return this.put(new SVG.Ellipse().size(width, height));
},
// Create a wrapped polyline element
polyline: function(points) {
return this.put(new Wrap(new SVG.Polyline())).plot(points);
},
// Create a wrapped polygon element
polygon: function(points) {
return this.put(new Wrap(new SVG.Polygon())).plot(points);
},
// Create a wrapped path element
path: function(data) {
return this.put(new Wrap(new SVG.Path())).plot(data);
},
// Create image element, load image and set its size
image: function(source, width, height) {
width = width != null ? width : 100;
return this.put(new SVG.Image().load(source).size(width, height != null ? height : width));
},
// Create text element
text: function(text) {
return this.put(new SVG.Text().text(text));
},
// Create nested svg document
nested: function() {
return this.put(new SVG.Nested());
},
// create element in defs
gradient: function(type, block) {
return this.defs().gradient(type, block);
},
// Create masking element
mask: function() {
return this.defs().put(new SVG.Mask());
},
// Get first child, skipping the defs node
first: function() {
return this.children()[0] instanceof SVG.Defs ? this.children()[1] : this.children()[0];
},
// Get the last child
last: function() {
return this.children()[this.children().length - 1];
},
// Remove all elements in this container
clear: function() {
this._children = [];
while (this.node.hasChildNodes())
this.node.removeChild(this.node.lastChild);
return this;
},
// Hack for safari preventing text to be rendered in one line.
// Basically it sets the position of the svg node to absolute
// when the dom is loaded, and resets it to relative a few milliseconds later.
stage: function() {
var check, element = this;
check = function() {
if (document.readyState === 'complete') {
element.attr('style', 'position:absolute;');
setTimeout(function() { element.attr('style', 'position:relative;'); }, 5);
} else {
setTimeout(check, 10);
}
};
check();
return this;
}
};
|