2013-08-15 08:29:47 +00:00
|
|
|
// 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.
|
2013-07-11 03:23:37 +00:00
|
|
|
Savage.plugin(function (Savage, Element, Paper, glob) {
|
2013-07-05 07:23:52 +00:00
|
|
|
var mmax = Math.max,
|
2013-07-11 03:23:37 +00:00
|
|
|
mmin = Math.min;
|
2013-07-05 07:23:52 +00:00
|
|
|
|
|
|
|
// Set
|
|
|
|
var Set = function (items) {
|
|
|
|
this.items = [];
|
|
|
|
this.length = 0;
|
|
|
|
this.type = "set";
|
|
|
|
if (items) {
|
|
|
|
for (var i = 0, ii = items.length; i < ii; i++) {
|
|
|
|
if (items[i]) {
|
|
|
|
this[this.items.length] = this.items[this.items.length] = items[i];
|
|
|
|
this.length++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setproto = Set.prototype;
|
|
|
|
/*\
|
|
|
|
* Set.push
|
|
|
|
[ method ]
|
|
|
|
**
|
|
|
|
* Adds each argument to the current set.
|
|
|
|
= (object) original element
|
|
|
|
\*/
|
|
|
|
setproto.push = function () {
|
|
|
|
var item,
|
|
|
|
len;
|
|
|
|
for (var i = 0, ii = arguments.length; i < ii; i++) {
|
|
|
|
item = arguments[i];
|
|
|
|
if (item) {
|
|
|
|
len = this.items.length;
|
|
|
|
this[len] = this.items[len] = item;
|
|
|
|
this.length++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/*\
|
|
|
|
* Set.pop
|
|
|
|
[ method ]
|
|
|
|
**
|
|
|
|
* Removes last element and returns it.
|
|
|
|
= (object) element
|
|
|
|
\*/
|
|
|
|
setproto.pop = function () {
|
|
|
|
this.length && delete this[this.length--];
|
|
|
|
return this.items.pop();
|
|
|
|
};
|
|
|
|
/*\
|
|
|
|
* Set.forEach
|
|
|
|
[ method ]
|
|
|
|
**
|
|
|
|
* Executes given function for each element in the set.
|
|
|
|
*
|
|
|
|
* If function returns `false` it will stop loop running.
|
|
|
|
**
|
|
|
|
> Parameters
|
|
|
|
**
|
|
|
|
- callback (function) function to run
|
|
|
|
- thisArg (object) context object for the callback
|
|
|
|
= (object) Set object
|
|
|
|
\*/
|
|
|
|
setproto.forEach = function (callback, thisArg) {
|
|
|
|
for (var i = 0, ii = this.items.length; i < ii; i++) {
|
|
|
|
if (callback.call(thisArg, this.items[i], i) === false) {
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
};
|
2013-07-11 03:23:37 +00:00
|
|
|
setproto.attr = function (value) {
|
2013-07-05 07:23:52 +00:00
|
|
|
for (var i = 0, ii = this.items.length; i < ii; i++) {
|
2013-07-11 03:23:37 +00:00
|
|
|
this.items[i].attr(value);
|
2013-07-05 07:23:52 +00:00
|
|
|
}
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/*\
|
|
|
|
* Set.clear
|
|
|
|
[ method ]
|
|
|
|
**
|
|
|
|
* Removeds all elements from the set
|
|
|
|
\*/
|
|
|
|
setproto.clear = function () {
|
|
|
|
while (this.length) {
|
|
|
|
this.pop();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/*\
|
|
|
|
* Set.splice
|
|
|
|
[ method ]
|
|
|
|
**
|
|
|
|
* Removes given element from the set
|
|
|
|
**
|
|
|
|
> Parameters
|
|
|
|
**
|
|
|
|
- index (number) position of the deletion
|
|
|
|
- count (number) number of element to remove
|
|
|
|
- insertion… (object) #optional elements to insert
|
|
|
|
= (object) set elements that were deleted
|
|
|
|
\*/
|
|
|
|
setproto.splice = function (index, count, insertion) {
|
|
|
|
index = index < 0 ? mmax(this.length + index, 0) : index;
|
|
|
|
count = mmax(0, mmin(this.length - index, count));
|
|
|
|
var tail = [],
|
|
|
|
todel = [],
|
|
|
|
args = [],
|
|
|
|
i;
|
|
|
|
for (i = 2; i < arguments.length; i++) {
|
|
|
|
args.push(arguments[i]);
|
|
|
|
}
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
todel.push(this[index + i]);
|
|
|
|
}
|
|
|
|
for (; i < this.length - index; i++) {
|
|
|
|
tail.push(this[index + i]);
|
|
|
|
}
|
|
|
|
var arglen = args.length;
|
|
|
|
for (i = 0; i < arglen + tail.length; i++) {
|
|
|
|
this.items[index + i] = this[index + i] = i < arglen ? args[i] : tail[i - arglen];
|
|
|
|
}
|
|
|
|
i = this.items.length = this.length -= count - arglen;
|
|
|
|
while (this[i]) {
|
|
|
|
delete this[i++];
|
|
|
|
}
|
|
|
|
return new Set(todel);
|
|
|
|
};
|
|
|
|
/*\
|
|
|
|
* Set.exclude
|
|
|
|
[ method ]
|
|
|
|
**
|
|
|
|
* Removes given element from the set
|
|
|
|
**
|
|
|
|
> Parameters
|
|
|
|
**
|
|
|
|
- element (object) element to remove
|
|
|
|
= (boolean) `true` if object was found & removed from the set
|
|
|
|
\*/
|
|
|
|
setproto.exclude = function (el) {
|
|
|
|
for (var i = 0, ii = this.length; i < ii; i++) if (this[i] == el) {
|
|
|
|
this.splice(i, 1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
setproto.insertAfter = function (el) {
|
|
|
|
var i = this.items.length;
|
|
|
|
while (i--) {
|
|
|
|
this.items[i].insertAfter(el);
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
setproto.getBBox = function () {
|
|
|
|
var x = [],
|
|
|
|
y = [],
|
|
|
|
x2 = [],
|
|
|
|
y2 = [];
|
|
|
|
for (var i = this.items.length; i--;) if (!this.items[i].removed) {
|
|
|
|
var box = this.items[i].getBBox();
|
|
|
|
x.push(box.x);
|
|
|
|
y.push(box.y);
|
|
|
|
x2.push(box.x + box.width);
|
|
|
|
y2.push(box.y + box.height);
|
|
|
|
}
|
|
|
|
x = mmin.apply(0, x);
|
|
|
|
y = mmin.apply(0, y);
|
|
|
|
x2 = mmax.apply(0, x2);
|
|
|
|
y2 = mmax.apply(0, y2);
|
|
|
|
return {
|
|
|
|
x: x,
|
|
|
|
y: y,
|
|
|
|
x2: x2,
|
|
|
|
y2: y2,
|
|
|
|
width: x2 - x,
|
|
|
|
height: y2 - y,
|
|
|
|
cx: x + (x2 - x) / 2,
|
|
|
|
cy: y + (y2 - y) / 2
|
|
|
|
};
|
|
|
|
};
|
|
|
|
setproto.clone = function (s) {
|
|
|
|
s = new Set;
|
|
|
|
for (var i = 0, ii = this.items.length; i < ii; i++) {
|
|
|
|
s.push(this.items[i].clone());
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
};
|
|
|
|
setproto.toString = function () {
|
|
|
|
return "Savage\u2018s set";
|
|
|
|
};
|
|
|
|
setproto.type = "set";
|
|
|
|
// export
|
2013-07-11 03:23:37 +00:00
|
|
|
Savage.set = function () {
|
2013-07-05 07:23:52 +00:00
|
|
|
var set = new Set;
|
|
|
|
if (arguments.length) {
|
|
|
|
set.push.apply(set, Array.prototype.slice.call(arguments, 0));
|
|
|
|
}
|
|
|
|
return set;
|
|
|
|
};
|
2013-07-11 03:23:37 +00:00
|
|
|
});
|