aboutsummaryrefslogtreecommitdiffstats
path: root/dcae_dmaapbc_webapp/src/main/webapp/app/fusion/ase/scripts/bower_components/Snap.svg/dist/snap.svg.js
diff options
context:
space:
mode:
Diffstat (limited to 'dcae_dmaapbc_webapp/src/main/webapp/app/fusion/ase/scripts/bower_components/Snap.svg/dist/snap.svg.js')
-rw-r--r--dcae_dmaapbc_webapp/src/main/webapp/app/fusion/ase/scripts/bower_components/Snap.svg/dist/snap.svg.js8170
1 files changed, 0 insertions, 8170 deletions
diff --git a/dcae_dmaapbc_webapp/src/main/webapp/app/fusion/ase/scripts/bower_components/Snap.svg/dist/snap.svg.js b/dcae_dmaapbc_webapp/src/main/webapp/app/fusion/ase/scripts/bower_components/Snap.svg/dist/snap.svg.js
deleted file mode 100644
index 5475170..0000000
--- a/dcae_dmaapbc_webapp/src/main/webapp/app/fusion/ase/scripts/bower_components/Snap.svg/dist/snap.svg.js
+++ /dev/null
@@ -1,8170 +0,0 @@
-// Snap.svg 0.4.1
-//
-// Copyright (c) 2013 – 2015 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.
-//
-// build: 2015-04-13
-
-// 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.
-// ┌────────────────────────────────────────────────────────────┐ \\
-// │ Eve 0.4.2 - JavaScript Events Library │ \\
-// ├────────────────────────────────────────────────────────────┤ \\
-// │ Author Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) │ \\
-// └────────────────────────────────────────────────────────────┘ \\
-
-(function (glob) {
- var version = "0.4.2",
- has = "hasOwnProperty",
- separator = /[\.\/]/,
- comaseparator = /\s*,\s*/,
- wildcard = "*",
- fun = function () {},
- numsort = function (a, b) {
- return a - b;
- },
- current_event,
- stop,
- events = {n: {}},
- firstDefined = function () {
- for (var i = 0, ii = this.length; i < ii; i++) {
- if (typeof this[i] != "undefined") {
- return this[i];
- }
- }
- },
- lastDefined = function () {
- var i = this.length;
- while (--i) {
- if (typeof this[i] != "undefined") {
- return this[i];
- }
- }
- },
- /*\
- * eve
- [ method ]
-
- * Fires event with given `name`, given scope and other parameters.
-
- > Arguments
-
- - name (string) name of the *event*, dot (`.`) or slash (`/`) separated
- - scope (object) context for the event handlers
- - varargs (...) the rest of arguments will be sent to event handlers
-
- = (object) array of returned values from the listeners. Array has two methods `.firstDefined()` and `.lastDefined()` to get first or last not `undefined` value.
- \*/
- eve = function (name, scope) {
- name = String(name);
- var e = events,
- oldstop = stop,
- args = Array.prototype.slice.call(arguments, 2),
- listeners = eve.listeners(name),
- z = 0,
- f = false,
- l,
- indexed = [],
- queue = {},
- out = [],
- ce = current_event,
- errors = [];
- out.firstDefined = firstDefined;
- out.lastDefined = lastDefined;
- current_event = name;
- stop = 0;
- for (var i = 0, ii = listeners.length; i < ii; i++) if ("zIndex" in listeners[i]) {
- indexed.push(listeners[i].zIndex);
- if (listeners[i].zIndex < 0) {
- queue[listeners[i].zIndex] = listeners[i];
- }
- }
- indexed.sort(numsort);
- while (indexed[z] < 0) {
- l = queue[indexed[z++]];
- out.push(l.apply(scope, args));
- if (stop) {
- stop = oldstop;
- return out;
- }
- }
- for (i = 0; i < ii; i++) {
- l = listeners[i];
- if ("zIndex" in l) {
- if (l.zIndex == indexed[z]) {
- out.push(l.apply(scope, args));
- if (stop) {
- break;
- }
- do {
- z++;
- l = queue[indexed[z]];
- l && out.push(l.apply(scope, args));
- if (stop) {
- break;
- }
- } while (l)
- } else {
- queue[l.zIndex] = l;
- }
- } else {
- out.push(l.apply(scope, args));
- if (stop) {
- break;
- }
- }
- }
- stop = oldstop;
- current_event = ce;
- return out;
- };
- // Undocumented. Debug only.
- eve._events = events;
- /*\
- * eve.listeners
- [ method ]
-
- * Internal method which gives you array of all event handlers that will be triggered by the given `name`.
-
- > Arguments
-
- - name (string) name of the event, dot (`.`) or slash (`/`) separated
-
- = (array) array of event handlers
- \*/
- eve.listeners = function (name) {
- var names = name.split(separator),
- e = events,
- item,
- items,
- k,
- i,
- ii,
- j,
- jj,
- nes,
- es = [e],
- out = [];
- for (i = 0, ii = names.length; i < ii; i++) {
- nes = [];
- for (j = 0, jj = es.length; j < jj; j++) {
- e = es[j].n;
- items = [e[names[i]], e[wildcard]];
- k = 2;
- while (k--) {
- item = items[k];
- if (item) {
- nes.push(item);
- out = out.concat(item.f || []);
- }
- }
- }
- es = nes;
- }
- return out;
- };
-
- /*\
- * eve.on
- [ method ]
- **
- * Binds given event handler with a given name. You can use wildcards “`*`” for the names:
- | eve.on("*.under.*", f);
- | eve("mouse.under.floor"); // triggers f
- * Use @eve to trigger the listener.
- **
- > Arguments
- **
- - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
- - f (function) event handler function
- **
- = (function) returned function accepts a single numeric parameter that represents z-index of the handler. It is an optional feature and only used when you need to ensure that some subset of handlers will be invoked in a given order, despite of the order of assignment.
- > Example:
- | eve.on("mouse", eatIt)(2);
- | eve.on("mouse", scream);
- | eve.on("mouse", catchIt)(1);
- * This will ensure that `catchIt` function will be called before `eatIt`.
- *
- * If you want to put your handler before non-indexed handlers, specify a negative value.
- * Note: I assume most of the time you don’t need to worry about z-index, but it’s nice to have this feature “just in case”.
- \*/
- eve.on = function (name, f) {
- name = String(name);
- if (typeof f != "function") {
- return function () {};
- }
- var names = name.split(comaseparator);
- for (var i = 0, ii = names.length; i < ii; i++) {
- (function (name) {
- var names = name.split(separator),
- e = events,
- exist;
- for (var i = 0, ii = names.length; i < ii; i++) {
- e = e.n;
- e = e.hasOwnProperty(names[i]) && e[names[i]] || (e[names[i]] = {n: {}});
- }
- e.f = e.f || [];
- for (i = 0, ii = e.f.length; i < ii; i++) if (e.f[i] == f) {
- exist = true;
- break;
- }
- !exist && e.f.push(f);
- }(names[i]));
- }
- return function (zIndex) {
- if (+zIndex == +zIndex) {
- f.zIndex = +zIndex;
- }
- };
- };
- /*\
- * eve.f
- [ method ]
- **
- * Returns function that will fire given event with optional arguments.
- * Arguments that will be passed to the result function will be also
- * concated to the list of final arguments.
- | el.onclick = eve.f("click", 1, 2);
- | eve.on("click", function (a, b, c) {
- | console.log(a, b, c); // 1, 2, [event object]
- | });
- > Arguments
- - event (string) event name
- - varargs (…) and any other arguments
- = (function) possible event handler function
- \*/
- eve.f = function (event) {
- var attrs = [].slice.call(arguments, 1);
- return function () {
- eve.apply(null, [event, null].concat(attrs).concat([].slice.call(arguments, 0)));
- };
- };
- /*\
- * eve.stop
- [ method ]
- **
- * Is used inside an event handler to stop the event, preventing any subsequent listeners from firing.
- \*/
- eve.stop = function () {
- stop = 1;
- };
- /*\
- * eve.nt
- [ method ]
- **
- * Could be used inside event handler to figure out actual name of the event.
- **
- > Arguments
- **
- - subname (string) #optional subname of the event
- **
- = (string) name of the event, if `subname` is not specified
- * or
- = (boolean) `true`, if current event’s name contains `subname`
- \*/
- eve.nt = function (subname) {
- if (subname) {
- return new RegExp("(?:\\.|\\/|^)" + subname + "(?:\\.|\\/|$)").test(current_event);
- }
- return current_event;
- };
- /*\
- * eve.nts
- [ method ]
- **
- * Could be used inside event handler to figure out actual name of the event.
- **
- **
- = (array) names of the event
- \*/
- eve.nts = function () {
- return current_event.split(separator);
- };
- /*\
- * eve.off
- [ method ]
- **
- * Removes given function from the list of event listeners assigned to given name.
- * If no arguments specified all the events will be cleared.
- **
- > Arguments
- **
- - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
- - f (function) event handler function
- \*/
- /*\
- * eve.unbind
- [ method ]
- **
- * See @eve.off
- \*/
- eve.off = eve.unbind = function (name, f) {
- if (!name) {
- eve._events = events = {n: {}};
- return;
- }
- var names = name.split(comaseparator);
- if (names.length > 1) {
- for (var i = 0, ii = names.length; i < ii; i++) {
- eve.off(names[i], f);
- }
- return;
- }
- names = name.split(separator);
- var e,
- key,
- splice,
- i, ii, j, jj,
- cur = [events];
- for (i = 0, ii = names.length; i < ii; i++) {
- for (j = 0; j < cur.length; j += splice.length - 2) {
- splice = [j, 1];
- e = cur[j].n;
- if (names[i] != wildcard) {
- if (e[names[i]]) {
- splice.push(e[names[i]]);
- }
- } else {
- for (key in e) if (e[has](key)) {
- splice.push(e[key]);
- }
- }
- cur.splice.apply(cur, splice);
- }
- }
- for (i = 0, ii = cur.length; i < ii; i++) {
- e = cur[i];
- while (e.n) {
- if (f) {
- if (e.f) {
- for (j = 0, jj = e.f.length; j < jj; j++) if (e.f[j] == f) {
- e.f.splice(j, 1);
- break;
- }
- !e.f.length && delete e.f;
- }
- for (key in e.n) if (e.n[has](key) && e.n[key].f) {
- var funcs = e.n[key].f;
- for (j = 0, jj = funcs.length; j < jj; j++) if (funcs[j] == f) {
- funcs.splice(j, 1);
- break;
- }
- !funcs.length && delete e.n[key].f;
- }
- } else {
- delete e.f;
- for (key in e.n) if (e.n[has](key) && e.n[key].f) {
- delete e.n[key].f;
- }
- }
- e = e.n;
- }
- }
- };
- /*\
- * eve.once
- [ method ]
- **
- * Binds given event handler with a given name to only run once then unbind itself.
- | eve.once("login", f);
- | eve("login"); // triggers f
- | eve("login"); // no listeners
- * Use @eve to trigger the listener.
- **
- > Arguments
- **
- - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
- - f (function) event handler function
- **
- = (function) same return function as @eve.on
- \*/
- eve.once = function (name, f) {
- var f2 = function () {
- eve.unbind(name, f2);
- return f.apply(this, arguments);
- };
- return eve.on(name, f2);
- };
- /*\
- * eve.version
- [ property (string) ]
- **
- * Current version of the library.
- \*/
- eve.version = version;
- eve.toString = function () {
- return "You are running Eve " + version;
- };
- (typeof module != "undefined" && module.exports) ? (module.exports = eve) : (typeof define === "function" && define.amd ? (define("eve", [], function() { return eve; })) : (glob.eve = eve));
-})(this);
-
-(function (glob, factory) {
- // AMD support
- if (typeof define == "function" && define.amd) {
- // Define as an anonymous module
- define(["eve"], function (eve) {
- return factory(glob, eve);
- });
- } else if (typeof exports != 'undefined') {
- // Next for Node.js or CommonJS
- var eve = require('eve');
- module.exports = factory(glob, eve);
- } else {
- // Browser globals (glob is window)
- // Snap adds itself to window
- factory(glob, glob.eve);
- }
-}(window || this, function (window, eve) {
-
-// 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.
-var mina = (function (eve) {
- var animations = {},
- requestAnimFrame = window.requestAnimationFrame ||
- window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- window.oRequestAnimationFrame ||
- window.msRequestAnimationFrame ||
- function (callback) {
- setTimeout(callback, 16);
- },
- isArray = Array.isArray || function (a) {
- return a instanceof Array ||
- Object.prototype.toString.call(a) == "[object Array]";
- },
- idgen = 0,
- idprefix = "M" + (+new Date).toString(36),
- ID = function () {
- return idprefix + (idgen++).toString(36);
- },
- 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);
- return function (bb) {
- return a + dif * (bb - b);
- };
- },
- timer = Date.now || function () {
- return +new Date;
- },
- sta = function (val) {
- var a = this;
- if (val == null) {
- return a.s;
- }
- var ds = a.s - val;
- a.b += a.dur * ds;
- a.B += a.dur * ds;
- a.s = val;
- },
- speed = function (val) {
- var a = this;
- if (val == null) {
- return a.spd;
- }
- a.spd = val;
- },
- duration = function (val) {
- var a = this;
- if (val == null) {
- return a.dur;
- }
- a.s = a.s * val / a.dur;
- a.dur = val;
- },
- stopit = function () {
- var a = this;
- delete animations[a.id];
- a.update();
- eve("mina.stop." + a.id, a);
- },
- pause = function () {
- var a = this;
- if (a.pdif) {
- return;
- }
- delete animations[a.id];
- a.update();
- a.pdif = a.get() - a.b;
- },
- resume = function () {
- var a = this;
- if (!a.pdif) {
- return;
- }
- a.b = a.get() - a.pdif;
- delete a.pdif;
- animations[a.id] = a;
- },
- update = function () {
- var a = this,
- res;
- if (isArray(a.start)) {
- res = [];
- for (var j = 0, jj = a.start.length; j < jj; j++) {
- res[j] = +a.start[j] +
- (a.end[j] - a.start[j]) * a.easing(a.s);
- }
- } else {
- res = +a.start + (a.end - a.start) * a.easing(a.s);
- }
- a.set(res);
- },
- frame = function () {
- var len = 0;
- for (var i in animations) if (animations.hasOwnProperty(i)) {
- var a = animations[i],
- b = a.get(),
- res;
- len++;
- a.s = (b - a.b) / (a.dur / a.spd);
- if (a.s >= 1) {
- delete animations[i];
- a.s = 1;
- len--;
- (function (a) {
- setTimeout(function () {
- eve("mina.finish." + a.id, a);
- });
- }(a));
- }
- a.update();
- }
- len && requestAnimFrame(frame);
- },
- /*\
- * mina
- [ method ]
- **
- * Generic animation of numbers
- **
- - a (number) start _slave_ number
- - A (number) end _slave_ number
- - b (number) start _master_ number (start time in general case)
- - B (number) end _master_ number (end time in gereal case)
- - get (function) getter of _master_ number (see @mina.time)
- - set (function) setter of _slave_ number
- - easing (function) #optional easing function, default is @mina.linear
- = (object) animation descriptor
- o {
- o id (string) animation id,
- o start (number) start _slave_ number,
- o end (number) end _slave_ number,
- o b (number) start _master_ number,
- o s (number) animation status (0..1),
- o dur (number) animation duration,
- o spd (number) animation speed,
- o get (function) getter of _master_ number (see @mina.time),
- o set (function) setter of _slave_ number,
- o easing (function) easing function, default is @mina.linear,
- o status (function) status getter/setter,
- o speed (function) speed getter/setter,
- o duration (function) duration getter/setter,
- o stop (function) animation stopper
- o pause (function) pauses the animation
- o resume (function) resumes the animation
- o update (function) calles setter with the right value of the animation
- o }
- \*/
- mina = function (a, A, b, B, get, set, easing) {
- var anim = {
- id: ID(),
- start: a,
- end: A,
- b: b,
- s: 0,
- dur: B - b,
- spd: 1,
- get: get,
- set: set,
- easing: easing || mina.linear,
- status: sta,
- speed: speed,
- duration: duration,
- stop: stopit,
- pause: pause,
- resume: resume,
- update: update
- };
- animations[anim.id] = anim;
- var len = 0, i;
- for (i in animations) if (animations.hasOwnProperty(i)) {
- len++;
- if (len == 2) {
- break;
- }
- }
- len == 1 && requestAnimFrame(frame);
- return anim;
- };
- /*\
- * mina.time
- [ method ]
- **
- * Returns the current time. Equivalent to:
- | function () {
- | return (new Date).getTime();
- | }
- \*/
- mina.time = timer;
- /*\
- * mina.getById
- [ method ]
- **
- * Returns an animation by its id
- - id (string) animation's id
- = (object) See @mina
- \*/
- mina.getById = function (id) {
- return animations[id] || null;
- };
-
- /*\
- * mina.linear
- [ method ]
- **
- * Default linear easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.linear = function (n) {
- return n;
- };
- /*\
- * mina.easeout
- [ method ]
- **
- * Easeout easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.easeout = function (n) {
- return Math.pow(n, 1.7);
- };
- /*\
- * mina.easein
- [ method ]
- **
- * Easein easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.easein = function (n) {
- return Math.pow(n, .48);
- };
- /*\
- * mina.easeinout
- [ method ]
- **
- * Easeinout easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.easeinout = function (n) {
- if (n == 1) {
- return 1;
- }
- if (n == 0) {
- return 0;
- }
- var q = .48 - n / 1.04,
- Q = Math.sqrt(.1734 + q * q),
- x = Q - q,
- X = Math.pow(Math.abs(x), 1 / 3) * (x < 0 ? -1 : 1),
- y = -Q - q,
- Y = Math.pow(Math.abs(y), 1 / 3) * (y < 0 ? -1 : 1),
- t = X + Y + .5;
- return (1 - t) * 3 * t * t + t * t * t;
- };
- /*\
- * mina.backin
- [ method ]
- **
- * Backin easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.backin = function (n) {
- if (n == 1) {
- return 1;
- }
- var s = 1.70158;
- return n * n * ((s + 1) * n - s);
- };
- /*\
- * mina.backout
- [ method ]
- **
- * Backout easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.backout = function (n) {
- if (n == 0) {
- return 0;
- }
- n = n - 1;
- var s = 1.70158;
- return n * n * ((s + 1) * n + s) + 1;
- };
- /*\
- * mina.elastic
- [ method ]
- **
- * Elastic easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.elastic = function (n) {
- if (n == !!n) {
- return n;
- }
- return Math.pow(2, -10 * n) * Math.sin((n - .075) *
- (2 * Math.PI) / .3) + 1;
- };
- /*\
- * mina.bounce
- [ method ]
- **
- * Bounce easing
- - n (number) input 0..1
- = (number) output 0..1
- \*/
- mina.bounce = function (n) {
- var s = 7.5625,
- p = 2.75,
- l;
- if (n < (1 / p)) {
- l = s * n * n;
- } else {
- if (n < (2 / p)) {
- n -= (1.5 / p);
- l = s * n * n + .75;
- } else {
- if (n < (2.5 / p)) {
- n -= (2.25 / p);
- l = s * n * n + .9375;
- } else {
- n -= (2.625 / p);
- l = s * n * n + .984375;
- }
- }
- }
- return l;
- };
- window.mina = mina;
- return mina;
-})(typeof eve == "undefined" ? function () {} : eve);
-// Copyright (c) 2013 - 2015 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.
-
-var Snap = (function(root) {
-Snap.version = "0.4.0";
-/*\
- * Snap
- [ method ]
- **
- * Creates a drawing surface or wraps existing SVG element.
- **
- - width (number|string) width of surface
- - height (number|string) height of surface
- * or
- - DOM (SVGElement) element to be wrapped into Snap structure
- * or
- - array (array) array of elements (will return set of elements)
- * or
- - query (string) CSS query selector
- = (object) @Element
-\*/
-function Snap(w, h) {
- if (w) {
- if (w.nodeType) {
- return wrap(w);
- }
- if (is(w, "array") && Snap.set) {
- return Snap.set.apply(Snap, w);
- }
- if (w instanceof Element) {
- return w;
- }
- if (h == null) {
- w = glob.doc.querySelector(String(w));
- return wrap(w);
- }
- }
- w = w == null ? "100%" : w;
- h = h == null ? "100%" : h;
- return new Paper(w, h);
-}
-Snap.toString = function () {
- return "Snap v" + this.version;
-};
-Snap._ = {};
-var glob = {
- win: root.window,
- doc: root.window.document
-};
-Snap._.glob = glob;
-var has = "hasOwnProperty",
- Str = String,
- toFloat = parseFloat,
- toInt = parseInt,
- math = Math,
- mmax = math.max,
- mmin = math.min,
- abs = math.abs,
- pow = math.pow,
- PI = math.PI,
- round = math.round,
- E = "",
- S = " ",
- objectToString = Object.prototype.toString,
- ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/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,
- bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,
- reURLValue = /^url\(#?([^)]+)\)$/,
- separator = Snap._.separator = /[,\s]+/,
- whitespace = /[\s]/g,
- commaSpaces = /[\s]*,[\s]*/,
- hsrg = {hs: 1, rg: 1},
- pathCommand = /([a-z])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/ig,
- tCommand = /([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/ig,
- pathValues = /(-?\d*\.?\d*(?:e[\-+]?\\d+)?)[\s]*,?[\s]*/ig,
- idgen = 0,
- idprefix = "S" + (+new Date).toString(36),
- ID = function (el) {
- return (el && el.type ? el.type : E) + idprefix + (idgen++).toString(36);
- },
- xlink = "http://www.w3.org/1999/xlink",
- xmlns = "http://www.w3.org/2000/svg",
- hub = {},
- URL = Snap.url = function (url) {
- return "url('#" + url + "')";
- };
-
-function $(el, attr) {
- if (attr) {
- if (el == "#text") {
- el = glob.doc.createTextNode(attr.text || attr["#text"] || "");
- }
- if (el == "#comment") {
- el = glob.doc.createComment(attr.text || attr["#text"] || "");
- }
- if (typeof el == "string") {
- el = $(el);
- }
- if (typeof attr == "string") {
- if (el.nodeType == 1) {
- if (attr.substring(0, 6) == "xlink:") {
- return el.getAttributeNS(xlink, attr.substring(6));
- }
- if (attr.substring(0, 4) == "xml:") {
- return el.getAttributeNS(xmlns, attr.substring(4));
- }
- return el.getAttribute(attr);
- } else if (attr == "text") {
- return el.nodeValue;
- } else {
- return null;
- }
- }
- if (el.nodeType == 1) {
- for (var key in attr) if (attr[has](key)) {
- var val = Str(attr[key]);
- if (val) {
- if (key.substring(0, 6) == "xlink:") {
- el.setAttributeNS(xlink, key.substring(6), val);
- } else if (key.substring(0, 4) == "xml:") {
- el.setAttributeNS(xmlns, key.substring(4), val);
- } else {
- el.setAttribute(key, val);
- }
- } else {
- el.removeAttribute(key);
- }
- }
- } else if ("text" in attr) {
- el.nodeValue = attr.text;
- }
- } else {
- el = glob.doc.createElementNS(xmlns, el);
- }
- return el;
-}
-Snap._.$ = $;
-Snap._.id = ID;
-function getAttrs(el) {
- var attrs = el.attributes,
- name,
- out = {};
- for (var i = 0; i < attrs.length; i++) {
- if (attrs[i].namespaceURI == xlink) {
- name = "xlink:";
- } else {
- name = "";
- }
- name += attrs[i].name;
- out[name] = attrs[i].textContent;
- }
- return out;
-}
-function is(o, type) {
- type = Str.prototype.toLowerCase.call(type);
- if (type == "finite") {
- return isFinite(o);
- }
- if (type == "array" &&
- (o instanceof Array || Array.isArray && Array.isArray(o))) {
- return true;
- }
- return (type == "null" && o === null) ||
- (type == typeof o && o !== null) ||
- (type == "object" && o === Object(o)) ||
- objectToString.call(o).slice(8, -1).toLowerCase() == type;
-}
-/*\
- * Snap.format
- [ method ]
- **
- * Replaces construction of type `{<name>}` to the corresponding argument
- **
- - token (string) string to format
- - json (object) object which properties are used as a replacement
- = (string) formatted string
- > Usage
- | // this draws a rectangular shape equivalent to "M10,20h40v50h-40z"
- | paper.path(Snap.format("M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']}z", {
- | x: 10,
- | y: 20,
- | dim: {
- | width: 40,
- | height: 50,
- | "negative width": -40
- | }
- | }));
-\*/
-Snap.format = (function () {
- var tokenRegex = /\{([^\}]+)\}/g,
- objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g, // matches .xxxxx or ["xxxxx"] to run over object properties
- replacer = function (all, key, obj) {
- var res = obj;
- key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) {
- name = name || quotedName;
- if (res) {
- if (name in res) {
- res = res[name];
- }
- typeof res == "function" && isFunc && (res = res());
- }
- });
- res = (res == null || res == obj ? all : res) + "";
- return res;
- };
- return function (str, obj) {
- return Str(str).replace(tokenRegex, function (all, key) {
- return replacer(all, key, obj);
- });
- };
-})();
-function clone(obj) {
- if (typeof obj == "function" || Object(obj) !== obj) {
- return obj;
- }
- var res = new obj.constructor;
- for (var key in obj) if (obj[has](key)) {
- res[key] = clone(obj[key]);
- }
- return res;
-}
-Snap._.clone = clone;
-function repush(array, item) {
- for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) {
- return array.push(array.splice(i, 1)[0]);
- }
-}
-function cacher(f, scope, postprocessor) {
- function newf() {
- var arg = Array.prototype.slice.call(arguments, 0),
- args = arg.join("\u2400"),
- cache = newf.cache = newf.cache || {},
- count = newf.count = newf.count || [];
- if (cache[has](args)) {
- repush(count, args);
- return postprocessor ? postprocessor(cache[args]) : cache[args];
- }
- count.length >= 1e3 && delete cache[count.shift()];
- count.push(args);
- cache[args] = f.apply(scope, arg);
- return postprocessor ? postprocessor(cache[args]) : cache[args];
- }
- return newf;
-}
-Snap._.cacher = cacher;
-function angle(x1, y1, x2, y2, x3, y3) {
- if (x3 == null) {
- var x = x1 - x2,
- y = y1 - y2;
- if (!x && !y) {
- return 0;
- }
- return (180 + math.atan2(-y, -x) * 180 / PI + 360) % 360;
- } else {
- return angle(x1, y1, x3, y3) - angle(x2, y2, x3, y3);
- }
-}
-function rad(deg) {
- return deg % 360 * PI / 180;
-}
-function deg(rad) {
- return rad * 180 / PI % 360;
-}
-function x_y() {
- return this.x + S + this.y;
-}
-function x_y_w_h() {
- return this.x + S + this.y + S + this.width + " \xd7 " + this.height;
-}
-
-/*\
- * Snap.rad
- [ method ]
- **
- * Transform angle to radians
- - deg (number) angle in degrees
- = (number) angle in radians
-\*/
-Snap.rad = rad;
-/*\
- * Snap.deg
- [ method ]
- **
- * Transform angle to degrees
- - rad (number) angle in radians
- = (number) angle in degrees
-\*/
-Snap.deg = deg;
-/*\
- * Snap.sin
- [ method ]
- **
- * Equivalent to `Math.sin()` only works with degrees, not radians.
- - angle (number) angle in degrees
- = (number) sin
-\*/
-Snap.sin = function (angle) {
- return math.sin(Snap.rad(angle));
-};
-/*\
- * Snap.tan
- [ method ]
- **
- * Equivalent to `Math.tan()` only works with degrees, not radians.
- - angle (number) angle in degrees
- = (number) tan
-\*/
-Snap.tan = function (angle) {
- return math.tan(Snap.rad(angle));
-};
-/*\
- * Snap.cos
- [ method ]
- **
- * Equivalent to `Math.cos()` only works with degrees, not radians.
- - angle (number) angle in degrees
- = (number) cos
-\*/
-Snap.cos = function (angle) {
- return math.cos(Snap.rad(angle));
-};
-/*\
- * Snap.asin
- [ method ]
- **
- * Equivalent to `Math.asin()` only works with degrees, not radians.
- - num (number) value
- = (number) asin in degrees
-\*/
-Snap.asin = function (num) {
- return Snap.deg(math.asin(num));
-};
-/*\
- * Snap.acos
- [ method ]
- **
- * Equivalent to `Math.acos()` only works with degrees, not radians.
- - num (number) value
- = (number) acos in degrees
-\*/
-Snap.acos = function (num) {
- return Snap.deg(math.acos(num));
-};
-/*\
- * Snap.atan
- [ method ]
- **
- * Equivalent to `Math.atan()` only works with degrees, not radians.
- - num (number) value
- = (number) atan in degrees
-\*/
-Snap.atan = function (num) {
- return Snap.deg(math.atan(num));
-};
-/*\
- * Snap.atan2
- [ method ]
- **
- * Equivalent to `Math.atan2()` only works with degrees, not radians.
- - num (number) value
- = (number) atan2 in degrees
-\*/
-Snap.atan2 = function (num) {
- return Snap.deg(math.atan2(num));
-};
-/*\
- * Snap.angle
- [ method ]
- **
- * Returns an angle between two or three points
- > Parameters
- - x1 (number) x coord of first point
- - y1 (number) y coord of first point
- - x2 (number) x coord of second point
- - y2 (number) y coord of second point
- - x3 (number) #optional x coord of third point
- - y3 (number) #optional y coord of third point
- = (number) angle in degrees
-\*/
-Snap.angle = angle;
-/*\
- * Snap.len
- [ method ]
- **
- * Returns distance between two points
- > Parameters
- - x1 (number) x coord of first point
- - y1 (number) y coord of first point
- - x2 (number) x coord of second point
- - y2 (number) y coord of second point
- = (number) distance
-\*/
-Snap.len = function (x1, y1, x2, y2) {
- return Math.sqrt(Snap.len2(x1, y1, x2, y2));
-};
-/*\
- * Snap.len2
- [ method ]
- **
- * Returns squared distance between two points
- > Parameters
- - x1 (number) x coord of first point
- - y1 (number) y coord of first point
- - x2 (number) x coord of second point
- - y2 (number) y coord of second point
- = (number) distance
-\*/
-Snap.len2 = function (x1, y1, x2, y2) {
- return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
-};
-/*\
- * Snap.closestPoint
- [ method ]
- **
- * Returns closest point to a given one on a given path.
- > Parameters
- - path (Element) path element
- - x (number) x coord of a point
- - y (number) y coord of a point
- = (object) in format
- {
- x (number) x coord of the point on the path
- y (number) y coord of the point on the path
- length (number) length of the path to the point
- distance (number) distance from the given point to the path
- }
-\*/
-// Copied from http://bl.ocks.org/mbostock/8027637
-Snap.closestPoint = function (path, x, y) {
- function distance2(p) {
- var dx = p.x - x,
- dy = p.y - y;
- return dx * dx + dy * dy;
- }
- var pathNode = path.node,
- pathLength = pathNode.getTotalLength(),
- precision = pathLength / pathNode.pathSegList.numberOfItems * .125,
- best,
- bestLength,
- bestDistance = Infinity;
-
- // linear scan for coarse approximation
- for (var scan, scanLength = 0, scanDistance; scanLength <= pathLength; scanLength += precision) {
- if ((scanDistance = distance2(scan = pathNode.getPointAtLength(scanLength))) < bestDistance) {
- best = scan, bestLength = scanLength, bestDistance = scanDistance;
- }
- }
-
- // binary search for precise estimate
- precision *= .5;
- while (precision > .5) {
- var before,
- after,
- beforeLength,
- afterLength,
- beforeDistance,
- afterDistance;
- if ((beforeLength = bestLength - precision) >= 0 && (beforeDistance = distance2(before = pathNode.getPointAtLength(beforeLength))) < bestDistance) {
- best = before, bestLength = beforeLength, bestDistance = beforeDistance;
- } else if ((afterLength = bestLength + precision) <= pathLength && (afterDistance = distance2(after = pathNode.getPointAtLength(afterLength))) < bestDistance) {
- best = after, bestLength = afterLength, bestDistance = afterDistance;
- } else {
- precision *= .5;
- }
- }
-
- best = {
- x: best.x,
- y: best.y,
- length: bestLength,
- distance: Math.sqrt(bestDistance)
- };
- return best;
-}
-/*\
- * Snap.is
- [ method ]
- **
- * Handy replacement for the `typeof` operator
- - o (…) any object or primitive
- - type (string) name of the type, e.g., `string`, `function`, `number`, etc.
- = (boolean) `true` if given value is of given type
-\*/
-Snap.is = is;
-/*\
- * Snap.snapTo
- [ method ]
- **
- * Snaps given value to given grid
- - values (array|number) given array of values or step of the grid
- - value (number) value to adjust
- - tolerance (number) #optional maximum distance to the target value that would trigger the snap. Default is `10`.
- = (number) adjusted value
-\*/
-Snap.snapTo = function (values, value, tolerance) {
- tolerance = is(tolerance, "finite") ? tolerance : 10;
- if (is(values, "array")) {
- var i = values.length;
- while (i--) if (abs(values[i] - value) <= tolerance) {
- return values[i];
- }
- } else {
- values = +values;
- var rem = value % values;
- if (rem < tolerance) {
- return value - rem;
- }
- if (rem > values - tolerance) {
- return value - rem + values;
- }
- }
- return value;
-};
-// Colour
-/*\
- * Snap.getRGB
- [ method ]
- **
- * Parses color string as RGB object
- - color (string) color string in one of the following formats:
- # <ul>
- # <li>Color name (<code>red</code>, <code>green</code>, <code>cornflowerblue</code>, etc)</li>
- # <li>#••• — shortened HTML color: (<code>#000</code>, <code>#fc0</code>, etc.)</li>
- # <li>#•••••• — full length HTML color: (<code>#000000</code>, <code>#bd2300</code>)</li>
- # <li>rgb(•••, •••, •••) — red, green and blue channels values: (<code>rgb(200,&nbsp;100,&nbsp;0)</code>)</li>
- # <li>rgba(•••, •••, •••, •••) — also with opacity</li>
- # <li>rgb(•••%, •••%, •••%) — same as above, but in %: (<code>rgb(100%,&nbsp;175%,&nbsp;0%)</code>)</li>
- # <li>rgba(•••%, •••%, •••%, •••%) — also with opacity</li>
- # <li>hsb(•••, •••, •••) — hue, saturation and brightness values: (<code>hsb(0.5,&nbsp;0.25,&nbsp;1)</code>)</li>
- # <li>hsba(•••, •••, •••, •••) — also with opacity</li>
- # <li>hsb(•••%, •••%, •••%) — same as above, but in %</li>
- # <li>hsba(•••%, •••%, •••%, •••%) — also with opacity</li>
- # <li>hsl(•••, •••, •••) — hue, saturation and luminosity values: (<code>hsb(0.5,&nbsp;0.25,&nbsp;0.5)</code>)</li>
- # <li>hsla(•••, •••, •••, •••) — also with opacity</li>
- # <li>hsl(•••%, •••%, •••%) — same as above, but in %</li>
- # <li>hsla(•••%, •••%, •••%, •••%) — also with opacity</li>
- # </ul>
- * Note that `%` can be used any time: `rgb(20%, 255, 50%)`.
- = (object) RGB object in the following format:
- o {
- o r (number) red,
- o g (number) green,
- o b (number) blue,
- o hex (string) color in HTML/CSS format: #••••••,
- o error (boolean) true if string can't be parsed
- o }
-\*/
-Snap.getRGB = cacher(function (colour) {
- if (!colour || !!((colour = Str(colour)).indexOf("-") + 1)) {
- return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: rgbtoString};
- }
- if (colour == "none") {
- return {r: -1, g: -1, b: -1, hex: "none", toString: rgbtoString};
- }
- !(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour));
- if (!colour) {
- return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: rgbtoString};
- }
- var res,
- red,
- green,
- blue,
- opacity,
- t,
- values,
- rgb = colour.match(colourRegExp);
- if (rgb) {
- if (rgb[2]) {
- blue = toInt(rgb[2].substring(5), 16);
- green = toInt(rgb[2].substring(3, 5), 16);
- red = toInt(rgb[2].substring(1, 3), 16);
- }
- if (rgb[3]) {
- blue = toInt((t = rgb[3].charAt(3)) + t, 16);
- green = toInt((t = rgb[3].charAt(2)) + t, 16);
- red = toInt((t = rgb[3].charAt(1)) + t, 16);
- }
- if (rgb[4]) {
- values = rgb[4].split(commaSpaces);
- red = toFloat(values[0]);
- values[0].slice(-1) == "%" && (red *= 2.55);
- green = toFloat(values[1]);
- values[1].slice(-1) == "%" && (green *= 2.55);
- blue = toFloat(values[2]);
- values[2].slice(-1) == "%" && (blue *= 2.55);
- rgb[1].toLowerCase().slice(0, 4) == "rgba" && (opacity = toFloat(values[3]));
- values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
- }
- if (rgb[5]) {
- values = rgb[5].split(commaSpaces);
- red = toFloat(values[0]);
- values[0].slice(-1) == "%" && (red /= 100);
- green = toFloat(values[1]);
- values[1].slice(-1) == "%" && (green /= 100);
- blue = toFloat(values[2]);
- values[2].slice(-1) == "%" && (blue /= 100);
- (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360);
- rgb[1].toLowerCase().slice(0, 4) == "hsba" && (opacity = toFloat(values[3]));
- values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
- return Snap.hsb2rgb(red, green, blue, opacity);
- }
- if (rgb[6]) {
- values = rgb[6].split(commaSpaces);
- red = toFloat(values[0]);
- values[0].slice(-1) == "%" && (red /= 100);
- green = toFloat(values[1]);
- values[1].slice(-1) == "%" && (green /= 100);
- blue = toFloat(values[2]);
- values[2].slice(-1) == "%" && (blue /= 100);
- (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360);
- rgb[1].toLowerCase().slice(0, 4) == "hsla" && (opacity = toFloat(values[3]));
- values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
- return Snap.hsl2rgb(red, green, blue, opacity);
- }
- red = mmin(math.round(red), 255);
- green = mmin(math.round(green), 255);
- blue = mmin(math.round(blue), 255);
- opacity = mmin(mmax(opacity, 0), 1);
- rgb = {r: red, g: green, b: blue, toString: rgbtoString};
- rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1);
- rgb.opacity = is(opacity, "finite") ? opacity : 1;
- return rgb;
- }
- return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: rgbtoString};
-}, Snap);
-/*\
- * Snap.hsb
- [ method ]
- **
- * Converts HSB values to a hex representation of the color
- - h (number) hue
- - s (number) saturation
- - b (number) value or brightness
- = (string) hex representation of the color
-\*/
-Snap.hsb = cacher(function (h, s, b) {
- return Snap.hsb2rgb(h, s, b).hex;
-});
-/*\
- * Snap.hsl
- [ method ]
- **
- * Converts HSL values to a hex representation of the color
- - h (number) hue
- - s (number) saturation
- - l (number) luminosity
- = (string) hex representation of the color
-\*/
-Snap.hsl = cacher(function (h, s, l) {
- return Snap.hsl2rgb(h, s, l).hex;
-});
-/*\
- * Snap.rgb
- [ method ]
- **
- * Converts RGB values to a hex representation of the color
- - r (number) red
- - g (number) green
- - b (number) blue
- = (string) hex representation of the color
-\*/
-Snap.rgb = cacher(function (r, g, b, o) {
- if (is(o, "finite")) {
- var round = math.round;
- return "rgba(" + [round(r), round(g), round(b), +o.toFixed(2)] + ")";
- }
- return "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1);
-});
-var toHex = function (color) {
- var i = glob.doc.getElementsByTagName("head")[0] || glob.doc.getElementsByTagName("svg")[0],
- red = "rgb(255, 0, 0)";
- toHex = cacher(function (color) {
- if (color.toLowerCase() == "red") {
- return red;
- }
- i.style.color = red;
- i.style.color = color;
- var out = glob.doc.defaultView.getComputedStyle(i, E).getPropertyValue("color");
- return out == red ? null : out;
- });
- return toHex(color);
-},
-hsbtoString = function () {
- return "hsb(" + [this.h, this.s, this.b] + ")";
-},
-hsltoString = function () {
- return "hsl(" + [this.h, this.s, this.l] + ")";
-},
-rgbtoString = function () {
- return this.opacity == 1 || this.opacity == null ?
- this.hex :
- "rgba(" + [this.r, this.g, this.b, this.opacity] + ")";
-},
-prepareRGB = function (r, g, b) {
- if (g == null && is(r, "object") && "r" in r && "g" in r && "b" in r) {
- b = r.b;
- g = r.g;
- r = r.r;
- }
- if (g == null && is(r, string)) {
- var clr = Snap.getRGB(r);
- r = clr.r;
- g = clr.g;
- b = clr.b;
- }
- if (r > 1 || g > 1 || b > 1) {
- r /= 255;
- g /= 255;
- b /= 255;
- }
-
- return [r, g, b];
-},
-packageRGB = function (r, g, b, o) {
- r = math.round(r * 255);
- g = math.round(g * 255);
- b = math.round(b * 255);
- var rgb = {
- r: r,
- g: g,
- b: b,
- opacity: is(o, "finite") ? o : 1,
- hex: Snap.rgb(r, g, b),
- toString: rgbtoString
- };
- is(o, "finite") && (rgb.opacity = o);
- return rgb;
-};
-/*\
- * Snap.color
- [ method ]
- **
- * Parses the color string and returns an object featuring the color's component values
- - clr (string) color string in one of the supported formats (see @Snap.getRGB)
- = (object) Combined RGB/HSB object in the following format:
- o {
- o r (number) red,
- o g (number) green,
- o b (number) blue,
- o hex (string) color in HTML/CSS format: #••••••,
- o error (boolean) `true` if string can't be parsed,
- o h (number) hue,
- o s (number) saturation,
- o v (number) value (brightness),
- o l (number) lightness
- o }
-\*/
-Snap.color = function (clr) {
- var rgb;
- if (is(clr, "object") && "h" in clr && "s" in clr && "b" in clr) {
- rgb = Snap.hsb2rgb(clr);
- clr.r = rgb.r;
- clr.g = rgb.g;
- clr.b = rgb.b;
- clr.opacity = 1;
- clr.hex = rgb.hex;
- } else if (is(clr, "object") && "h" in clr && "s" in clr && "l" in clr) {
- rgb = Snap.hsl2rgb(clr);
- clr.r = rgb.r;
- clr.g = rgb.g;
- clr.b = rgb.b;
- clr.opacity = 1;
- clr.hex = rgb.hex;
- } else {
- if (is(clr, "string")) {
- clr = Snap.getRGB(clr);
- }
- if (is(clr, "object") && "r" in clr && "g" in clr && "b" in clr && !("error" in clr)) {
- rgb = Snap.rgb2hsl(clr);
- clr.h = rgb.h;
- clr.s = rgb.s;
- clr.l = rgb.l;
- rgb = Snap.rgb2hsb(clr);
- clr.v = rgb.b;
- } else {
- clr = {hex: "none"};
- clr.r = clr.g = clr.b = clr.h = clr.s = clr.v = clr.l = -1;
- clr.error = 1;
- }
- }
- clr.toString = rgbtoString;
- return clr;
-};
-/*\
- * Snap.hsb2rgb
- [ method ]
- **
- * Converts HSB values to an RGB object
- - h (number) hue
- - s (number) saturation
- - v (number) value or brightness
- = (object) RGB object in the following format:
- o {
- o r (number) red,
- o g (number) green,
- o b (number) blue,
- o hex (string) color in HTML/CSS format: #••••••
- o }
-\*/
-Snap.hsb2rgb = function (h, s, v, o) {
- if (is(h, "object") && "h" in h && "s" in h && "b" in h) {
- v = h.b;
- s = h.s;
- o = h.o;
- h = h.h;
- }
- h *= 360;
- var R, G, B, X, C;
- h = (h % 360) / 60;
- C = v * s;
- X = C * (1 - abs(h % 2 - 1));
- R = G = B = v - C;
-
- h = ~~h;
- R += [C, X, 0, 0, X, C][h];
- G += [X, C, C, X, 0, 0][h];
- B += [0, 0, X, C, C, X][h];
- return packageRGB(R, G, B, o);
-};
-/*\
- * Snap.hsl2rgb
- [ method ]
- **
- * Converts HSL values to an RGB object
- - h (number) hue
- - s (number) saturation
- - l (number) luminosity
- = (object) RGB object in the following format:
- o {
- o r (number) red,
- o g (number) green,
- o b (number) blue,
- o hex (string) color in HTML/CSS format: #••••••
- o }
-\*/
-Snap.hsl2rgb = function (h, s, l, o) {
- if (is(h, "object") && "h" in h && "s" in h && "l" in h) {
- l = h.l;
- s = h.s;
- h = h.h;
- }
- if (h > 1 || s > 1 || l > 1) {
- h /= 360;
- s /= 100;
- l /= 100;
- }
- h *= 360;
- var R, G, B, X, C;
- h = (h % 360) / 60;
- C = 2 * s * (l < .5 ? l : 1 - l);
- X = C * (1 - abs(h % 2 - 1));
- R = G = B = l - C / 2;
-
- h = ~~h;
- R += [C, X, 0, 0, X, C][h];
- G += [X, C, C, X, 0, 0][h];
- B += [0, 0, X, C, C, X][h];
- return packageRGB(R, G, B, o);
-};
-/*\
- * Snap.rgb2hsb
- [ method ]
- **
- * Converts RGB values to an HSB object
- - r (number) red
- - g (number) green
- - b (number) blue
- = (object) HSB object in the following format:
- o {
- o h (number) hue,
- o s (number) saturation,
- o b (number) brightness
- o }
-\*/
-Snap.rgb2hsb = function (r, g, b) {
- b = prepareRGB(r, g, b);
- r = b[0];
- g = b[1];
- b = b[2];
-
- var H, S, V, C;
- V = mmax(r, g, b);
- C = V - mmin(r, g, b);
- H = (C == 0 ? null :
- V == r ? (g - b) / C :
- V == g ? (b - r) / C + 2 :
- (r - g) / C + 4
- );
- H = ((H + 360) % 6) * 60 / 360;
- S = C == 0 ? 0 : C / V;
- return {h: H, s: S, b: V, toString: hsbtoString};
-};
-/*\
- * Snap.rgb2hsl
- [ method ]
- **
- * Converts RGB values to an HSL object
- - r (number) red
- - g (number) green
- - b (number) blue
- = (object) HSL object in the following format:
- o {
- o h (number) hue,
- o s (number) saturation,
- o l (number) luminosity
- o }
-\*/
-Snap.rgb2hsl = function (r, g, b) {
- b = prepareRGB(r, g, b);
- r = b[0];
- g = b[1];
- b = b[2];
-
- var H, S, L, M, m, C;
- M = mmax(r, g, b);
- m = mmin(r, g, b);
- C = M - m;
- H = (C == 0 ? null :
- M == r ? (g - b) / C :
- M == g ? (b - r) / C + 2 :
- (r - g) / C + 4);
- H = ((H + 360) % 6) * 60 / 360;
- L = (M + m) / 2;
- S = (C == 0 ? 0 :
- L < .5 ? C / (2 * L) :
- C / (2 - 2 * L));
- return {h: H, s: S, l: L, toString: hsltoString};
-};
-
-// Transformations
-/*\
- * Snap.parsePathString
- [ method ]
- **
- * Utility method
- **
- * Parses given path string into an array of arrays of path segments
- - pathString (string|array) path string or array of segments (in the last case it is returned straight away)
- = (array) array of segments
-\*/
-Snap.parsePathString = function (pathString) {
- if (!pathString) {
- return null;
- }
- var pth = Snap.path(pathString);
- if (pth.arr) {
- return Snap.path.clone(pth.arr);
- }
-
- var paramCounts = {a: 7, c: 6, o: 2, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, u: 3, z: 0},
- data = [];
- if (is(pathString, "array") && is(pathString[0], "array")) { // rough assumption
- data = Snap.path.clone(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 == "o" && params.length == 1) {
- data.push([b, params[0]]);
- }
- 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 = Snap.path.toString;
- pth.arr = Snap.path.clone(data);
- return data;
-};
-/*\
- * Snap.parseTransformString
- [ method ]
- **
- * Utility method
- **
- * Parses given transform string into an array of transformations
- - TString (string|array) transform string or array of transformations (in the last case it is returned straight away)
- = (array) array of transformations
-\*/
-var parseTransformString = Snap.parseTransformString = function (TString) {
- if (!TString) {
- return null;
- }
- var paramCounts = {r: 3, s: 4, t: 2, m: 6},
- data = [];
- if (is(TString, "array") && is(TString[0], "array")) { // rough assumption
- data = Snap.path.clone(TString);
- }
- if (!data.length) {
- Str(TString).replace(tCommand, function (a, b, c) {
- var params = [],
- name = b.toLowerCase();
- c.replace(pathValues, function (a, b) {
- b && params.push(+b);
- });
- data.push([b].concat(params));
- });
- }
- data.toString = Snap.path.toString;
- return data;
-};
-function svgTransform2string(tstr) {
- var res = [];
- tstr = tstr.replace(/(?:^|\s)(\w+)\(([^)]+)\)/g, function (all, name, params) {
- params = params.split(/\s*,\s*|\s+/);
- if (name == "rotate" && params.length == 1) {
- params.push(0, 0);
- }
- if (name == "scale") {
- if (params.length > 2) {
- params = params.slice(0, 2);
- } else if (params.length == 2) {
- params.push(0, 0);
- }
- if (params.length == 1) {
- params.push(params[0], 0, 0);
- }
- }
- if (name == "skewX") {
- res.push(["m", 1, 0, math.tan(rad(params[0])), 1, 0, 0]);
- } else if (name == "skewY") {
- res.push(["m", 1, math.tan(rad(params[0])), 0, 1, 0, 0]);
- } else {
- res.push([name.charAt(0)].concat(params));
- }
- return all;
- });
- return res;
-}
-Snap._.svgTransform2string = svgTransform2string;
-Snap._.rgTransform = /^[a-z][\s]*-?\.?\d/i;
-function transform2matrix(tstr, bbox) {
- var tdata = parseTransformString(tstr),
- m = new Snap.Matrix;
- if (tdata) {
- for (var i = 0, ii = tdata.length; i < ii; i++) {
- var t = tdata[i],
- tlen = t.length,
- command = Str(t[0]).toLowerCase(),
- absolute = t[0] != command,
- inver = absolute ? m.invert() : 0,
- x1,
- y1,
- x2,
- y2,
- bb;
- if (command == "t" && tlen == 2){
- m.translate(t[1], 0);
- } else if (command == "t" && tlen == 3) {
- if (absolute) {
- x1 = inver.x(0, 0);
- y1 = inver.y(0, 0);
- x2 = inver.x(t[1], t[2]);
- y2 = inver.y(t[1], t[2]);
- m.translate(x2 - x1, y2 - y1);
- } else {
- m.translate(t[1], t[2]);
- }
- } else if (command == "r") {
- if (tlen == 2) {
- bb = bb || bbox;
- m.rotate(t[1], bb.x + bb.width / 2, bb.y + bb.height / 2);
- } else if (tlen == 4) {
- if (absolute) {
- x2 = inver.x(t[2], t[3]);
- y2 = inver.y(t[2], t[3]);
- m.rotate(t[1], x2, y2);
- } else {
- m.rotate(t[1], t[2], t[3]);
- }
- }
- } else if (command == "s") {
- if (tlen == 2 || tlen == 3) {
- bb = bb || bbox;
- m.scale(t[1], t[tlen - 1], bb.x + bb.width / 2, bb.y + bb.height / 2);
- } else if (tlen == 4) {
- if (absolute) {
- x2 = inver.x(t[2], t[3]);
- y2 = inver.y(t[2], t[3]);
- m.scale(t[1], t[1], x2, y2);
- } else {
- m.scale(t[1], t[1], t[2], t[3]);
- }
- } else if (tlen == 5) {
- if (absolute) {
- x2 = inver.x(t[3], t[4]);
- y2 = inver.y(t[3], t[4]);
- m.scale(t[1], t[2], x2, y2);
- } else {
- m.scale(t[1], t[2], t[3], t[4]);
- }
- }
- } else if (command == "m" && tlen == 7) {
- m.add(t[1], t[2], t[3], t[4], t[5], t[6]);
- }
- }
- }
- return m;
-}
-Snap._.transform2matrix = transform2matrix;
-Snap._unit2px = unit2px;
-var contains = glob.doc.contains || glob.doc.compareDocumentPosition ?
- function (a, b) {
- var adown = a.nodeType == 9 ? a.documentElement : a,
- bup = b && b.parentNode;
- return a == bup || !!(bup && bup.nodeType == 1 && (
- adown.contains ?
- adown.contains(bup) :
- a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16
- ));
- } :
- function (a, b) {
- if (b) {
- while (b) {
- b = b.parentNode;
- if (b == a) {
- return true;
- }
- }
- }
- return false;
- };
-function getSomeDefs(el) {
- var p = (el.node.ownerSVGElement && wrap(el.node.ownerSVGElement)) ||
- (el.node.parentNode && wrap(el.node.parentNode)) ||
- Snap.select("svg") ||
- Snap(0, 0),
- pdefs = p.select("defs"),
- defs = pdefs == null ? false : pdefs.node;
- if (!defs) {
- defs = make("defs", p.node).node;
- }
- return defs;
-}
-function getSomeSVG(el) {
- return el.node.ownerSVGElement && wrap(el.node.ownerSVGElement) || Snap.select("svg");
-}
-Snap._.getSomeDefs = getSomeDefs;
-Snap._.getSomeSVG = getSomeSVG;
-function unit2px(el, name, value) {
- var svg = getSomeSVG(el).node,
- out = {},
- mgr = svg.querySelector(".svg---mgr");
- if (!mgr) {
- mgr = $("rect");
- $(mgr, {x: -9e9, y: -9e9, width: 10, height: 10, "class": "svg---mgr", fill: "none"});
- svg.appendChild(mgr);
- }
- function getW(val) {
- if (val == null) {
- return E;
- }
- if (val == +val) {
- return val;
- }
- $(mgr, {width: val});
- try {
- return mgr.getBBox().width;
- } catch (e) {
- return 0;
- }
- }
- function getH(val) {
- if (val == null) {
- return E;
- }
- if (val == +val) {
- return val;
- }
- $(mgr, {height: val});
- try {
- return mgr.getBBox().height;
- } catch (e) {
- return 0;
- }
- }
- function set(nam, f) {
- if (name == null) {
- out[nam] = f(el.attr(nam) || 0);
- } else if (nam == name) {
- out = f(value == null ? el.attr(nam) || 0 : value);
- }
- }
- switch (el.type) {
- case "rect":
- set("rx", getW);
- set("ry", getH);
- case "image":
- set("width", getW);
- set("height", getH);
- case "text":
- set("x", getW);
- set("y", getH);
- break;
- case "circle":
- set("cx", getW);
- set("cy", getH);
- set("r", getW);
- break;
- case "ellipse":
- set("cx", getW);
- set("cy", getH);
- set("rx", getW);
- set("ry", getH);
- 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:
- set(name, getW);
- }
- svg.removeChild(mgr);
- return out;
-}
-/*\
- * Snap.select
- [ method ]
- **
- * Wraps a DOM element specified by CSS selector as @Element
- - query (string) CSS selector of the element
- = (Element) the current element
-\*/
-Snap.select = function (query) {
- query = Str(query).replace(/([^\\]):/g, "$1\\:");
- return wrap(glob.doc.querySelector(query));
-};
-/*\
- * Snap.selectAll
- [ method ]
- **
- * Wraps DOM elements specified by CSS selector as set or array of @Element
- - query (string) CSS selector of the element
- = (Element) the current element
-\*/
-Snap.selectAll = function (query) {
- var nodelist = glob.doc.querySelectorAll(query),
- set = (Snap.set || Array)();
- for (var i = 0; i < nodelist.length; i++) {
- set.push(wrap(nodelist[i]));
- }
- return set;
-};
-
-function add2group(list) {
- if (!is(list, "array")) {
- list = Array.prototype.slice.call(arguments, 0);
- }
- var i = 0,
- j = 0,
- node = this.node;
- while (this[i]) delete this[i++];
- for (i = 0; i < list.length; i++) {
- if (list[i].type == "set") {
- list[i].forEach(function (el) {
- node.appendChild(el.node);
- });
- } else {
- node.appendChild(list[i].node);
- }
- }
- var children = node.childNodes;
- for (i = 0; i < children.length; i++) {
- this[j++] = wrap(children[i]);
- }
- return this;
-}
-// Hub garbage collector every 10s
-setInterval(function () {
- for (var key in hub) if (hub[has](key)) {
- var el = hub[key],
- node = el.node;
- if (el.type != "svg" && !node.ownerSVGElement || el.type == "svg" && (!node.parentNode || "ownerSVGElement" in node.parentNode && !node.ownerSVGElement)) {
- delete hub[key];
- }
- }
-}, 1e4);
-function Element(el) {
- if (el.snap in hub) {
- return hub[el.snap];
- }
- var svg;
- try {
- svg = el.ownerSVGElement;
- } catch(e) {}
- /*\
- * Element.node
- [ property (object) ]
- **
- * Gives you a reference to the DOM object, so you can assign event handlers or just mess around.
- > Usage
- | // draw a circle at coordinate 10,10 with radius of 10
- | var c = paper.circle(10, 10, 10);
- | c.node.onclick = function () {
- | c.attr("fill", "red");
- | };
- \*/
- this.node = el;
- if (svg) {
- this.paper = new Paper(svg);
- }
- /*\
- * Element.type
- [ property (string) ]
- **
- * SVG tag name of the given element.
- \*/
- this.type = el.tagName || el.nodeName;
- var id = this.id = ID(this);
- this.anims = {};
- this._ = {
- transform: []
- };
- el.snap = id;
- hub[id] = this;
- if (this.type == "g") {
- this.add = add2group;
- }
- if (this.type in {g: 1, mask: 1, pattern: 1, symbol: 1}) {
- for (var method in Paper.prototype) if (Paper.prototype[has](method)) {
- this[method] = Paper.prototype[method];
- }
- }
-}
- /*\
- * Element.attr
- [ method ]
- **
- * Gets or sets given attributes of the element.
- **
- - params (object) contains key-value pairs of attributes you want to set
- * or
- - param (string) name of the attribute
- = (Element) the current element
- * or
- = (string) value of attribute
- > Usage
- | el.attr({
- | fill: "#fc0",
- | stroke: "#000",
- | strokeWidth: 2, // CamelCase...
- | "fill-opacity": 0.5, // or dash-separated names
- | width: "*=2" // prefixed values
- | });
- | console.log(el.attr("fill")); // #fc0
- * Prefixed values in format `"+=10"` supported. All four operations
- * (`+`, `-`, `*` and `/`) could be used. Optionally you can use units for `+`
- * and `-`: `"+=2em"`.
- \*/
- Element.prototype.attr = function (params, value) {
- var el = this,
- node = el.node;
- if (!params) {
- if (node.nodeType != 1) {
- return {
- text: node.nodeValue
- };
- }
- var attr = node.attributes,
- out = {};
- for (var i = 0, ii = attr.length; i < ii; i++) {
- out[attr[i].nodeName] = attr[i].nodeValue;
- }
- return out;
- }
- if (is(params, "string")) {
- if (arguments.length > 1) {
- var json = {};
- json[params] = value;
- params = json;
- } else {
- return eve("snap.util.getattr." + params, el).firstDefined();
- }
- }
- for (var att in params) {
- if (params[has](att)) {
- eve("snap.util.attr." + att, el, params[att]);
- }
- }
- return el;
- };
-/*\
- * Snap.parse
- [ method ]
- **
- * Parses SVG fragment and converts it into a @Fragment
- **
- - svg (string) SVG string
- = (Fragment) the @Fragment
-\*/
-Snap.parse = function (svg) {
- var f = glob.doc.createDocumentFragment(),
- full = true,
- div = glob.doc.createElement("div");
- svg = Str(svg);
- if (!svg.match(/^\s*<\s*svg(?:\s|>)/)) {
- svg = "<svg>" + svg + "</svg>";
- full = false;
- }
- div.innerHTML = svg;
- svg = div.getElementsByTagName("svg")[0];
- if (svg) {
- if (full) {
- f = svg;
- } else {
- while (svg.firstChild) {
- f.appendChild(svg.firstChild);
- }
- }
- }
- return new Fragment(f);
-};
-function Fragment(frag) {
- this.node = frag;
-}
-/*\
- * Snap.fragment
- [ method ]
- **
- * Creates a DOM fragment from a given list of elements or strings
- **
- - varargs (…) SVG string
- = (Fragment) the @Fragment
-\*/
-Snap.fragment = function () {
- var args = Array.prototype.slice.call(arguments, 0),
- f = glob.doc.createDocumentFragment();
- for (var i = 0, ii = args.length; i < ii; i++) {
- var item = args[i];
- if (item.node && item.node.nodeType) {
- f.appendChild(item.node);
- }
- if (item.nodeType) {
- f.appendChild(item);
- }
- if (typeof item == "string") {
- f.appendChild(Snap.parse(item).node);
- }
- }
- return new Fragment(f);
-};
-
-function make(name, parent) {
- var res = $(name);
- parent.appendChild(res);
- var el = wrap(res);
- return el;
-}
-function Paper(w, h) {
- var res,
- desc,
- defs,
- proto = Paper.prototype;
- if (w && w.tagName == "svg") {
- if (w.snap in hub) {
- return hub[w.snap];
- }
- var doc = w.ownerDocument;
- res = new Element(w);
- desc = w.getElementsByTagName("desc")[0];
- defs = w.getElementsByTagName("defs")[0];
- if (!desc) {
- desc = $("desc");
- desc.appendChild(doc.createTextNode("Created with Snap"));
- res.node.appendChild(desc);
- }
- if (!defs) {
- defs = $("defs");
- res.node.appendChild(defs);
- }
- res.defs = defs;
- for (var key in proto) if (proto[has](key)) {
- res[key] = proto[key];
- }
- res.paper = res.root = res;
- } else {
- res = make("svg", glob.doc.body);
- $(res.node, {
- height: h,
- version: 1.1,
- width: w,
- xmlns: xmlns
- });
- }
- return res;
-}
-function wrap(dom) {
- if (!dom) {
- return dom;
- }
- if (dom instanceof Element || dom instanceof Fragment) {
- return dom;
- }
- if (dom.tagName && dom.tagName.toLowerCase() == "svg") {
- return new Paper(dom);
- }
- if (dom.tagName && dom.tagName.toLowerCase() == "object" && dom.type == "image/svg+xml") {
- return new Paper(dom.contentDocument.getElementsByTagName("svg")[0]);
- }
- return new Element(dom);
-}
-
-Snap._.make = make;
-Snap._.wrap = wrap;
-/*\
- * Paper.el
- [ method ]
- **
- * Creates an element on paper with a given name and no attributes
- **
- - name (string) tag name
- - attr (object) attributes
- = (Element) the current element
- > Usage
- | var c = paper.circle(10, 10, 10); // is the same as...
- | var c = paper.el("circle").attr({
- | cx: 10,
- | cy: 10,
- | r: 10
- | });
- | // and the same as
- | var c = paper.el("circle", {
- | cx: 10,
- | cy: 10,
- | r: 10
- | });
-\*/
-Paper.prototype.el = function (name, attr) {
- var el = make(name, this.node);
- attr && el.attr(attr);
- return el;
-};
-/*\
- * Element.children
- [ method ]
- **
- * Returns array of all the children of the element.
- = (array) array of Elements
-\*/
-Element.prototype.children = function () {
- var out = [],
- ch = this.node.childNodes;
- for (var i = 0, ii = ch.length; i < ii; i++) {
- out[i] = Snap(ch[i]);
- }
- return out;
-};
-function jsonFiller(root, o) {
- for (var i = 0, ii = root.length; i < ii; i++) {
- var item = {
- type: root[i].type,
- attr: root[i].attr()
- },
- children = root[i].children();
- o.push(item);
- if (children.length) {
- jsonFiller(children, item.childNodes = []);
- }
- }
-}
-/*\
- * Element.toJSON
- [ method ]
- **
- * Returns object representation of the given element and all its children.
- = (object) in format
- o {
- o type (string) this.type,
- o attr (object) attributes map,
- o childNodes (array) optional array of children in the same format
- o }
-\*/
-Element.prototype.toJSON = function () {
- var out = [];
- jsonFiller([this], out);
- return out[0];
-};
-// default
-eve.on("snap.util.getattr", function () {
- var att = eve.nt();
- att = att.substring(att.lastIndexOf(".") + 1);
- var css = att.replace(/[A-Z]/g, function (letter) {
- return "-" + letter.toLowerCase();
- });
- if (cssAttr[has](css)) {
- return this.node.ownerDocument.defaultView.getComputedStyle(this.node, null).getPropertyValue(css);
- } else {
- return $(this.node, att);
- }
-});
-var cssAttr = {
- "alignment-baseline": 0,
- "baseline-shift": 0,
- "clip": 0,
- "clip-path": 0,
- "clip-rule": 0,
- "color": 0,
- "color-interpolation": 0,
- "color-interpolation-filters": 0,
- "color-profile": 0,
- "color-rendering": 0,
- "cursor": 0,
- "direction": 0,
- "display": 0,
- "dominant-baseline": 0,
- "enable-background": 0,
- "fill": 0,
- "fill-opacity": 0,
- "fill-rule": 0,
- "filter": 0,
- "flood-color": 0,
- "flood-opacity": 0,
- "font": 0,
- "font-family": 0,
- "font-size": 0,
- "font-size-adjust": 0,
- "font-stretch": 0,
- "font-style": 0,
- "font-variant": 0,
- "font-weight": 0,
- "glyph-orientation-horizontal": 0,
- "glyph-orientation-vertical": 0,
- "image-rendering": 0,
- "kerning": 0,
- "letter-spacing": 0,
- "lighting-color": 0,
- "marker": 0,
- "marker-end": 0,
- "marker-mid": 0,
- "marker-start": 0,
- "mask": 0,
- "opacity": 0,
- "overflow": 0,
- "pointer-events": 0,
- "shape-rendering": 0,
- "stop-color": 0,
- "stop-opacity": 0,
- "stroke": 0,
- "stroke-dasharray": 0,
- "stroke-dashoffset": 0,
- "stroke-linecap": 0,
- "stroke-linejoin": 0,
- "stroke-miterlimit": 0,
- "stroke-opacity": 0,
- "stroke-width": 0,
- "text-anchor": 0,
- "text-decoration": 0,
- "text-rendering": 0,
- "unicode-bidi": 0,
- "visibility": 0,
- "word-spacing": 0,
- "writing-mode": 0
-};
-
-eve.on("snap.util.attr", function (value) {
- var att = eve.nt(),
- attr = {};
- att = att.substring(att.lastIndexOf(".") + 1);
- attr[att] = value;
- var style = att.replace(/-(\w)/gi, function (all, letter) {
- return letter.toUpperCase();
- }),
- css = att.replace(/[A-Z]/g, function (letter) {
- return "-" + letter.toLowerCase();
- });
- if (cssAttr[has](css)) {
- this.node.style[style] = value == null ? E : value;
- } else {
- $(this.node, attr);
- }
-});
-(function (proto) {}(Paper.prototype));
-
-// simple ajax
-/*\
- * Snap.ajax
- [ method ]
- **
- * Simple implementation of Ajax
- **
- - url (string) URL
- - postData (object|string) data for post request
- - callback (function) callback
- - scope (object) #optional scope of callback
- * or
- - url (string) URL
- - callback (function) callback
- - scope (object) #optional scope of callback
- = (XMLHttpRequest) the XMLHttpRequest object, just in case
-\*/
-Snap.ajax = function (url, postData, callback, scope){
- var req = new XMLHttpRequest,
- id = ID();
- if (req) {
- if (is(postData, "function")) {
- scope = callback;
- callback = postData;
- postData = null;
- } else if (is(postData, "object")) {
- var pd = [];
- for (var key in postData) if (postData.hasOwnProperty(key)) {
- pd.push(encodeURIComponent(key) + "=" + encodeURIComponent(postData[key]));
- }
- postData = pd.join("&");
- }
- req.open((postData ? "POST" : "GET"), url, true);
- if (postData) {
- req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
- req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
- }
- if (callback) {
- eve.once("snap.ajax." + id + ".0", callback);
- eve.once("snap.ajax." + id + ".200", callback);
- eve.once("snap.ajax." + id + ".304", callback);
- }
- req.onreadystatechange = function() {
- if (req.readyState != 4) return;
- eve("snap.ajax." + id + "." + req.status, scope, req);
- };
- if (req.readyState == 4) {
- return req;
- }
- req.send(postData);
- return req;
- }
-};
-/*\
- * Snap.load
- [ method ]
- **
- * Loads external SVG file as a @Fragment (see @Snap.ajax for more advanced AJAX)
- **
- - url (string) URL
- - callback (function) callback
- - scope (object) #optional scope of callback
-\*/
-Snap.load = function (url, callback, scope) {
- Snap.ajax(url, function (req) {
- var f = Snap.parse(req.responseText);
- scope ? callback.call(scope, f) : callback(f);
- });
-};
-var getOffset = function (elem) {
- var box = elem.getBoundingClientRect(),
- doc = elem.ownerDocument,
- body = doc.body,
- docElem = doc.documentElement,
- clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
- top = box.top + (g.win.pageYOffset || docElem.scrollTop || body.scrollTop ) - clientTop,
- left = box.left + (g.win.pageXOffset || docElem.scrollLeft || body.scrollLeft) - clientLeft;
- return {
- y: top,
- x: left
- };
-};
-/*\
- * Snap.getElementByPoint
- [ method ]
- **
- * Returns you topmost element under given point.
- **
- = (object) Snap element object
- - x (number) x coordinate from the top left corner of the window
- - y (number) y coordinate from the top left corner of the window
- > Usage
- | Snap.getElementByPoint(mouseX, mouseY).attr({stroke: "#f00"});
-\*/
-Snap.getElementByPoint = function (x, y) {
- var paper = this,
- svg = paper.canvas,
- target = glob.doc.elementFromPoint(x, y);
- if (glob.win.opera && target.tagName == "svg") {
- var so = getOffset(target),
- sr = target.createSVGRect();
- sr.x = x - so.x;
- sr.y = y - so.y;
- sr.width = sr.height = 1;
- var hits = target.getIntersectionList(sr, null);
- if (hits.length) {
- target = hits[hits.length - 1];
- }
- }
- if (!target) {
- return null;
- }
- return wrap(target);
-};
-/*\
- * Snap.plugin
- [ method ]
- **
- * Let you write plugins. You pass in a function with five arguments, like this:
- | Snap.plugin(function (Snap, Element, Paper, global, Fragment) {
- | Snap.newmethod = function () {};
- | Element.prototype.newmethod = function () {};
- | Paper.prototype.newmethod = function () {};
- | });
- * Inside the function you have access to all main objects (and their
- * prototypes). This allow you to extend anything you want.
- **
- - f (function) your plugin body
-\*/
-Snap.plugin = function (f) {
- f(Snap, Element, Paper, glob, Fragment);
-};
-glob.win.Snap = Snap;
-return Snap;
-}(window || this));
-
-// 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 || "");
- }
- 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;
- this._.transform = tstr.toTransformString();
- } 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) {
- 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.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 = attrs.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;
-});
-
-// 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 objectToString = Object.prototype.toString,
- Str = String,
- math = Math,
- E = "";
- function Matrix(a, b, c, d, e, f) {
- if (b == null && objectToString.call(a) == "[object SVGMatrix]") {
- this.a = a.a;
- this.b = a.b;
- this.c = a.c;
- this.d = a.d;
- this.e = a.e;
- this.f = a.f;
- return;
- }
- if (a != null) {
- this.a = +a;
- this.b = +b;
- this.c = +c;
- this.d = +d;
- this.e = +e;
- this.f = +f;
- } else {
- this.a = 1;
- this.b = 0;
- this.c = 0;
- this.d = 1;
- this.e = 0;
- this.f = 0;
- }
- }
- (function (matrixproto) {
- /*\
- * Matrix.add
- [ method ]
- **
- * Adds the given matrix to existing one
- - a (number)
- - b (number)
- - c (number)
- - d (number)
- - e (number)
- - f (number)
- * or
- - matrix (object) @Matrix
- \*/
- matrixproto.add = function (a, b, c, d, e, f) {
- var out = [[], [], []],
- m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]],
- matrix = [[a, c, e], [b, d, f], [0, 0, 1]],
- x, y, z, res;
-
- if (a && a instanceof Matrix) {
- matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]];
- }
-
- for (x = 0; x < 3; x++) {
- for (y = 0; y < 3; y++) {
- res = 0;
- for (z = 0; z < 3; z++) {
- res += m[x][z] * matrix[z][y];
- }
- out[x][y] = res;
- }
- }
- this.a = out[0][0];
- this.b = out[1][0];
- this.c = out[0][1];
- this.d = out[1][1];
- this.e = out[0][2];
- this.f = out[1][2];
- return this;
- };
- /*\
- * Matrix.invert
- [ method ]
- **
- * Returns an inverted version of the matrix
- = (object) @Matrix
- \*/
- matrixproto.invert = function () {
- var me = this,
- x = me.a * me.d - me.b * me.c;
- return new Matrix(me.d / x, -me.b / x, -me.c / x, me.a / x, (me.c * me.f - me.d * me.e) / x, (me.b * me.e - me.a * me.f) / x);
- };
- /*\
- * Matrix.clone
- [ method ]
- **
- * Returns a copy of the matrix
- = (object) @Matrix
- \*/
- matrixproto.clone = function () {
- return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f);
- };
- /*\
- * Matrix.translate
- [ method ]
- **
- * Translate the matrix
- - x (number) horizontal offset distance
- - y (number) vertical offset distance
- \*/
- matrixproto.translate = function (x, y) {
- return this.add(1, 0, 0, 1, x, y);
- };
- /*\
- * Matrix.scale
- [ method ]
- **
- * Scales the matrix
- - x (number) amount to be scaled, with `1` resulting in no change
- - y (number) #optional amount to scale along the vertical axis. (Otherwise `x` applies to both axes.)
- - cx (number) #optional horizontal origin point from which to scale
- - cy (number) #optional vertical origin point from which to scale
- * Default cx, cy is the middle point of the element.
- \*/
- matrixproto.scale = function (x, y, cx, cy) {
- y == null && (y = x);
- (cx || cy) && this.add(1, 0, 0, 1, cx, cy);
- this.add(x, 0, 0, y, 0, 0);
- (cx || cy) && this.add(1, 0, 0, 1, -cx, -cy);
- return this;
- };
- /*\
- * Matrix.rotate
- [ method ]
- **
- * Rotates the matrix
- - a (number) angle of rotation, in degrees
- - x (number) horizontal origin point from which to rotate
- - y (number) vertical origin point from which to rotate
- \*/
- matrixproto.rotate = function (a, x, y) {
- a = Snap.rad(a);
- x = x || 0;
- y = y || 0;
- var cos = +math.cos(a).toFixed(9),
- sin = +math.sin(a).toFixed(9);
- this.add(cos, sin, -sin, cos, x, y);
- return this.add(1, 0, 0, 1, -x, -y);
- };
- /*\
- * Matrix.x
- [ method ]
- **
- * Returns x coordinate for given point after transformation described by the matrix. See also @Matrix.y
- - x (number)
- - y (number)
- = (number) x
- \*/
- matrixproto.x = function (x, y) {
- return x * this.a + y * this.c + this.e;
- };
- /*\
- * Matrix.y
- [ method ]
- **
- * Returns y coordinate for given point after transformation described by the matrix. See also @Matrix.x
- - x (number)
- - y (number)
- = (number) y
- \*/
- matrixproto.y = function (x, y) {
- return x * this.b + y * this.d + this.f;
- };
- matrixproto.get = function (i) {
- return +this[Str.fromCharCode(97 + i)].toFixed(4);
- };
- matrixproto.toString = function () {
- return "matrix(" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + ")";
- };
- matrixproto.offset = function () {
- return [this.e.toFixed(4), this.f.toFixed(4)];
- };
- function norm(a) {
- return a[0] * a[0] + a[1] * a[1];
- }
- function normalize(a) {
- var mag = math.sqrt(norm(a));
- a[0] && (a[0] /= mag);
- a[1] && (a[1] /= mag);
- }
- /*\
- * Matrix.determinant
- [ method ]
- **
- * Finds determinant of the given matrix.
- = (number) determinant
- \*/
- matrixproto.determinant = function () {
- return this.a * this.d - this.b * this.c;
- };
- /*\
- * Matrix.split
- [ method ]
- **
- * Splits matrix into primitive transformations
- = (object) in format:
- o dx (number) translation by x
- o dy (number) translation by y
- o scalex (number) scale by x
- o scaley (number) scale by y
- o shear (number) shear
- o rotate (number) rotation in deg
- o isSimple (boolean) could it be represented via simple transformations
- \*/
- matrixproto.split = function () {
- var out = {};
- // translation
- out.dx = this.e;
- out.dy = this.f;
-
- // scale and shear
- var row = [[this.a, this.c], [this.b, this.d]];
- out.scalex = math.sqrt(norm(row[0]));
- normalize(row[0]);
-
- out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1];
- row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear];
-
- out.scaley = math.sqrt(norm(row[1]));
- normalize(row[1]);
- out.shear /= out.scaley;
-
- if (this.determinant() < 0) {
- out.scalex = -out.scalex;
- }
-
- // rotation
- var sin = -row[0][1],
- cos = row[1][1];
- if (cos < 0) {
- out.rotate = Snap.deg(math.acos(cos));
- if (sin < 0) {
- out.rotate = 360 - out.rotate;
- }
- } else {
- out.rotate = Snap.deg(math.asin(sin));
- }
-
- out.isSimple = !+out.shear.toFixed(9) && (out.scalex.toFixed(9) == out.scaley.toFixed(9) || !out.rotate);
- out.isSuperSimple = !+out.shear.toFixed(9) && out.scalex.toFixed(9) == out.scaley.toFixed(9) && !out.rotate;
- out.noRotation = !+out.shear.toFixed(9) && !out.rotate;
- return out;
- };
- /*\
- * Matrix.toTransformString
- [ method ]
- **
- * Returns transform string that represents given matrix
- = (string) transform string
- \*/
- matrixproto.toTransformString = function (shorter) {
- var s = shorter || this.split();
- if (!+s.shear.toFixed(9)) {
- s.scalex = +s.scalex.toFixed(4);
- s.scaley = +s.scaley.toFixed(4);
- s.rotate = +s.rotate.toFixed(4);
- return (s.dx || s.dy ? "t" + [+s.dx.toFixed(4), +s.dy.toFixed(4)] : E) +
- (s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E) +
- (s.rotate ? "r" + [+s.rotate.toFixed(4), 0, 0] : E);
- } else {
- return "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)];
- }
- };
- })(Matrix.prototype);
- /*\
- * Snap.Matrix
- [ method ]
- **
- * Matrix constructor, extend on your own risk.
- * To create matrices use @Snap.matrix.
- \*/
- Snap.Matrix = Matrix;
- /*\
- * Snap.matrix
- [ method ]
- **
- * Utility method
- **
- * Returns a matrix based on the given parameters
- - a (number)
- - b (number)
- - c (number)
- - d (number)
- - e (number)
- - f (number)
- * or
- - svgMatrix (SVGMatrix)
- = (object) @Matrix
- \*/
- Snap.matrix = function (a, b, c, d, e, f) {
- return new Matrix(a, b, c, d, e, f);
- };
-});
-// 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 has = "hasOwnProperty",
- make = Snap._.make,
- wrap = Snap._.wrap,
- is = Snap.is,
- getSomeDefs = Snap._.getSomeDefs,
- reURLValue = /^url\(#?([^)]+)\)$/,
- $ = Snap._.$,
- URL = Snap.url,
- Str = String,
- separator = Snap._.separator,
- E = "";
- // Attributes event handlers
- eve.on("snap.util.attr.mask", function (value) {
- if (value instanceof Element || value instanceof Fragment) {
- eve.stop();
- if (value instanceof Fragment && value.node.childNodes.length == 1) {
- value = value.node.firstChild;
- getSomeDefs(this).appendChild(value);
- value = wrap(value);
- }
- if (value.type == "mask") {
- var mask = value;
- } else {
- mask = make("mask", getSomeDefs(this));
- mask.node.appendChild(value.node);
- }
- !mask.node.id && $(mask.node, {
- id: mask.id
- });
- $(this.node, {
- mask: URL(mask.id)
- });
- }
- });
- (function (clipIt) {
- eve.on("snap.util.attr.clip", clipIt);
- eve.on("snap.util.attr.clip-path", clipIt);
- eve.on("snap.util.attr.clipPath", clipIt);
- }(function (value) {
- if (value instanceof Element || value instanceof Fragment) {
- eve.stop();
- if (value.type == "clipPath") {
- var clip = value;
- } else {
- clip = make("clipPath", getSomeDefs(this));
- clip.node.appendChild(value.node);
- !clip.node.id && $(clip.node, {
- id: clip.id
- });
- }
- $(this.node, {
- "clip-path": URL(clip.node.id || clip.id)
- });
- }
- }));
- function fillStroke(name) {
- return function (value) {
- eve.stop();
- if (value instanceof Fragment && value.node.childNodes.length == 1 &&
- (value.node.firstChild.tagName == "radialGradient" ||
- value.node.firstChild.tagName == "linearGradient" ||
- value.node.firstChild.tagName == "pattern")) {
- value = value.node.firstChild;
- getSomeDefs(this).appendChild(value);
- value = wrap(value);
- }
- if (value instanceof Element) {
- if (value.type == "radialGradient" || value.type == "linearGradient"
- || value.type == "pattern") {
- if (!value.node.id) {
- $(value.node, {
- id: value.id
- });
- }
- var fill = URL(value.node.id);
- } else {
- fill = value.attr(name);
- }
- } else {
- fill = Snap.color(value);
- if (fill.error) {
- var grad = Snap(getSomeDefs(this).ownerSVGElement).gradient(value);
- if (grad) {
- if (!grad.node.id) {
- $(grad.node, {
- id: grad.id
- });
- }
- fill = URL(grad.node.id);
- } else {
- fill = value;
- }
- } else {
- fill = Str(fill);
- }
- }
- var attrs = {};
- attrs[name] = fill;
- $(this.node, attrs);
- this.node.style[name] = E;
- };
- }
- eve.on("snap.util.attr.fill", fillStroke("fill"));
- eve.on("snap.util.attr.stroke", fillStroke("stroke"));
- var gradrg = /^([lr])(?:\(([^)]*)\))?(.*)$/i;
- eve.on("snap.util.grad.parse", function parseGrad(string) {
- string = Str(string);
- var tokens = string.match(gradrg);
- if (!tokens) {
- return null;
- }
- var type = tokens[1],
- params = tokens[2],
- stops = tokens[3];
- params = params.split(/\s*,\s*/).map(function (el) {
- return +el == el ? +el : el;
- });
- if (params.length == 1 && params[0] == 0) {
- params = [];
- }
- stops = stops.split("-");
- stops = stops.map(function (el) {
- el = el.split(":");
- var out = {
- color: el[0]
- };
- if (el[1]) {
- out.offset = parseFloat(el[1]);
- }
- return out;
- });
- return {
- type: type,
- params: params,
- stops: stops
- };
- });
-
- eve.on("snap.util.attr.d", function (value) {
- eve.stop();
- if (is(value, "array") && is(value[0], "array")) {
- value = Snap.path.toString.call(value);
- }
- value = Str(value);
- if (value.match(/[ruo]/i)) {
- value = Snap.path.toAbsolute(value);
- }
- $(this.node, {d: value});
- })(-1);
- eve.on("snap.util.attr.#text", function (value) {
- eve.stop();
- value = Str(value);
- var txt = glob.doc.createTextNode(value);
- while (this.node.firstChild) {
- this.node.removeChild(this.node.firstChild);
- }
- this.node.appendChild(txt);
- })(-1);
- eve.on("snap.util.attr.path", function (value) {
- eve.stop();
- this.attr({d: value});
- })(-1);
- eve.on("snap.util.attr.class", function (value) {
- eve.stop();
- this.node.className.baseVal = value;
- })(-1);
- eve.on("snap.util.attr.viewBox", function (value) {
- var vb;
- if (is(value, "object") && "x" in value) {
- vb = [value.x, value.y, value.width, value.height].join(" ");
- } else if (is(value, "array")) {
- vb = value.join(" ");
- } else {
- vb = value;
- }
- $(this.node, {
- viewBox: vb
- });
- eve.stop();
- })(-1);
- eve.on("snap.util.attr.transform", function (value) {
- this.transform(value);
- eve.stop();
- })(-1);
- eve.on("snap.util.attr.r", function (value) {
- if (this.type == "rect") {
- eve.stop();
- $(this.node, {
- rx: value,
- ry: value
- });
- }
- })(-1);
- eve.on("snap.util.attr.textpath", function (value) {
- eve.stop();
- if (this.type == "text") {
- var id, tp, node;
- if (!value && this.textPath) {
- tp = this.textPath;
- while (tp.node.firstChild) {
- this.node.appendChild(tp.node.firstChild);
- }
- tp.remove();
- delete this.textPath;
- return;
- }
- if (is(value, "string")) {
- var defs = getSomeDefs(this),
- path = wrap(defs.parentNode).path(value);
- defs.appendChild(path.node);
- id = path.id;
- path.attr({id: id});
- } else {
- value = wrap(value);
- if (value instanceof Element) {
- id = value.attr("id");
- if (!id) {
- id = value.id;
- value.attr({id: id});
- }
- }
- }
- if (id) {
- tp = this.textPath;
- node = this.node;
- if (tp) {
- tp.attr({"xlink:href": "#" + id});
- } else {
- tp = $("textPath", {
- "xlink:href": "#" + id
- });
- while (node.firstChild) {
- tp.appendChild(node.firstChild);
- }
- node.appendChild(tp);
- this.textPath = wrap(tp);
- }
- }
- }
- })(-1);
- eve.on("snap.util.attr.text", function (value) {
- if (this.type == "text") {
- var i = 0,
- node = this.node,
- tuner = function (chunk) {
- var out = $("tspan");
- if (is(chunk, "array")) {
- for (var i = 0; i < chunk.length; i++) {
- out.appendChild(tuner(chunk[i]));
- }
- } else {
- out.appendChild(glob.doc.createTextNode(chunk));
- }
- out.normalize && out.normalize();
- return out;
- };
- while (node.firstChild) {
- node.removeChild(node.firstChild);
- }
- var tuned = tuner(value);
- while (tuned.firstChild) {
- node.appendChild(tuned.firstChild);
- }
- }
- eve.stop();
- })(-1);
- function setFontSize(value) {
- eve.stop();
- if (value == +value) {
- value += "px";
- }
- this.node.style.fontSize = value;
- }
- eve.on("snap.util.attr.fontSize", setFontSize)(-1);
- eve.on("snap.util.attr.font-size", setFontSize)(-1);
-
-
- eve.on("snap.util.getattr.transform", function () {
- eve.stop();
- return this.transform();
- })(-1);
- eve.on("snap.util.getattr.textpath", function () {
- eve.stop();
- return this.textPath;
- })(-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 Snap(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("snap.util.getattr.marker-end", getter("end"))(-1);
- eve.on("snap.util.getattr.markerEnd", getter("end"))(-1);
- eve.on("snap.util.getattr.marker-start", getter("start"))(-1);
- eve.on("snap.util.getattr.markerStart", getter("start"))(-1);
- eve.on("snap.util.getattr.marker-mid", getter("mid"))(-1);
- eve.on("snap.util.getattr.markerMid", getter("mid"))(-1);
- eve.on("snap.util.attr.marker-end", setter("end"))(-1);
- eve.on("snap.util.attr.markerEnd", setter("end"))(-1);
- eve.on("snap.util.attr.marker-start", setter("start"))(-1);
- eve.on("snap.util.attr.markerStart", setter("start"))(-1);
- eve.on("snap.util.attr.marker-mid", setter("mid"))(-1);
- eve.on("snap.util.attr.markerMid", setter("mid"))(-1);
- }());
- eve.on("snap.util.getattr.r", function () {
- if (this.type == "rect" && $(this.node, "rx") == $(this.node, "ry")) {
- eve.stop();
- return $(this.node, "rx");
- }
- })(-1);
- function textExtract(node) {
- var out = [];
- var children = node.childNodes;
- for (var i = 0, ii = children.length; i < ii; i++) {
- var chi = children[i];
- if (chi.nodeType == 3) {
- out.push(chi.nodeValue);
- }
- if (chi.tagName == "tspan") {
- if (chi.childNodes.length == 1 && chi.firstChild.nodeType == 3) {
- out.push(chi.firstChild.nodeValue);
- } else {
- out.push(textExtract(chi));
- }
- }
- }
- return out;
- }
- eve.on("snap.util.getattr.text", function () {
- if (this.type == "text" || this.type == "tspan") {
- eve.stop();
- var out = textExtract(this.node);
- return out.length == 1 ? out[0] : out;
- }
- })(-1);
- eve.on("snap.util.getattr.#text", function () {
- return this.node.textContent;
- })(-1);
- eve.on("snap.util.getattr.viewBox", function () {
- eve.stop();
- var vb = $(this.node, "viewBox");
- if (vb) {
- vb = vb.split(separator);
- return Snap._.box(+vb[0], +vb[1], +vb[2], +vb[3]);
- } else {
- return;
- }
- })(-1);
- eve.on("snap.util.getattr.points", function () {
- var p = $(this.node, "points");
- eve.stop();
- if (p) {
- return p.split(separator);
- } else {
- return;
- }
- })(-1);
- eve.on("snap.util.getattr.path", function () {
- var p = $(this.node, "d");
- eve.stop();
- return p;
- })(-1);
- eve.on("snap.util.getattr.class", function () {
- return this.node.className.baseVal;
- })(-1);
- function getFontSize() {
- eve.stop();
- return this.node.style.fontSize;
- }
- eve.on("snap.util.getattr.fontSize", getFontSize)(-1);
- eve.on("snap.util.getattr.font-size", getFontSize)(-1);
-});
-
-// Copyright (c) 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.
-// 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 rgNotSpace = /\S+/g,
- rgBadSpace = /[\t\r\n\f]/g,
- rgTrim = /(^\s+|\s+$)/g,
- Str = String,
- elproto = Element.prototype;
- /*\
- * Element.addClass
- [ method ]
- **
- * Adds given class name or list of class names to the element.
- - value (string) class name or space separated list of class names
- **
- = (Element) original element.
- \*/
- elproto.addClass = function (value) {
- var classes = Str(value || "").match(rgNotSpace) || [],
- elem = this.node,
- className = elem.className.baseVal,
- curClasses = className.match(rgNotSpace) || [],
- j,
- pos,
- clazz,
- finalValue;
-
- if (classes.length) {
- j = 0;
- while ((clazz = classes[j++])) {
- pos = curClasses.indexOf(clazz);
- if (!~pos) {
- curClasses.push(clazz);
- }
- }
-
- finalValue = curClasses.join(" ");
- if (className != finalValue) {
- elem.className.baseVal = finalValue;
- }
- }
- return this;
- };
- /*\
- * Element.removeClass
- [ method ]
- **
- * Removes given class name or list of class names from the element.
- - value (string) class name or space separated list of class names
- **
- = (Element) original element.
- \*/
- elproto.removeClass = function (value) {
- var classes = Str(value || "").match(rgNotSpace) || [],
- elem = this.node,
- className = elem.className.baseVal,
- curClasses = className.match(rgNotSpace) || [],
- j,
- pos,
- clazz,
- finalValue;
- if (curClasses.length) {
- j = 0;
- while ((clazz = classes[j++])) {
- pos = curClasses.indexOf(clazz);
- if (~pos) {
- curClasses.splice(pos, 1);
- }
- }
-
- finalValue = curClasses.join(" ");
- if (className != finalValue) {
- elem.className.baseVal = finalValue;
- }
- }
- return this;
- };
- /*\
- * Element.hasClass
- [ method ]
- **
- * Checks if the element has a given class name in the list of class names applied to it.
- - value (string) class name
- **
- = (boolean) `true` if the element has given class
- \*/
- elproto.hasClass = function (value) {
- var elem = this.node,
- className = elem.className.baseVal,
- curClasses = className.match(rgNotSpace) || [];
- return !!~curClasses.indexOf(value);
- };
- /*\
- * Element.toggleClass
- [ method ]
- **
- * Add or remove one or more classes from the element, depending on either
- * the class’s presence or the value of the `flag` argument.
- - value (string) class name or space separated list of class names
- - flag (boolean) value to determine whether the class should be added or removed
- **
- = (Element) original element.
- \*/
- elproto.toggleClass = function (value, flag) {
- if (flag != null) {
- if (flag) {
- return this.addClass(value);
- } else {
- return this.removeClass(value);
- }
- }
- var classes = (value || "").match(rgNotSpace) || [],
- elem = this.node,
- className = elem.className.baseVal,
- curClasses = className.match(rgNotSpace) || [],
- j,
- pos,
- clazz,
- finalValue;
- j = 0;
- while ((clazz = classes[j++])) {
- pos = curClasses.indexOf(clazz);
- if (~pos) {
- curClasses.splice(pos, 1);
- } else {
- curClasses.push(clazz);
- }
- }
-
- finalValue = curClasses.join(" ");
- if (className != finalValue) {
- elem.className.baseVal = finalValue;
- }
- return this;
- };
-});
-
-// 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 operators = {
- "+": function (x, y) {
- return x + y;
- },
- "-": function (x, y) {
- return x - y;
- },
- "/": function (x, y) {
- return x / y;
- },
- "*": function (x, y) {
- return x * y;
- }
- },
- Str = String,
- reUnit = /[a-z]+$/i,
- reAddon = /^\s*([+\-\/*])\s*=\s*([\d.eE+\-]+)\s*([^\d\s]+)?\s*$/;
- function getNumber(val) {
- return val;
- }
- function getUnit(unit) {
- return function (val) {
- return +val.toFixed(3) + unit;
- };
- }
- eve.on("snap.util.attr", function (val) {
- var plus = Str(val).match(reAddon);
- if (plus) {
- var evnt = eve.nt(),
- name = evnt.substring(evnt.lastIndexOf(".") + 1),
- a = this.attr(name),
- atr = {};
- eve.stop();
- var unit = plus[3] || "",
- aUnit = a.match(reUnit),
- op = operators[plus[1]];
- if (aUnit && aUnit == unit) {
- val = op(parseFloat(a), +plus[2]);
- } else {
- a = this.asPX(name);
- val = op(this.asPX(name), this.asPX(name, plus[2] + unit));
- }
- if (isNaN(a) || isNaN(val)) {
- return;
- }
- atr[name] = val;
- this.attr(atr);
- }
- })(-10);
- eve.on("snap.util.equal", function (name, b) {
- var A, B, a = Str(this.attr(name) || ""),
- el = this,
- bplus = Str(b).match(reAddon);
- if (bplus) {
- eve.stop();
- var unit = bplus[3] || "",
- aUnit = a.match(reUnit),
- op = operators[bplus[1]];
- if (aUnit && aUnit == unit) {
- return {
- from: parseFloat(a),
- to: op(parseFloat(a), +bplus[2]),
- f: getUnit(aUnit)
- };
- } else {
- a = this.asPX(name);
- return {
- from: a,
- to: op(a, this.asPX(name, bplus[2] + unit)),
- f: getNumber
- };
- }
- }
- })(-10);
-});
-// 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 proto = Paper.prototype,
- is = Snap.is;
- /*\
- * Paper.rect
- [ method ]
- *
- * Draws a rectangle
- **
- - x (number) x coordinate of the top left corner
- - y (number) y coordinate of the top left corner
- - width (number) width
- - height (number) height
- - rx (number) #optional horizontal radius for rounded corners, default is 0
- - ry (number) #optional vertical radius for rounded corners, default is rx or 0
- = (object) the `rect` element
- **
- > Usage
- | // regular rectangle
- | var c = paper.rect(10, 10, 50, 50);
- | // rectangle with rounded corners
- | var c = paper.rect(40, 40, 50, 50, 10);
- \*/
- proto.rect = function (x, y, w, h, rx, ry) {
- var attr;
- if (ry == null) {
- ry = rx;
- }
- if (is(x, "object") && x == "[object Object]") {
- attr = x;
- } else if (x != null) {
- attr = {
- x: x,
- y: y,
- width: w,
- height: h
- };
- if (rx != null) {
- attr.rx = rx;
- attr.ry = ry;
- }
- }
- return this.el("rect", attr);
- };
- /*\
- * Paper.circle
- [ method ]
- **
- * Draws a circle
- **
- - x (number) x coordinate of the centre
- - y (number) y coordinate of the centre
- - r (number) radius
- = (object) the `circle` element
- **
- > Usage
- | var c = paper.circle(50, 50, 40);
- \*/
- proto.circle = function (cx, cy, r) {
- var attr;
- if (is(cx, "object") && cx == "[object Object]") {
- attr = cx;
- } else if (cx != null) {
- attr = {
- cx: cx,
- cy: cy,
- r: r
- };
- }
- return this.el("circle", attr);
- };
-
- var preload = (function () {
- function onerror() {
- this.parentNode.removeChild(this);
- }
- return function (src, f) {
- var img = glob.doc.createElement("img"),
- body = glob.doc.body;
- img.style.cssText = "position:absolute;left:-9999em;top:-9999em";
- img.onload = function () {
- f.call(img);
- img.onload = img.onerror = null;
- body.removeChild(img);
- };
- img.onerror = onerror;
- body.appendChild(img);
- img.src = src;
- };
- }());
-
- /*\
- * Paper.image
- [ method ]
- **
- * Places an image on the surface
- **
- - src (string) URI of the source image
- - x (number) x offset position
- - y (number) y offset position
- - width (number) width of the image
- - height (number) height of the image
- = (object) the `image` element
- * or
- = (object) Snap element object with type `image`
- **
- > Usage
- | var c = paper.image("apple.png", 10, 10, 80, 80);
- \*/
- proto.image = function (src, x, y, width, height) {
- var el = this.el("image");
- if (is(src, "object") && "src" in src) {
- el.attr(src);
- } else if (src != null) {
- var set = {
- "xlink:href": src,
- preserveAspectRatio: "none"
- };
- if (x != null && y != null) {
- set.x = x;
- set.y = y;
- }
- if (width != null && height != null) {
- set.width = width;
- set.height = height;
- } else {
- preload(src, function () {
- Snap._.$(el.node, {
- width: this.offsetWidth,
- height: this.offsetHeight
- });
- });
- }
- Snap._.$(el.node, set);
- }
- return el;
- };
- /*\
- * Paper.ellipse
- [ method ]
- **
- * Draws an ellipse
- **
- - x (number) x coordinate of the centre
- - y (number) y coordinate of the centre
- - rx (number) horizontal radius
- - ry (number) vertical radius
- = (object) the `ellipse` element
- **
- > Usage
- | var c = paper.ellipse(50, 50, 40, 20);
- \*/
- proto.ellipse = function (cx, cy, rx, ry) {
- var attr;
- if (is(cx, "object") && cx == "[object Object]") {
- attr = cx;
- } else if (cx != null) {
- attr ={
- cx: cx,
- cy: cy,
- rx: rx,
- ry: ry
- };
- }
- return this.el("ellipse", attr);
- };
- // SIERRA Paper.path(): Unclear from the link what a Catmull-Rom curveto is, and why it would make life any easier.
- /*\
- * Paper.path
- [ method ]
- **
- * Creates a `<path>` element using the given string as the path's definition
- - pathString (string) #optional path string in SVG format
- * Path string consists of one-letter commands, followed by comma seprarated arguments in numerical form. Example:
- | "M10,20L30,40"
- * This example features two commands: `M`, with arguments `(10, 20)` and `L` with arguments `(30, 40)`. Uppercase letter commands express coordinates in absolute terms, while lowercase commands express them in relative terms from the most recently declared coordinates.
- *
- # <p>Here is short list of commands available, for more details see <a href="http://www.w3.org/TR/SVG/paths.html#PathData" title="Details of a path's data attribute's format are described in the SVG specification.">SVG path string format</a> or <a href="https://developer.mozilla.org/en/SVG/Tutorial/Paths">article about path strings at MDN</a>.</p>
- # <table><thead><tr><th>Command</th><th>Name</th><th>Parameters</th></tr></thead><tbody>
- # <tr><td>M</td><td>moveto</td><td>(x y)+</td></tr>
- # <tr><td>Z</td><td>closepath</td><td>(none)</td></tr>
- # <tr><td>L</td><td>lineto</td><td>(x y)+</td></tr>
- # <tr><td>H</td><td>horizontal lineto</td><td>x+</td></tr>
- # <tr><td>V</td><td>vertical lineto</td><td>y+</td></tr>
- # <tr><td>C</td><td>curveto</td><td>(x1 y1 x2 y2 x y)+</td></tr>
- # <tr><td>S</td><td>smooth curveto</td><td>(x2 y2 x y)+</td></tr>
- # <tr><td>Q</td><td>quadratic Bézier curveto</td><td>(x1 y1 x y)+</td></tr>
- # <tr><td>T</td><td>smooth quadratic Bézier curveto</td><td>(x y)+</td></tr>
- # <tr><td>A</td><td>elliptical arc</td><td>(rx ry x-axis-rotation large-arc-flag sweep-flag x y)+</td></tr>
- # <tr><td>R</td><td><a href="http://en.wikipedia.org/wiki/Catmull–Rom_spline#Catmull.E2.80.93Rom_spline">Catmull-Rom curveto</a>*</td><td>x1 y1 (x y)+</td></tr></tbody></table>
- * * _Catmull-Rom curveto_ is a not standard SVG command and added to make life easier.
- * Note: there is a special case when a path consists of only three commands: `M10,10R…z`. In this case the path connects back to its starting point.
- > Usage
- | var c = paper.path("M10 10L90 90");
- | // draw a diagonal line:
- | // move to 10,10, line to 90,90
- \*/
- proto.path = function (d) {
- var attr;
- if (is(d, "object") && !is(d, "array")) {
- attr = d;
- } else if (d) {
- attr = {d: d};
- }
- return this.el("path", attr);
- };
- /*\
- * Paper.g
- [ method ]
- **
- * Creates a group element
- **
- - varargs (…) #optional elements to nest within the group
- = (object) the `g` element
- **
- > Usage
- | var c1 = paper.circle(),
- | c2 = paper.rect(),
- | g = paper.g(c2, c1); // note that the order of elements is different
- * or
- | var c1 = paper.circle(),
- | c2 = paper.rect(),
- | g = paper.g();
- | g.add(c2, c1);
- \*/
- /*\
- * Paper.group
- [ method ]
- **
- * See @Paper.g
- \*/
- proto.group = proto.g = function (first) {
- var attr,
- el = this.el("g");
- if (arguments.length == 1 && first && !first.type) {
- el.attr(first);
- } else if (arguments.length) {
- el.add(Array.prototype.slice.call(arguments, 0));
- }
- return el;
- };
- /*\
- * Paper.svg
- [ method ]
- **
- * Creates a nested SVG element.
- - x (number) @optional X of the element
- - y (number) @optional Y of the element
- - width (number) @optional width of the element
- - height (number) @optional height of the element
- - vbx (number) @optional viewbox X
- - vby (number) @optional viewbox Y
- - vbw (number) @optional viewbox width
- - vbh (number) @optional viewbox height
- **
- = (object) the `svg` element
- **
- \*/
- proto.svg = function (x, y, width, height, vbx, vby, vbw, vbh) {
- var attrs = {};
- if (is(x, "object") && y == null) {
- attrs = x;
- } else {
- if (x != null) {
- attrs.x = x;
- }
- if (y != null) {
- attrs.y = y;
- }
- if (width != null) {
- attrs.width = width;
- }
- if (height != null) {
- attrs.height = height;
- }
- if (vbx != null && vby != null && vbw != null && vbh != null) {
- attrs.viewBox = [vbx, vby, vbw, vbh];
- }
- }
- return this.el("svg", attrs);
- };
- /*\
- * Paper.mask
- [ method ]
- **
- * Equivalent in behaviour to @Paper.g, except it’s a mask.
- **
- = (object) the `mask` element
- **
- \*/
- proto.mask = function (first) {
- var attr,
- el = this.el("mask");
- if (arguments.length == 1 && first && !first.type) {
- el.attr(first);
- } else if (arguments.length) {
- el.add(Array.prototype.slice.call(arguments, 0));
- }
- return el;
- };
- /*\
- * Paper.ptrn
- [ method ]
- **
- * Equivalent in behaviour to @Paper.g, except it’s a pattern.
- - x (number) @optional X of the element
- - y (number) @optional Y of the element
- - width (number) @optional width of the element
- - height (number) @optional height of the element
- - vbx (number) @optional viewbox X
- - vby (number) @optional viewbox Y
- - vbw (number) @optional viewbox width
- - vbh (number) @optional viewbox height
- **
- = (object) the `pattern` element
- **
- \*/
- proto.ptrn = function (x, y, width, height, vx, vy, vw, vh) {
- if (is(x, "object")) {
- var attr = x;
- } else {
- attr = {patternUnits: "userSpaceOnUse"};
- if (x) {
- attr.x = x;
- }
- if (y) {
- attr.y = y;
- }
- if (width != null) {
- attr.width = width;
- }
- if (height != null) {
- attr.height = height;
- }
- if (vx != null && vy != null && vw != null && vh != null) {
- attr.viewBox = [vx, vy, vw, vh];
- } else {
- attr.viewBox = [x || 0, y || 0, width || 0, height || 0];
- }
- }
- return this.el("pattern", attr);
- };
- /*\
- * Paper.use
- [ method ]
- **
- * Creates a <use> element.
- - id (string) @optional id of element to link
- * or
- - id (Element) @optional element to link
- **
- = (object) the `use` element
- **
- \*/
- proto.use = function (id) {
- if (id != null) {
- if (id instanceof Element) {
- if (!id.attr("id")) {
- id.attr({id: Snap._.id(id)});
- }
- id = id.attr("id");
- }
- if (String(id).charAt() == "#") {
- id = id.substring(1);
- }
- return this.el("use", {"xlink:href": "#" + id});
- } else {
- return Element.prototype.use.call(this);
- }
- };
- /*\
- * Paper.symbol
- [ method ]
- **
- * Creates a <symbol> element.
- - vbx (number) @optional viewbox X
- - vby (number) @optional viewbox Y
- - vbw (number) @optional viewbox width
- - vbh (number) @optional viewbox height
- = (object) the `symbol` element
- **
- \*/
- proto.symbol = function (vx, vy, vw, vh) {
- var attr = {};
- if (vx != null && vy != null && vw != null && vh != null) {
- attr.viewBox = [vx, vy, vw, vh];
- }
-
- return this.el("symbol", attr);
- };
- /*\
- * Paper.text
- [ method ]
- **
- * Draws a text string
- **
- - x (number) x coordinate position
- - y (number) y coordinate position
- - text (string|array) The text string to draw or array of strings to nest within separate `<tspan>` elements
- = (object) the `text` element
- **
- > Usage
- | var t1 = paper.text(50, 50, "Snap");
- | var t2 = paper.text(50, 50, ["S","n","a","p"]);
- | // Text path usage
- | t1.attr({textpath: "M10,10L100,100"});
- | // or
- | var pth = paper.path("M10,10L100,100");
- | t1.attr({textpath: pth});
- \*/
- proto.text = function (x, y, text) {
- var attr = {};
- if (is(x, "object")) {
- attr = x;
- } else if (x != null) {
- attr = {
- x: x,
- y: y,
- text: text || ""
- };
- }
- return this.el("text", attr);
- };
- /*\
- * Paper.line
- [ method ]
- **
- * Draws a line
- **
- - x1 (number) x coordinate position of the start
- - y1 (number) y coordinate position of the start
- - x2 (number) x coordinate position of the end
- - y2 (number) y coordinate position of the end
- = (object) the `line` element
- **
- > Usage
- | var t1 = paper.line(50, 50, 100, 100);
- \*/
- proto.line = function (x1, y1, x2, y2) {
- var attr = {};
- if (is(x1, "object")) {
- attr = x1;
- } else if (x1 != null) {
- attr = {
- x1: x1,
- x2: x2,
- y1: y1,
- y2: y2
- };
- }
- return this.el("line", attr);
- };
- /*\
- * Paper.polyline
- [ method ]
- **
- * Draws a polyline
- **
- - points (array) array of points
- * or
- - varargs (…) points
- = (object) the `polyline` element
- **
- > Usage
- | var p1 = paper.polyline([10, 10, 100, 100]);
- | var p2 = paper.polyline(10, 10, 100, 100);
- \*/
- proto.polyline = function (points) {
- if (arguments.length > 1) {
- points = Array.prototype.slice.call(arguments, 0);
- }
- var attr = {};
- if (is(points, "object") && !is(points, "array")) {
- attr = points;
- } else if (points != null) {
- attr = {points: points};
- }
- return this.el("polyline", attr);
- };
- /*\
- * Paper.polygon
- [ method ]
- **
- * Draws a polygon. See @Paper.polyline
- \*/
- proto.polygon = function (points) {
- if (arguments.length > 1) {
- points = Array.prototype.slice.call(arguments, 0);
- }
- var attr = {};
- if (is(points, "object") && !is(points, "array")) {
- attr = points;
- } else if (points != null) {
- attr = {points: points};
- }
- return this.el("polygon", attr);
- };
- // gradients
- (function () {
- var $ = Snap._.$;
- // gradients' helpers
- function Gstops() {
- return this.selectAll("stop");
- }
- function GaddStop(color, offset) {
- var stop = $("stop"),
- attr = {
- offset: +offset + "%"
- };
- color = Snap.color(color);
- attr["stop-color"] = color.hex;
- if (color.opacity < 1) {
- attr["stop-opacity"] = color.opacity;
- }
- $(stop, attr);
- this.node.appendChild(stop);
- return this;
- }
- function GgetBBox() {
- if (this.type == "linearGradient") {
- var x1 = $(this.node, "x1") || 0,
- x2 = $(this.node, "x2") || 1,
- y1 = $(this.node, "y1") || 0,
- y2 = $(this.node, "y2") || 0;
- return Snap._.box(x1, y1, math.abs(x2 - x1), math.abs(y2 - y1));
- } else {
- var cx = this.node.cx || .5,
- cy = this.node.cy || .5,
- r = this.node.r || 0;
- return Snap._.box(cx - r, cy - r, r * 2, r * 2);
- }
- }
- function gradient(defs, str) {
- var grad = eve("snap.util.grad.parse", null, str).firstDefined(),
- el;
- if (!grad) {
- return null;
- }
- grad.params.unshift(defs);
- if (grad.type.toLowerCase() == "l") {
- el = gradientLinear.apply(0, grad.params);
- } else {
- el = gradientRadial.apply(0, grad.params);
- }
- if (grad.type != grad.type.toLowerCase()) {
- $(el.node, {
- gradientUnits: "userSpaceOnUse"
- });
- }
- var stops = grad.stops,
- len = stops.length,
- start = 0,
- j = 0;
- function seed(i, end) {
- var step = (end - start) / (i - j);
- for (var k = j; k < i; k++) {
- stops[k].offset = +(+start + step * (k - j)).toFixed(2);
- }
- j = i;
- start = end;
- }
- len--;
- for (var i = 0; i < len; i++) if ("offset" in stops[i]) {
- seed(i, stops[i].offset);
- }
- stops[len].offset = stops[len].offset || 100;
- seed(len, stops[len].offset);
- for (i = 0; i <= len; i++) {
- var stop = stops[i];
- el.addStop(stop.color, stop.offset);
- }
- return el;
- }
- function gradientLinear(defs, x1, y1, x2, y2) {
- var el = Snap._.make("linearGradient", defs);
- el.stops = Gstops;
- el.addStop = GaddStop;
- el.getBBox = GgetBBox;
- if (x1 != null) {
- $(el.node, {
- x1: x1,
- y1: y1,
- x2: x2,
- y2: y2
- });
- }
- return el;
- }
- function gradientRadial(defs, cx, cy, r, fx, fy) {
- var el = Snap._.make("radialGradient", defs);
- el.stops = Gstops;
- el.addStop = GaddStop;
- el.getBBox = GgetBBox;
- if (cx != null) {
- $(el.node, {
- cx: cx,
- cy: cy,
- r: r
- });
- }
- if (fx != null && fy != null) {
- $(el.node, {
- fx: fx,
- fy: fy
- });
- }
- return el;
- }
- /*\
- * Paper.gradient
- [ method ]
- **
- * Creates a gradient element
- **
- - gradient (string) gradient descriptor
- > Gradient Descriptor
- * The gradient descriptor is an expression formatted as
- * follows: `<type>(<coords>)<colors>`. The `<type>` can be
- * either linear or radial. The uppercase `L` or `R` letters
- * indicate absolute coordinates offset from the SVG surface.
- * Lowercase `l` or `r` letters indicate coordinates
- * calculated relative to the element to which the gradient is
- * applied. Coordinates specify a linear gradient vector as
- * `x1`, `y1`, `x2`, `y2`, or a radial gradient as `cx`, `cy`,
- * `r` and optional `fx`, `fy` specifying a focal point away
- * from the center of the circle. Specify `<colors>` as a list
- * of dash-separated CSS color values. Each color may be
- * followed by a custom offset value, separated with a colon
- * character.
- > Examples
- * Linear gradient, relative from top-left corner to bottom-right
- * corner, from black through red to white:
- | var g = paper.gradient("l(0, 0, 1, 1)#000-#f00-#fff");
- * Linear gradient, absolute from (0, 0) to (100, 100), from black
- * through red at 25% to white:
- | var g = paper.gradient("L(0, 0, 100, 100)#000-#f00:25-#fff");
- * Radial gradient, relative from the center of the element with radius
- * half the width, from black to white:
- | var g = paper.gradient("r(0.5, 0.5, 0.5)#000-#fff");
- * To apply the gradient:
- | paper.circle(50, 50, 40).attr({
- | fill: g
- | });
- = (object) the `gradient` element
- \*/
- proto.gradient = function (str) {
- return gradient(this.defs, str);
- };
- proto.gradientLinear = function (x1, y1, x2, y2) {
- return gradientLinear(this.defs, x1, y1, x2, y2);
- };
- proto.gradientRadial = function (cx, cy, r, fx, fy) {
- return gradientRadial(this.defs, cx, cy, r, fx, fy);
- };
- /*\
- * Paper.toString
- [ method ]
- **
- * Returns SVG code for the @Paper
- = (string) SVG code for the @Paper
- \*/
- proto.toString = function () {
- var doc = this.node.ownerDocument,
- f = doc.createDocumentFragment(),
- d = doc.createElement("div"),
- svg = this.node.cloneNode(true),
- res;
- f.appendChild(d);
- d.appendChild(svg);
- Snap._.$(svg, {xmlns: "http://www.w3.org/2000/svg"});
- res = d.innerHTML;
- 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 ]
- **
- * Removes all child nodes of the paper, except <defs>.
- \*/
- proto.clear = function () {
- var node = this.node.firstChild,
- next;
- while (node) {
- next = node.nextSibling;
- if (node.tagName != "defs") {
- node.parentNode.removeChild(node);
- } else {
- proto.clear.call({node: node});
- }
- node = next;
- }
- };
- }());
-});
-
-// 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) {
- var elproto = Element.prototype,
- is = Snap.is,
- clone = Snap._.clone,
- has = "hasOwnProperty",
- p2s = /,?([a-z]),?/gi,
- toFloat = parseFloat,
- math = Math,
- PI = math.PI,
- mmin = math.min,
- mmax = math.max,
- pow = math.pow,
- abs = math.abs;
- function paths(ps) {
- var p = paths.ps = paths.ps || {};
- if (p[ps]) {
- p[ps].sleep = 100;
- } else {
- p[ps] = {
- sleep: 100
- };
- }
- setTimeout(function () {
- for (var key in p) if (p[has](key) && key != ps) {
- p[key].sleep--;
- !p[key].sleep && delete p[key];
- }
- });
- return p[ps];
- }
- function box(x, y, width, height) {
- if (x == null) {
- x = y = width = height = 0;
- }
- if (y == null) {
- y = x.y;
- width = x.width;
- height = x.height;
- x = x.x;
- }
- return {
- x: x,
- y: y,
- width: width,
- w: width,
- height: height,
- h: height,
- x2: x + width,
- y2: y + height,
- cx: x + width / 2,
- cy: y + height / 2,
- r1: math.min(width, height) / 2,
- r2: math.max(width, height) / 2,
- r0: math.sqrt(width * width + height * height) / 2,
- path: rectPath(x, y, width, height),
- vb: [x, y, width, height].join(" ")
- };
- }
- function toString() {
- return this.join(",").replace(p2s, "$1");
- }
- function pathClone(pathArray) {
- var res = clone(pathArray);
- res.toString = toString;
- return res;
- }
- function getPointAtSegmentLength(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) {
- if (length == null) {
- return bezlen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y);
- } else {
- return findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y,
- getTotLen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length));
- }
- }
- function getLengthFactory(istotal, subpath) {
- function O(val) {
- return +(+val).toFixed(3);
- }
- return Snap._.cacher(function (path, length, onlystart) {
- if (path instanceof Element) {
- path = path.attr("d");
- }
- path = path2curve(path);
- var x, y, p, l, sp = "", subpaths = {}, point,
- len = 0;
- for (var i = 0, ii = path.length; i < ii; i++) {
- p = path[i];
- if (p[0] == "M") {
- x = +p[1];
- y = +p[2];
- } else {
- l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);
- if (len + l > length) {
- if (subpath && !subpaths.start) {
- point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);
- sp += [
- "C" + O(point.start.x),
- O(point.start.y),
- O(point.m.x),
- O(point.m.y),
- O(point.x),
- O(point.y)
- ];
- if (onlystart) {return sp;}
- subpaths.start = sp;
- sp = [
- "M" + O(point.x),
- O(point.y) + "C" + O(point.n.x),
- O(point.n.y),
- O(point.end.x),
- O(point.end.y),
- O(p[5]),
- O(p[6])
- ].join();
- len += l;
- x = +p[5];
- y = +p[6];
- continue;
- }
- if (!istotal && !subpath) {
- point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);
- return point;
- }
- }
- len += l;
- x = +p[5];
- y = +p[6];
- }
- sp += p.shift() + p;
- }
- subpaths.end = sp;
- point = istotal ? len : subpath ? subpaths : findDotsAtSegment(x, y, p[0], p[1], p[2], p[3], p[4], p[5], 1);
- return point;
- }, null, Snap._.clone);
- }
- var getTotalLength = getLengthFactory(1),
- getPointAtLength = getLengthFactory(),
- getSubpathsAtLength = getLengthFactory(0, 1);
- function findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
- var t1 = 1 - t,
- t13 = pow(t1, 3),
- t12 = pow(t1, 2),
- t2 = t * t,
- t3 = t2 * t,
- x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x,
- y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y,
- mx = p1x + 2 * t * (c1x - p1x) + t2 * (c2x - 2 * c1x + p1x),
- my = p1y + 2 * t * (c1y - p1y) + t2 * (c2y - 2 * c1y + p1y),
- nx = c1x + 2 * t * (c2x - c1x) + t2 * (p2x - 2 * c2x + c1x),
- ny = c1y + 2 * t * (c2y - c1y) + t2 * (p2y - 2 * c2y + c1y),
- ax = t1 * p1x + t * c1x,
- ay = t1 * p1y + t * c1y,
- cx = t1 * c2x + t * p2x,
- cy = t1 * c2y + t * p2y,
- alpha = (90 - math.atan2(mx - nx, my - ny) * 180 / PI);
- // (mx > nx || my < ny) && (alpha += 180);
- return {
- x: x,
- y: y,
- m: {x: mx, y: my},
- n: {x: nx, y: ny},
- start: {x: ax, y: ay},
- end: {x: cx, y: cy},
- alpha: alpha
- };
- }
- function bezierBBox(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
- if (!Snap.is(p1x, "array")) {
- p1x = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y];
- }
- var bbox = curveDim.apply(null, p1x);
- return box(
- bbox.min.x,
- bbox.min.y,
- bbox.max.x - bbox.min.x,
- bbox.max.y - bbox.min.y
- );
- }
- function isPointInsideBBox(bbox, x, y) {
- return x >= bbox.x &&
- x <= bbox.x + bbox.width &&
- y >= bbox.y &&
- y <= bbox.y + bbox.height;
- }
- function isBBoxIntersect(bbox1, bbox2) {
- bbox1 = box(bbox1);
- bbox2 = box(bbox2);
- return isPointInsideBBox(bbox2, bbox1.x, bbox1.y)
- || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y)
- || isPointInsideBBox(bbox2, bbox1.x, bbox1.y2)
- || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y2)
- || isPointInsideBBox(bbox1, bbox2.x, bbox2.y)
- || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y)
- || isPointInsideBBox(bbox1, bbox2.x, bbox2.y2)
- || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y2)
- || (bbox1.x < bbox2.x2 && bbox1.x > bbox2.x
- || bbox2.x < bbox1.x2 && bbox2.x > bbox1.x)
- && (bbox1.y < bbox2.y2 && bbox1.y > bbox2.y
- || bbox2.y < bbox1.y2 && bbox2.y > bbox1.y);
- }
- function base3(t, p1, p2, p3, p4) {
- var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4,
- t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3;
- return t * t2 - 3 * p1 + 3 * p2;
- }
- function bezlen(x1, y1, x2, y2, x3, y3, x4, y4, z) {
- if (z == null) {
- z = 1;
- }
- z = z > 1 ? 1 : z < 0 ? 0 : z;
- var z2 = z / 2,
- n = 12,
- Tvalues = [-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],
- Cvalues = [0.2491,0.2491,0.2335,0.2335,0.2032,0.2032,0.1601,0.1601,0.1069,0.1069,0.0472,0.0472],
- sum = 0;
- for (var i = 0; i < n; i++) {
- var ct = z2 * Tvalues[i] + z2,
- xbase = base3(ct, x1, x2, x3, x4),
- ybase = base3(ct, y1, y2, y3, y4),
- comb = xbase * xbase + ybase * ybase;
- sum += Cvalues[i] * math.sqrt(comb);
- }
- return z2 * sum;
- }
- function getTotLen(x1, y1, x2, y2, x3, y3, x4, y4, ll) {
- if (ll < 0 || bezlen(x1, y1, x2, y2, x3, y3, x4, y4) < ll) {
- return;
- }
- var t = 1,
- step = t / 2,
- t2 = t - step,
- l,
- e = .01;
- l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2);
- while (abs(l - ll) > e) {
- step /= 2;
- t2 += (l < ll ? 1 : -1) * step;
- l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2);
- }
- return t2;
- }
- function intersect(x1, y1, x2, y2, x3, y3, x4, y4) {
- if (
- mmax(x1, x2) < mmin(x3, x4) ||
- mmin(x1, x2) > mmax(x3, x4) ||
- mmax(y1, y2) < mmin(y3, y4) ||
- mmin(y1, y2) > mmax(y3, y4)
- ) {
- return;
- }
- var nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4),
- ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4),
- denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
-
- if (!denominator) {
- return;
- }
- var px = nx / denominator,
- py = ny / denominator,
- px2 = +px.toFixed(2),
- py2 = +py.toFixed(2);
- if (
- px2 < +mmin(x1, x2).toFixed(2) ||
- px2 > +mmax(x1, x2).toFixed(2) ||
- px2 < +mmin(x3, x4).toFixed(2) ||
- px2 > +mmax(x3, x4).toFixed(2) ||
- py2 < +mmin(y1, y2).toFixed(2) ||
- py2 > +mmax(y1, y2).toFixed(2) ||
- py2 < +mmin(y3, y4).toFixed(2) ||
- py2 > +mmax(y3, y4).toFixed(2)
- ) {
- return;
- }
- return {x: px, y: py};
- }
- function inter(bez1, bez2) {
- return interHelper(bez1, bez2);
- }
- function interCount(bez1, bez2) {
- return interHelper(bez1, bez2, 1);
- }
- function interHelper(bez1, bez2, justCount) {
- var bbox1 = bezierBBox(bez1),
- bbox2 = bezierBBox(bez2);
- if (!isBBoxIntersect(bbox1, bbox2)) {
- return justCount ? 0 : [];
- }
- var l1 = bezlen.apply(0, bez1),
- l2 = bezlen.apply(0, bez2),
- n1 = ~~(l1 / 8),
- n2 = ~~(l2 / 8),
- dots1 = [],
- dots2 = [],
- xy = {},
- res = justCount ? 0 : [];
- for (var i = 0; i < n1 + 1; i++) {
- var p = findDotsAtSegment.apply(0, bez1.concat(i / n1));
- dots1.push({x: p.x, y: p.y, t: i / n1});
- }
- for (i = 0; i < n2 + 1; i++) {
- p = findDotsAtSegment.apply(0, bez2.concat(i / n2));
- dots2.push({x: p.x, y: p.y, t: i / n2});
- }
- for (i = 0; i < n1; i++) {
- for (var j = 0; j < n2; j++) {
- var di = dots1[i],
- di1 = dots1[i + 1],
- dj = dots2[j],
- dj1 = dots2[j + 1],
- ci = abs(di1.x - di.x) < .001 ? "y" : "x",
- cj = abs(dj1.x - dj.x) < .001 ? "y" : "x",
- is = intersect(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y);
- if (is) {
- if (xy[is.x.toFixed(4)] == is.y.toFixed(4)) {
- continue;
- }
- xy[is.x.toFixed(4)] = is.y.toFixed(4);
- var t1 = di.t + abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t),
- t2 = dj.t + abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t);
- if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) {
- if (justCount) {
- res++;
- } else {
- res.push({
- x: is.x,
- y: is.y,
- t1: t1,
- t2: t2
- });
- }
- }
- }
- }
- }
- return res;
- }
- function pathIntersection(path1, path2) {
- return interPathHelper(path1, path2);
- }
- function pathIntersectionNumber(path1, path2) {
- return interPathHelper(path1, path2, 1);
- }
- function interPathHelper(path1, path2, justCount) {
- path1 = path2curve(path1);
- path2 = path2curve(path2);
- var x1, y1, x2, y2, x1m, y1m, x2m, y2m, bez1, bez2,
- res = justCount ? 0 : [];
- for (var i = 0, ii = path1.length; i < ii; i++) {
- var pi = path1[i];
- if (pi[0] == "M") {
- x1 = x1m = pi[1];
- y1 = y1m = pi[2];
- } else {
- if (pi[0] == "C") {
- bez1 = [x1, y1].concat(pi.slice(1));
- x1 = bez1[6];
- y1 = bez1[7];
- } else {
- bez1 = [x1, y1, x1, y1, x1m, y1m, x1m, y1m];
- x1 = x1m;
- y1 = y1m;
- }
- for (var j = 0, jj = path2.length; j < jj; j++) {
- var pj = path2[j];
- if (pj[0] == "M") {
- x2 = x2m = pj[1];
- y2 = y2m = pj[2];
- } else {
- if (pj[0] == "C") {
- bez2 = [x2, y2].concat(pj.slice(1));
- x2 = bez2[6];
- y2 = bez2[7];
- } else {
- bez2 = [x2, y2, x2, y2, x2m, y2m, x2m, y2m];
- x2 = x2m;
- y2 = y2m;
- }
- var intr = interHelper(bez1, bez2, justCount);
- if (justCount) {
- res += intr;
- } else {
- for (var k = 0, kk = intr.length; k < kk; k++) {
- intr[k].segment1 = i;
- intr[k].segment2 = j;
- intr[k].bez1 = bez1;
- intr[k].bez2 = bez2;
- }
- res = res.concat(intr);
- }
- }
- }
- }
- }
- return res;
- }
- function isPointInsidePath(path, x, y) {
- var bbox = pathBBox(path);
- return isPointInsideBBox(bbox, x, y) &&
- interPathHelper(path, [["M", x, y], ["H", bbox.x2 + 10]], 1) % 2 == 1;
- }
- function pathBBox(path) {
- var pth = paths(path);
- if (pth.bbox) {
- return clone(pth.bbox);
- }
- if (!path) {
- return box();
- }
- path = path2curve(path);
- var x = 0,
- y = 0,
- X = [],
- Y = [],
- p;
- for (var i = 0, ii = path.length; i < ii; i++) {
- p = path[i];
- if (p[0] == "M") {
- x = p[1];
- y = p[2];
- X.push(x);
- Y.push(y);
- } else {
- var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);
- X = X.concat(dim.min.x, dim.max.x);
- Y = Y.concat(dim.min.y, dim.max.y);
- x = p[5];
- y = p[6];
- }
- }
- var xmin = mmin.apply(0, X),
- ymin = mmin.apply(0, Y),
- xmax = mmax.apply(0, X),
- ymax = mmax.apply(0, Y),
- bb = box(xmin, ymin, xmax - xmin, ymax - ymin);
- pth.bbox = clone(bb);
- return bb;
- }
- function rectPath(x, y, w, h, r) {
- if (r) {
- return [
- ["M", +x + (+r), y],
- ["l", w - r * 2, 0],
- ["a", r, r, 0, 0, 1, r, r],
- ["l", 0, h - r * 2],
- ["a", r, r, 0, 0, 1, -r, r],
- ["l", r * 2 - w, 0],
- ["a", r, r, 0, 0, 1, -r, -r],
- ["l", 0, r * 2 - h],
- ["a", r, r, 0, 0, 1, r, -r],
- ["z"]
- ];
- }
- var res = [["M", x, y], ["l", w, 0], ["l", 0, h], ["l", -w, 0], ["z"]];
- res.toString = toString;
- return res;
- }
- function ellipsePath(x, y, rx, ry, a) {
- if (a == null && ry == null) {
- ry = rx;
- }
- x = +x;
- y = +y;
- rx = +rx;
- ry = +ry;
- if (a != null) {
- var rad = Math.PI / 180,
- x1 = x + rx * Math.cos(-ry * rad),
- x2 = x + rx * Math.cos(-a * rad),
- y1 = y + rx * Math.sin(-ry * rad),
- y2 = y + rx * Math.sin(-a * rad),
- res = [["M", x1, y1], ["A", rx, rx, 0, +(a - ry > 180), 0, x2, y2]];
- } else {
- res = [
- ["M", x, y],
- ["m", 0, -ry],
- ["a", rx, ry, 0, 1, 1, 0, 2 * ry],
- ["a", rx, ry, 0, 1, 1, 0, -2 * ry],
- ["z"]
- ];
- }
- res.toString = toString;
- return res;
- }
- var unit2px = Snap._unit2px,
- getPath = {
- path: function (el) {
- return el.attr("path");
- },
- circle: function (el) {
- var attr = unit2px(el);
- return ellipsePath(attr.cx, attr.cy, attr.r);
- },
- ellipse: function (el) {
- var attr = unit2px(el);
- return ellipsePath(attr.cx || 0, attr.cy || 0, attr.rx, attr.ry);
- },
- rect: function (el) {
- var attr = unit2px(el);
- return rectPath(attr.x || 0, attr.y || 0, attr.width, attr.height, attr.rx, attr.ry);
- },
- image: function (el) {
- var attr = unit2px(el);
- return rectPath(attr.x || 0, attr.y || 0, attr.width, attr.height);
- },
- line: function (el) {
- return "M" + [el.attr("x1") || 0, el.attr("y1") || 0, el.attr("x2"), el.attr("y2")];
- },
- polyline: function (el) {
- return "M" + el.attr("points");
- },
- polygon: function (el) {
- return "M" + el.attr("points") + "z";
- },
- deflt: function (el) {
- var bbox = el.node.getBBox();
- return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);
- }
- };
- function pathToRelative(pathArray) {
- var pth = paths(pathArray),
- lowerCase = String.prototype.toLowerCase;
- if (pth.rel) {
- return pathClone(pth.rel);
- }
- if (!Snap.is(pathArray, "array") || !Snap.is(pathArray && pathArray[0], "array")) {
- pathArray = Snap.parsePathString(pathArray);
- }
- var res = [],
- x = 0,
- y = 0,
- mx = 0,
- my = 0,
- start = 0;
- if (pathArray[0][0] == "M") {
- x = pathArray[0][1];
- y = pathArray[0][2];
- mx = x;
- my = y;
- start++;
- res.push(["M", x, y]);
- }
- for (var i = start, ii = pathArray.length; i < ii; i++) {
- var r = res[i] = [],
- pa = pathArray[i];
- if (pa[0] != lowerCase.call(pa[0])) {
- r[0] = lowerCase.call(pa[0]);
- switch (r[0]) {
- case "a":
- r[1] = pa[1];
- r[2] = pa[2];
- r[3] = pa[3];
- r[4] = pa[4];
- r[5] = pa[5];
- r[6] = +(pa[6] - x).toFixed(3);
- r[7] = +(pa[7] - y).toFixed(3);
- break;
- case "v":
- r[1] = +(pa[1] - y).toFixed(3);
- break;
- case "m":
- mx = pa[1];
- my = pa[2];
- default:
- for (var j = 1, jj = pa.length; j < jj; j++) {
- r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3);
- }
- }
- } else {
- r = res[i] = [];
- if (pa[0] == "m") {
- mx = pa[1] + x;
- my = pa[2] + y;
- }
- for (var k = 0, kk = pa.length; k < kk; k++) {
- res[i][k] = pa[k];
- }
- }
- var len = res[i].length;
- switch (res[i][0]) {
- case "z":
- x = mx;
- y = my;
- break;
- case "h":
- x += +res[i][len - 1];
- break;
- case "v":
- y += +res[i][len - 1];
- break;
- default:
- x += +res[i][len - 2];
- y += +res[i][len - 1];
- }
- }
- res.toString = toString;
- pth.rel = pathClone(res);
- return res;
- }
- function pathToAbsolute(pathArray) {
- var pth = paths(pathArray);
- if (pth.abs) {
- return pathClone(pth.abs);
- }
- if (!is(pathArray, "array") || !is(pathArray && pathArray[0], "array")) { // rough assumption
- pathArray = Snap.parsePathString(pathArray);
- }
- if (!pathArray || !pathArray.length) {
- return [["M", 0, 0]];
- }
- var res = [],
- x = 0,
- y = 0,
- mx = 0,
- my = 0,
- start = 0,
- pa0;
- if (pathArray[0][0] == "M") {
- x = +pathArray[0][1];
- y = +pathArray[0][2];
- mx = x;
- my = y;
- start++;
- res[0] = ["M", x, y];
- }
- var crz = pathArray.length == 3 &&
- pathArray[0][0] == "M" &&
- pathArray[1][0].toUpperCase() == "R" &&
- pathArray[2][0].toUpperCase() == "Z";
- for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) {
- res.push(r = []);
- pa = pathArray[i];
- pa0 = pa[0];
- if (pa0 != pa0.toUpperCase()) {
- r[0] = pa0.toUpperCase();
- switch (r[0]) {
- case "A":
- r[1] = pa[1];
- r[2] = pa[2];
- r[3] = pa[3];
- r[4] = pa[4];
- r[5] = pa[5];
- r[6] = +pa[6] + x;
- r[7] = +pa[7] + y;
- break;
- case "V":
- r[1] = +pa[1] + y;
- break;
- case "H":
- r[1] = +pa[1] + x;
- break;
- case "R":
- var dots = [x, y].concat(pa.slice(1));
- for (var j = 2, jj = dots.length; j < jj; j++) {
- dots[j] = +dots[j] + x;
- dots[++j] = +dots[j] + y;
- }
- res.pop();
- res = res.concat(catmullRom2bezier(dots, crz));
- break;
- case "O":
- res.pop();
- dots = ellipsePath(x, y, pa[1], pa[2]);
- dots.push(dots[0]);
- res = res.concat(dots);
- break;
- case "U":
- res.pop();
- res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3]));
- r = ["U"].concat(res[res.length - 1].slice(-2));
- break;
- case "M":
- mx = +pa[1] + x;
- my = +pa[2] + y;
- default:
- for (j = 1, jj = pa.length; j < jj; j++) {
- r[j] = +pa[j] + ((j % 2) ? x : y);
- }
- }
- } else if (pa0 == "R") {
- dots = [x, y].concat(pa.slice(1));
- res.pop();
- res = res.concat(catmullRom2bezier(dots, crz));
- r = ["R"].concat(pa.slice(-2));
- } else if (pa0 == "O") {
- res.pop();
- dots = ellipsePath(x, y, pa[1], pa[2]);
- dots.push(dots[0]);
- res = res.concat(dots);
- } else if (pa0 == "U") {
- res.pop();
- res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3]));
- r = ["U"].concat(res[res.length - 1].slice(-2));
- } else {
- for (var k = 0, kk = pa.length; k < kk; k++) {
- r[k] = pa[k];
- }
- }
- pa0 = pa0.toUpperCase();
- if (pa0 != "O") {
- switch (r[0]) {
- case "Z":
- x = +mx;
- y = +my;
- break;
- case "H":
- x = r[1];
- break;
- case "V":
- y = r[1];
- break;
- case "M":
- mx = r[r.length - 2];
- my = r[r.length - 1];
- default:
- x = r[r.length - 2];
- y = r[r.length - 1];
- }
- }
- }
- res.toString = toString;
- pth.abs = pathClone(res);
- return res;
- }
- function l2c(x1, y1, x2, y2) {
- return [x1, y1, x2, y2, x2, y2];
- }
- function q2c(x1, y1, ax, ay, x2, y2) {
- var _13 = 1 / 3,
- _23 = 2 / 3;
- return [
- _13 * x1 + _23 * ax,
- _13 * y1 + _23 * ay,
- _13 * x2 + _23 * ax,
- _13 * y2 + _23 * ay,
- x2,
- y2
- ];
- }
- function a2c(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {
- // for more information of where this math came from visit:
- // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
- var _120 = PI * 120 / 180,
- rad = PI / 180 * (+angle || 0),
- res = [],
- xy,
- rotate = Snap._.cacher(function (x, y, rad) {
- var X = x * math.cos(rad) - y * math.sin(rad),
- Y = x * math.sin(rad) + y * math.cos(rad);
- return {x: X, y: Y};
- });
- if (!recursive) {
- xy = rotate(x1, y1, -rad);
- x1 = xy.x;
- y1 = xy.y;
- xy = rotate(x2, y2, -rad);
- x2 = xy.x;
- y2 = xy.y;
- var cos = math.cos(PI / 180 * angle),
- sin = math.sin(PI / 180 * angle),
- x = (x1 - x2) / 2,
- y = (y1 - y2) / 2;
- var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
- if (h > 1) {
- h = math.sqrt(h);
- rx = h * rx;
- ry = h * ry;
- }
- var rx2 = rx * rx,
- ry2 = ry * ry,
- k = (large_arc_flag == sweep_flag ? -1 : 1) *
- math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),
- cx = k * rx * y / ry + (x1 + x2) / 2,
- cy = k * -ry * x / rx + (y1 + y2) / 2,
- f1 = math.asin(((y1 - cy) / ry).toFixed(9)),
- f2 = math.asin(((y2 - cy) / ry).toFixed(9));
-
- f1 = x1 < cx ? PI - f1 : f1;
- f2 = x2 < cx ? PI - f2 : f2;
- f1 < 0 && (f1 = PI * 2 + f1);
- f2 < 0 && (f2 = PI * 2 + f2);
- if (sweep_flag && f1 > f2) {
- f1 = f1 - PI * 2;
- }
- if (!sweep_flag && f2 > f1) {
- f2 = f2 - PI * 2;
- }
- } else {
- f1 = recursive[0];
- f2 = recursive[1];
- cx = recursive[2];
- cy = recursive[3];
- }
- var df = f2 - f1;
- if (abs(df) > _120) {
- var f2old = f2,
- x2old = x2,
- y2old = y2;
- f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
- x2 = cx + rx * math.cos(f2);
- y2 = cy + ry * math.sin(f2);
- res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);
- }
- df = f2 - f1;
- var c1 = math.cos(f1),
- s1 = math.sin(f1),
- c2 = math.cos(f2),
- s2 = math.sin(f2),
- t = math.tan(df / 4),
- hx = 4 / 3 * rx * t,
- hy = 4 / 3 * ry * t,
- m1 = [x1, y1],
- m2 = [x1 + hx * s1, y1 - hy * c1],
- m3 = [x2 + hx * s2, y2 - hy * c2],
- m4 = [x2, y2];
- m2[0] = 2 * m1[0] - m2[0];
- m2[1] = 2 * m1[1] - m2[1];
- if (recursive) {
- return [m2, m3, m4].concat(res);
- } else {
- res = [m2, m3, m4].concat(res).join().split(",");
- var newres = [];
- for (var i = 0, ii = res.length; i < ii; i++) {
- newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;
- }
- return newres;
- }
- }
- function findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
- var t1 = 1 - t;
- return {
- x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,
- y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y
- };
- }
-
- // Returns bounding box of cubic bezier curve.
- // Source: http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
- // Original version: NISHIO Hirokazu
- // Modifications: https://github.com/timo22345
- function curveDim(x0, y0, x1, y1, x2, y2, x3, y3) {
- var tvalues = [],
- bounds = [[], []],
- a, b, c, t, t1, t2, b2ac, sqrtb2ac;
- for (var i = 0; i < 2; ++i) {
- if (i == 0) {
- b = 6 * x0 - 12 * x1 + 6 * x2;
- a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;
- c = 3 * x1 - 3 * x0;
- } else {
- b = 6 * y0 - 12 * y1 + 6 * y2;
- a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;
- c = 3 * y1 - 3 * y0;
- }
- if (abs(a) < 1e-12) {
- if (abs(b) < 1e-12) {
- continue;
- }
- t = -c / b;
- if (0 < t && t < 1) {
- tvalues.push(t);
- }
- continue;
- }
- b2ac = b * b - 4 * c * a;
- sqrtb2ac = math.sqrt(b2ac);
- if (b2ac < 0) {
- continue;
- }
- t1 = (-b + sqrtb2ac) / (2 * a);
- if (0 < t1 && t1 < 1) {
- tvalues.push(t1);
- }
- t2 = (-b - sqrtb2ac) / (2 * a);
- if (0 < t2 && t2 < 1) {
- tvalues.push(t2);
- }
- }
-
- var x, y, j = tvalues.length,
- jlen = j,
- mt;
- while (j--) {
- t = tvalues[j];
- mt = 1 - t;
- bounds[0][j] = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);
- bounds[1][j] = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);
- }
-
- bounds[0][jlen] = x0;
- bounds[1][jlen] = y0;
- bounds[0][jlen + 1] = x3;
- bounds[1][jlen + 1] = y3;
- bounds[0].length = bounds[1].length = jlen + 2;
-
-
- return {
- min: {x: mmin.apply(0, bounds[0]), y: mmin.apply(0, bounds[1])},
- max: {x: mmax.apply(0, bounds[0]), y: mmax.apply(0, bounds[1])}
- };
- }
-
- function path2curve(path, path2) {
- var pth = !path2 && paths(path);
- if (!path2 && pth.curve) {
- return pathClone(pth.curve);
- }
- var p = pathToAbsolute(path),
- p2 = path2 && pathToAbsolute(path2),
- attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},
- attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},
- processPath = function (path, d, pcom) {
- var nx, ny;
- if (!path) {
- return ["C", d.x, d.y, d.x, d.y, d.x, d.y];
- }
- !(path[0] in {T: 1, Q: 1}) && (d.qx = d.qy = null);
- switch (path[0]) {
- case "M":
- d.X = path[1];
- d.Y = path[2];
- break;
- case "A":
- path = ["C"].concat(a2c.apply(0, [d.x, d.y].concat(path.slice(1))));
- break;
- case "S":
- if (pcom == "C" || pcom == "S") { // In "S" case we have to take into account, if the previous command is C/S.
- nx = d.x * 2 - d.bx; // And reflect the previous
- ny = d.y * 2 - d.by; // command's control point relative to the current point.
- }
- else { // or some else or nothing
- nx = d.x;
- ny = d.y;
- }
- path = ["C", nx, ny].concat(path.slice(1));
- break;
- case "T":
- if (pcom == "Q" || pcom == "T") { // In "T" case we have to take into account, if the previous command is Q/T.
- d.qx = d.x * 2 - d.qx; // And make a reflection similar
- d.qy = d.y * 2 - d.qy; // to case "S".
- }
- else { // or something else or nothing
- d.qx = d.x;
- d.qy = d.y;
- }
- path = ["C"].concat(q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));
- break;
- case "Q":
- d.qx = path[1];
- d.qy = path[2];
- path = ["C"].concat(q2c(d.x, d.y, path[1], path[2], path[3], path[4]));
- break;
- case "L":
- path = ["C"].concat(l2c(d.x, d.y, path[1], path[2]));
- break;
- case "H":
- path = ["C"].concat(l2c(d.x, d.y, path[1], d.y));
- break;
- case "V":
- path = ["C"].concat(l2c(d.x, d.y, d.x, path[1]));
- break;
- case "Z":
- path = ["C"].concat(l2c(d.x, d.y, d.X, d.Y));
- break;
- }
- return path;
- },
- fixArc = function (pp, i) {
- if (pp[i].length > 7) {
- pp[i].shift();
- var pi = pp[i];
- while (pi.length) {
- pcoms1[i] = "A"; // if created multiple C:s, their original seg is saved
- p2 && (pcoms2[i] = "A"); // the same as above
- pp.splice(i++, 0, ["C"].concat(pi.splice(0, 6)));
- }
- pp.splice(i, 1);
- ii = mmax(p.length, p2 && p2.length || 0);
- }
- },
- fixM = function (path1, path2, a1, a2, i) {
- if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") {
- path2.splice(i, 0, ["M", a2.x, a2.y]);
- a1.bx = 0;
- a1.by = 0;
- a1.x = path1[i][1];
- a1.y = path1[i][2];
- ii = mmax(p.length, p2 && p2.length || 0);
- }
- },
- pcoms1 = [], // path commands of original path p
- pcoms2 = [], // path commands of original path p2
- pfirst = "", // temporary holder for original path command
- pcom = ""; // holder for previous path command of original path
- for (var i = 0, ii = mmax(p.length, p2 && p2.length || 0); i < ii; i++) {
- p[i] && (pfirst = p[i][0]); // save current path command
-
- if (pfirst != "C") // C is not saved yet, because it may be result of conversion
- {
- pcoms1[i] = pfirst; // Save current path command
- i && ( pcom = pcoms1[i - 1]); // Get previous path command pcom
- }
- p[i] = processPath(p[i], attrs, pcom); // Previous path command is inputted to processPath
-
- if (pcoms1[i] != "A" && pfirst == "C") pcoms1[i] = "C"; // A is the only command
- // which may produce multiple C:s
- // so we have to make sure that C is also C in original path
-
- fixArc(p, i); // fixArc adds also the right amount of A:s to pcoms1
-
- if (p2) { // the same procedures is done to p2
- p2[i] && (pfirst = p2[i][0]);
- if (pfirst != "C") {
- pcoms2[i] = pfirst;
- i && (pcom = pcoms2[i - 1]);
- }
- p2[i] = processPath(p2[i], attrs2, pcom);
-
- if (pcoms2[i] != "A" && pfirst == "C") {
- pcoms2[i] = "C";
- }
-
- fixArc(p2, i);
- }
- fixM(p, p2, attrs, attrs2, i);
- fixM(p2, p, attrs2, attrs, i);
- var seg = p[i],
- seg2 = p2 && p2[i],
- seglen = seg.length,
- seg2len = p2 && seg2.length;
- attrs.x = seg[seglen - 2];
- attrs.y = seg[seglen - 1];
- attrs.bx = toFloat(seg[seglen - 4]) || attrs.x;
- attrs.by = toFloat(seg[seglen - 3]) || attrs.y;
- attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x);
- attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y);
- attrs2.x = p2 && seg2[seg2len - 2];
- attrs2.y = p2 && seg2[seg2len - 1];
- }
- if (!p2) {
- pth.curve = pathClone(p);
- }
- return p2 ? [p, p2] : p;
- }
- function mapPath(path, matrix) {
- if (!matrix) {
- return path;
- }
- var x, y, i, j, ii, jj, pathi;
- path = path2curve(path);
- for (i = 0, ii = path.length; i < ii; i++) {
- pathi = path[i];
- for (j = 1, jj = pathi.length; j < jj; j += 2) {
- x = matrix.x(pathi[j], pathi[j + 1]);
- y = matrix.y(pathi[j], pathi[j + 1]);
- pathi[j] = x;
- pathi[j + 1] = y;
- }
- }
- return path;
- }
-
- // 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;
- }
-
- // export
- Snap.path = paths;
-
- /*\
- * Snap.path.getTotalLength
- [ method ]
- **
- * Returns the length of the given path in pixels
- **
- - path (string) SVG path string
- **
- = (number) length
- \*/
- Snap.path.getTotalLength = getTotalLength;
- /*\
- * Snap.path.getPointAtLength
- [ method ]
- **
- * Returns the coordinates of the point located at the given length along the given path
- **
- - path (string) SVG path string
- - length (number) length, in pixels, from the start of the path, excluding non-rendering jumps
- **
- = (object) representation of the point:
- o {
- o x: (number) x coordinate,
- o y: (number) y coordinate,
- o alpha: (number) angle of derivative
- o }
- \*/
- Snap.path.getPointAtLength = getPointAtLength;
- /*\
- * Snap.path.getSubpath
- [ method ]
- **
- * Returns the subpath of a given path between given start and end lengths
- **
- - path (string) SVG path string
- - from (number) length, in pixels, from the start of the path to the start of the segment
- - to (number) length, in pixels, from the start of the path to the end of the segment
- **
- = (string) path string definition for the segment
- \*/
- Snap.path.getSubpath = function (path, from, to) {
- if (this.getTotalLength(path) - to < 1e-6) {
- return getSubpathsAtLength(path, from).end;
- }
- var a = getSubpathsAtLength(path, to, 1);
- return from ? getSubpathsAtLength(a, from).end : a;
- };
- /*\
- * Element.getTotalLength
- [ method ]
- **
- * Returns the length of the path in pixels (only works for `path` elements)
- = (number) length
- \*/
- elproto.getTotalLength = function () {
- if (this.node.getTotalLength) {
- return this.node.getTotalLength();
- }
- };
- // SIERRA Element.getPointAtLength()/Element.getTotalLength(): If a <path> is broken into different segments, is the jump distance to the new coordinates set by the _M_ or _m_ commands calculated as part of the path's total length?
- /*\
- * Element.getPointAtLength
- [ method ]
- **
- * Returns coordinates of the point located at the given length on the given path (only works for `path` elements)
- **
- - length (number) length, in pixels, from the start of the path, excluding non-rendering jumps
- **
- = (object) representation of the point:
- o {
- o x: (number) x coordinate,
- o y: (number) y coordinate,
- o alpha: (number) angle of derivative
- o }
- \*/
- elproto.getPointAtLength = function (length) {
- return getPointAtLength(this.attr("d"), length);
- };
- // SIERRA Element.getSubpath(): Similar to the problem for Element.getPointAtLength(). Unclear how this would work for a segmented path. Overall, the concept of _subpath_ and what I'm calling a _segment_ (series of non-_M_ or _Z_ commands) is unclear.
- /*\
- * Element.getSubpath
- [ method ]
- **
- * Returns subpath of a given element from given start and end lengths (only works for `path` elements)
- **
- - from (number) length, in pixels, from the start of the path to the start of the segment
- - to (number) length, in pixels, from the start of the path to the end of the segment
- **
- = (string) path string definition for the segment
- \*/
- elproto.getSubpath = function (from, to) {
- return Snap.path.getSubpath(this.attr("d"), from, to);
- };
- Snap._.box = box;
- /*\
- * Snap.path.findDotsAtSegment
- [ method ]
- **
- * Utility method
- **
- * Finds dot coordinates on the given cubic beziér curve at the given t
- - p1x (number) x of the first point of the curve
- - p1y (number) y of the first point of the curve
- - c1x (number) x of the first anchor of the curve
- - c1y (number) y of the first anchor of the curve
- - c2x (number) x of the second anchor of the curve
- - c2y (number) y of the second anchor of the curve
- - p2x (number) x of the second point of the curve
- - p2y (number) y of the second point of the curve
- - t (number) position on the curve (0..1)
- = (object) point information in format:
- o {
- o x: (number) x coordinate of the point,
- o y: (number) y coordinate of the point,
- o m: {
- o x: (number) x coordinate of the left anchor,
- o y: (number) y coordinate of the left anchor
- o },
- o n: {
- o x: (number) x coordinate of the right anchor,
- o y: (number) y coordinate of the right anchor
- o },
- o start: {
- o x: (number) x coordinate of the start of the curve,
- o y: (number) y coordinate of the start of the curve
- o },
- o end: {
- o x: (number) x coordinate of the end of the curve,
- o y: (number) y coordinate of the end of the curve
- o },
- o alpha: (number) angle of the curve derivative at the point
- o }
- \*/
- Snap.path.findDotsAtSegment = findDotsAtSegment;
- /*\
- * Snap.path.bezierBBox
- [ method ]
- **
- * Utility method
- **
- * Returns the bounding box of a given cubic beziér curve
- - p1x (number) x of the first point of the curve
- - p1y (number) y of the first point of the curve
- - c1x (number) x of the first anchor of the curve
- - c1y (number) y of the first anchor of the curve
- - c2x (number) x of the second anchor of the curve
- - c2y (number) y of the second anchor of the curve
- - p2x (number) x of the second point of the curve
- - p2y (number) y of the second point of the curve
- * or
- - bez (array) array of six points for beziér curve
- = (object) bounding box
- o {
- o x: (number) x coordinate of the left top point of the box,
- o y: (number) y coordinate of the left top point of the box,
- o x2: (number) x coordinate of the right bottom point of the box,
- o y2: (number) y coordinate of the right bottom point of the box,
- o width: (number) width of the box,
- o height: (number) height of the box
- o }
- \*/
- Snap.path.bezierBBox = bezierBBox;
- /*\
- * Snap.path.isPointInsideBBox
- [ method ]
- **
- * Utility method
- **
- * Returns `true` if given point is inside bounding box
- - bbox (string) bounding box
- - x (string) x coordinate of the point
- - y (string) y coordinate of the point
- = (boolean) `true` if point is inside
- \*/
- Snap.path.isPointInsideBBox = isPointInsideBBox;
- Snap.closest = function (x, y, X, Y) {
- var r = 100,
- b = box(x - r / 2, y - r / 2, r, r),
- inside = [],
- getter = X[0].hasOwnProperty("x") ? function (i) {
- return {
- x: X[i].x,
- y: X[i].y
- };
- } : function (i) {
- return {
- x: X[i],
- y: Y[i]
- };
- },
- found = 0;
- while (r <= 1e6 && !found) {
- for (var i = 0, ii = X.length; i < ii; i++) {
- var xy = getter(i);
- if (isPointInsideBBox(b, xy.x, xy.y)) {
- found++;
- inside.push(xy);
- break;
- }
- }
- if (!found) {
- r *= 2;
- b = box(x - r / 2, y - r / 2, r, r)
- }
- }
- if (r == 1e6) {
- return;
- }
- var len = Infinity,
- res;
- for (i = 0, ii = inside.length; i < ii; i++) {
- var l = Snap.len(x, y, inside[i].x, inside[i].y);
- if (len > l) {
- len = l;
- inside[i].len = l;
- res = inside[i];
- }
- }
- return res;
- };
- /*\
- * Snap.path.isBBoxIntersect
- [ method ]
- **
- * Utility method
- **
- * Returns `true` if two bounding boxes intersect
- - bbox1 (string) first bounding box
- - bbox2 (string) second bounding box
- = (boolean) `true` if bounding boxes intersect
- \*/
- Snap.path.isBBoxIntersect = isBBoxIntersect;
- /*\
- * Snap.path.intersection
- [ method ]
- **
- * Utility method
- **
- * Finds intersections of two paths
- - path1 (string) path string
- - path2 (string) path string
- = (array) dots of intersection
- o [
- o {
- o x: (number) x coordinate of the point,
- o y: (number) y coordinate of the point,
- o t1: (number) t value for segment of path1,
- o t2: (number) t value for segment of path2,
- o segment1: (number) order number for segment of path1,
- o segment2: (number) order number for segment of path2,
- o bez1: (array) eight coordinates representing beziér curve for the segment of path1,
- o bez2: (array) eight coordinates representing beziér curve for the segment of path2
- o }
- o ]
- \*/
- Snap.path.intersection = pathIntersection;
- Snap.path.intersectionNumber = pathIntersectionNumber;
- /*\
- * Snap.path.isPointInside
- [ method ]
- **
- * Utility method
- **
- * Returns `true` if given point is inside a given closed path.
- *
- * Note: fill mode doesn’t affect the result of this method.
- - path (string) path string
- - x (number) x of the point
- - y (number) y of the point
- = (boolean) `true` if point is inside the path
- \*/
- Snap.path.isPointInside = isPointInsidePath;
- /*\
- * Snap.path.getBBox
- [ method ]
- **
- * Utility method
- **
- * Returns the bounding box of a given path
- - path (string) path string
- = (object) bounding box
- o {
- o x: (number) x coordinate of the left top point of the box,
- o y: (number) y coordinate of the left top point of the box,
- o x2: (number) x coordinate of the right bottom point of the box,
- o y2: (number) y coordinate of the right bottom point of the box,
- o width: (number) width of the box,
- o height: (number) height of the box
- o }
- \*/
- Snap.path.getBBox = pathBBox;
- Snap.path.get = getPath;
- /*\
- * Snap.path.toRelative
- [ method ]
- **
- * Utility method
- **
- * Converts path coordinates into relative values
- - path (string) path string
- = (array) path string
- \*/
- Snap.path.toRelative = pathToRelative;
- /*\
- * Snap.path.toAbsolute
- [ method ]
- **
- * Utility method
- **
- * Converts path coordinates into absolute values
- - path (string) path string
- = (array) path string
- \*/
- Snap.path.toAbsolute = pathToAbsolute;
- /*\
- * Snap.path.toCubic
- [ method ]
- **
- * Utility method
- **
- * Converts path to a new path where all segments are cubic beziér curves
- - pathString (string|array) path string or array of segments
- = (array) array of segments
- \*/
- Snap.path.toCubic = path2curve;
- /*\
- * Snap.path.map
- [ method ]
- **
- * Transform the path string with the given matrix
- - path (string) path string
- - matrix (object) see @Matrix
- = (string) transformed path string
- \*/
- Snap.path.map = mapPath;
- Snap.path.toString = toString;
- Snap.path.clone = pathClone;
-});
-
-// 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) {
- var mmax = Math.max,
- mmin = Math.min;
-
- // Set
- var Set = function (items) {
- this.items = [];
- this.bindings = {};
- 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 the function returns `false`, the loop stops running.
- **
- - 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;
- };
- /*\
- * Set.animate
- [ method ]
- **
- * Animates each element in set in sync.
- *
- **
- - 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
- * or
- - animation (array) array of animation parameter for each element in set in format `[attrs, duration, easing, callback]`
- > Usage
- | // animate all elements in set to radius 10
- | set.animate({r: 10}, 500, mina.easein);
- | // or
- | // animate first element to radius 10, but second to radius 20 and in different time
- | set.animate([{r: 10}, 500, mina.easein], [{r: 20}, 1500, mina.easein]);
- = (Element) the current element
- \*/
- setproto.animate = function (attrs, ms, easing, callback) {
- if (typeof easing == "function" && !easing.length) {
- callback = easing;
- easing = mina.linear;
- }
- if (attrs instanceof Snap._.Animation) {
- callback = attrs.callback;
- easing = attrs.easing;
- ms = easing.dur;
- attrs = attrs.attr;
- }
- var args = arguments;
- if (Snap.is(attrs, "array") && Snap.is(args[args.length - 1], "array")) {
- var each = true;
- }
- var begin,
- handler = function () {
- if (begin) {
- this.b = begin;
- } else {
- begin = this.b;
- }
- },
- cb = 0,
- set = this,
- callbacker = callback && function () {
- if (++cb == set.length) {
- callback.call(this);
- }
- };
- return this.forEach(function (el, i) {
- eve.once("snap.animcreated." + el.id, handler);
- if (each) {
- args[i] && el.animate.apply(el, args[i]);
- } else {
- el.animate(attrs, ms, easing, callbacker);
- }
- });
- };
- setproto.remove = function () {
- while (this.length) {
- this.pop().remove();
- }
- return this;
- };
- /*\
- * Set.bind
- [ method ]
- **
- * Specifies how to handle a specific attribute when applied
- * to a set.
- *
- **
- - attr (string) attribute name
- - callback (function) function to run
- * or
- - attr (string) attribute name
- - element (Element) specific element in the set to apply the attribute to
- * or
- - attr (string) attribute name
- - element (Element) specific element in the set to apply the attribute to
- - eattr (string) attribute on the element to bind the attribute to
- = (object) Set object
- \*/
- setproto.bind = function (attr, a, b) {
- var data = {};
- if (typeof a == "function") {
- this.bindings[attr] = a;
- } else {
- var aname = b || attr;
- this.bindings[attr] = function (v) {
- data[aname] = v;
- a.attr(data);
- };
- }
- return this;
- };
- setproto.attr = function (value) {
- var unbound = {};
- for (var k in value) {
- if (this.bindings[k]) {
- this.bindings[k](value[k]);
- } else {
- unbound[k] = value[k];
- }
- }
- for (var i = 0, ii = this.items.length; i < ii; i++) {
- this.items[i].attr(unbound);
- }
- return this;
- };
- /*\
- * Set.clear
- [ method ]
- **
- * Removes all elements from the set
- \*/
- setproto.clear = function () {
- while (this.length) {
- this.pop();
- }
- };
- /*\
- * Set.splice
- [ method ]
- **
- * Removes range of elements from the set
- **
- - 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
- **
- - element (object) element to remove
- = (boolean) `true` if object was found and 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;
- }
- return false;
- };
- 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 "Snap\u2018s set";
- };
- setproto.type = "set";
- // export
- Snap.Set = Set;
- Snap.set = function () {
- var set = new Set;
- if (arguments.length) {
- set.push.apply(set, Array.prototype.slice.call(arguments, 0));
- }
- return set;
- };
-});
-
-// 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) {
- 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, getBBox) {
- t2 = Str(t2).replace(/\.{3}|\u2026/g, t1);
- t1 = Snap.parseTransformString(t1) || [];
- t2 = Snap.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]))
- ) {
- t1 = Snap._.transform2matrix(t1, getBBox());
- t2 = Snap._.transform2matrix(t2, getBBox());
- from = [["m", t1.a, t1.b, t1.c, t1.d, t1.e, t1.f]];
- to = [["m", t2.a, t2.b, t2.c, t2.d, t2.e, t2.f]];
- break;
- }
- 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 getViewBox(val) {
- return val.join(" ");
- }
- function getColour(clr) {
- return Snap.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 Snap.path.toString.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;
- }
- function isNumeric(obj) {
- return isFinite(parseFloat(obj));
- }
- function arrayEqual(arr1, arr2) {
- if (!Snap.is(arr1, "array") || !Snap.is(arr2, "array")) {
- return false;
- }
- return arr1.toString() == arr2.toString();
- }
- Element.prototype.equal = function (name, b) {
- return eve("snap.util.equal", this, name, b).firstDefined();
- };
- eve.on("snap.util.equal", function (name, b) {
- var A, B, a = Str(this.attr(name) || ""),
- el = this;
- if (isNumeric(a) && isNumeric(b)) {
- return {
- from: parseFloat(a),
- to: parseFloat(b),
- f: getNumber
- };
- }
- if (names[name] == "colour") {
- A = Snap.color(a);
- B = Snap.color(b);
- return {
- from: [A.r, A.g, A.b, A.opacity],
- to: [B.r, B.g, B.b, B.opacity],
- f: getColour
- };
- }
- if (name == "viewBox") {
- A = this.attr(name).vb.split(" ").map(Number);
- B = b.split(" ").map(Number);
- return {
- from: A,
- to: B,
- f: getViewBox
- };
- }
- if (name == "transform" || name == "gradientTransform" || name == "patternTransform") {
- if (b instanceof Snap.Matrix) {
- b = b.toTransformString();
- }
- if (!Snap._.rgTransform.test(b)) {
- b = Snap._.svgTransform2string(b);
- }
- return equaliseTransform(a, b, function () {
- return el.getBBox(1);
- });
- }
- if (name == "d" || name == "path") {
- A = Snap.path.toCubic(a, b);
- return {
- from: path2array(A[0]),
- to: path2array(A[1]),
- f: getPath(A[0])
- };
- }
- if (name == "points") {
- A = Str(a).split(Snap._.separator);
- B = Str(b).split(Snap._.separator);
- return {
- from: A,
- to: B,
- f: function (val) { return val; }
- };
- }
- var aUnit = a.match(reUnit),
- bUnit = Str(b).match(reUnit);
- if (aUnit && arrayEqual(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
- };
- }
- });
-});
-
-// 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) {
- 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, el) {
- var name = xy == "y" ? "scrollTop" : "scrollLeft",
- doc = el && el.node ? el.node.ownerDocument : glob.doc;
- return doc[name in doc.documentElement ? "documentElement" : "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 (obj, type, fn, element) {
- var realName = supportsTouch && touchMap[type] ? touchMap[type] : type,
- f = function (e) {
- var scrollY = getScroll("y", element),
- scrollX = getScroll("x", element);
- if (supportsTouch && touchMap[has](type)) {
- for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) {
- if (e.targetTouches[i].target == obj || obj.contains(e.targetTouches[i].target)) {
- var olde = e;
- e = e.targetTouches[i];
- e.originalEvent = olde;
- e.preventDefault = preventTouch;
- e.stopPropagation = stopTouch;
- break;
- }
- }
- }
- var x = e.clientX + scrollX,
- y = e.clientY + scrollY;
- return fn.call(element, e, x, y);
- };
-
- if (type !== realName) {
- obj.addEventListener(type, f, false);
- }
-
- obj.addEventListener(realName, f, false);
-
- return function () {
- if (type !== realName) {
- obj.removeEventListener(type, f, false);
- }
-
- obj.removeEventListener(realName, f, false);
- return true;
- };
- },
- 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 && e.touches.length,
- touch;
- while (i--) {
- touch = e.touches[i];
- if (touch.identifier == dragi.el._drag.id || dragi.el.node.contains(touch.target)) {
- 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("snap.drag.over." + dragi.el.id, dragi.el, o);
- x += scrollX;
- y += scrollY;
- eve("snap.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) {
- Snap.unmousemove(dragMove).unmouseup(dragUp);
- var i = drag.length,
- dragi;
- while (i--) {
- dragi = drag[i];
- dragi.el._drag = {};
- eve("snap.drag.end." + dragi.el.id, dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e);
- eve.off("snap.drag.*." + dragi.el.id);
- }
- drag = [];
- };
- /*\
- * Element.click
- [ method ]
- **
- * Adds a click event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.unclick
- [ method ]
- **
- * Removes a click event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.dblclick
- [ method ]
- **
- * Adds a double click event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.undblclick
- [ method ]
- **
- * Removes a double click event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.mousedown
- [ method ]
- **
- * Adds a mousedown event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.unmousedown
- [ method ]
- **
- * Removes a mousedown event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.mousemove
- [ method ]
- **
- * Adds a mousemove event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.unmousemove
- [ method ]
- **
- * Removes a mousemove event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.mouseout
- [ method ]
- **
- * Adds a mouseout event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.unmouseout
- [ method ]
- **
- * Removes a mouseout event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.mouseover
- [ method ]
- **
- * Adds a mouseover event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.unmouseover
- [ method ]
- **
- * Removes a mouseover event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.mouseup
- [ method ]
- **
- * Adds a mouseup event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.unmouseup
- [ method ]
- **
- * Removes a mouseup event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.touchstart
- [ method ]
- **
- * Adds a touchstart event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.untouchstart
- [ method ]
- **
- * Removes a touchstart event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.touchmove
- [ method ]
- **
- * Adds a touchmove event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.untouchmove
- [ method ]
- **
- * Removes a touchmove event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.touchend
- [ method ]
- **
- * Adds a touchend event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.untouchend
- [ method ]
- **
- * Removes a touchend event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
-
- /*\
- * Element.touchcancel
- [ method ]
- **
- * Adds a touchcancel event handler to the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- /*\
- * Element.untouchcancel
- [ method ]
- **
- * Removes a touchcancel event handler from the element
- - handler (function) handler for the event
- = (object) @Element
- \*/
- for (var i = events.length; i--;) {
- (function (eventName) {
- Snap[eventName] = elproto[eventName] = function (fn, scope) {
- if (Snap.is(fn, "function")) {
- this.events = this.events || [];
- this.events.push({
- name: eventName,
- f: fn,
- unbind: addEvent(this.node || document, eventName, fn, scope || this)
- });
- } else {
- for (var i = 0, ii = this.events.length; i < ii; i++) if (this.events[i].name == eventName) {
- try {
- this.events[i].f.call(this);
- } catch (e) {}
- }
- }
- return this;
- };
- Snap["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 || !fn)) {
- events[l].unbind();
- events.splice(l, 1);
- !events.length && delete this.events;
- return this;
- }
- return this;
- };
- })(events[i]);
- }
- /*\
- * Element.hover
- [ method ]
- **
- * Adds hover event handlers to the element
- - 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 hover event handlers from the element
- - 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 = [];
- // SIERRA unclear what _context_ refers to for starting, ending, moving the drag gesture.
- // SIERRA Element.drag(): _x position of the mouse_: Where are the x/y values offset from?
- // SIERRA Element.drag(): much of this member's doc appears to be duplicated for some reason.
- // SIERRA Unclear about this sentence: _Additionally following drag events will be triggered: drag.start.<id> on start, drag.end.<id> on end and drag.move.<id> on every move._ Is there a global _drag_ object to which you can assign handlers keyed by an element's ID?
- /*\
- * Element.drag
- [ method ]
- **
- * Adds event handlers for an element's drag gesture
- **
- - 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 are triggered: `drag.start.<id>` on start,
- * `drag.end.<id>` on end and `drag.move.<id>` on every move. When element is dragged over another element
- * `drag.over.<id>` fires as well.
- *
- * Start event and start handler are 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 are 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 are 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) {
- var el = this;
- if (!arguments.length) {
- var origTransform;
- return el.drag(function (dx, dy) {
- this.attr({
- transform: origTransform + (origTransform ? "T" : "t") + [dx, dy]
- });
- }, function () {
- origTransform = this.transform().local;
- });
- }
- function start(e, x, y) {
- (e.originalEvent || e).preventDefault();
- el._drag.x = x;
- el._drag.y = y;
- el._drag.id = e.identifier;
- !drag.length && Snap.mousemove(dragMove).mouseup(dragUp);
- drag.push({el: el, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope});
- onstart && eve.on("snap.drag.start." + el.id, onstart);
- onmove && eve.on("snap.drag.move." + el.id, onmove);
- onend && eve.on("snap.drag.end." + el.id, onend);
- eve("snap.drag.start." + el.id, start_scope || move_scope || el, x, y, e);
- }
- function init(e, x, y) {
- eve("snap.draginit." + el.id, el, e, x, y);
- }
- eve.on("snap.draginit." + el.id, start);
- el._drag = {};
- draggable.push({el: el, start: start, init: init});
- el.mousedown(init);
- return el;
- };
- /*
- * Element.onDragOver
- [ method ]
- **
- * Shortcut to assign event handler for `drag.over.<id>` event, where `id` is the element's `id` (see @Element.id)
- - f (function) handler for event, first argument would be the element you are dragging over
- \*/
- // elproto.onDragOver = function (f) {
- // f ? eve.on("snap.drag.over." + this.id, f) : eve.unbind("snap.drag.over." + this.id);
- // };
- /*\
- * Element.undrag
- [ method ]
- **
- * Removes all drag event handlers from the given element
- \*/
- elproto.undrag = function () {
- var i = draggable.length;
- while (i--) if (draggable[i].el == this) {
- this.unmousedown(draggable[i].init);
- draggable.splice(i, 1);
- eve.unbind("snap.drag.*." + this.id);
- eve.unbind("snap.draginit." + this.id);
- }
- !draggable.length && Snap.unmousemove(dragMove).unmouseup(dragUp);
- return this;
- };
-});
-
-// 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) {
- var elproto = Element.prototype,
- pproto = Paper.prototype,
- rgurl = /^\s*url\((.+)\)/,
- Str = String,
- $ = Snap._.$;
- Snap.filter = {};
- /*\
- * Paper.filter
- [ method ]
- **
- * Creates a `<filter>` element
- **
- - filstr (string) SVG fragment of filter provided as a string
- = (object) @Element
- * Note: It is recommended to use filters embedded into the page inside an empty SVG element.
- > Usage
- | var f = paper.filter('<feGaussianBlur stdDeviation="2"/>'),
- | c = paper.circle(10, 10, 10).attr({
- | filter: f
- | });
- \*/
- pproto.filter = function (filstr) {
- var paper = this;
- if (paper.type != "svg") {
- paper = paper.paper;
- }
- var f = Snap.parse(Str(filstr)),
- id = Snap._.id(),
- width = paper.node.offsetWidth,
- height = paper.node.offsetHeight,
- filter = $("filter");
- $(filter, {
- id: id,
- filterUnits: "userSpaceOnUse"
- });
- filter.appendChild(f.node);
- paper.defs.appendChild(filter);
- return new Element(filter);
- };
-
- eve.on("snap.util.getattr.filter", function () {
- eve.stop();
- var p = $(this.node, "filter");
- if (p) {
- var match = Str(p).match(rgurl);
- return match && Snap.select(match[1]);
- }
- });
- eve.on("snap.util.attr.filter", function (value) {
- if (value instanceof Element && value.type == "filter") {
- eve.stop();
- var id = value.node.id;
- if (!id) {
- $(value.node, {id: value.id});
- id = value.id;
- }
- $(this.node, {
- filter: Snap.url(id)
- });
- }
- if (!value || value == "none") {
- eve.stop();
- this.node.removeAttribute("filter");
- }
- });
- /*\
- * Snap.filter.blur
- [ method ]
- **
- * Returns an SVG markup string for the blur filter
- **
- - x (number) amount of horizontal blur, in pixels
- - y (number) #optional amount of vertical blur, in pixels
- = (string) filter representation
- > Usage
- | var f = paper.filter(Snap.filter.blur(5, 10)),
- | c = paper.circle(10, 10, 10).attr({
- | filter: f
- | });
- \*/
- Snap.filter.blur = function (x, y) {
- if (x == null) {
- x = 2;
- }
- var def = y == null ? x : [x, y];
- return Snap.format('\<feGaussianBlur stdDeviation="{def}"/>', {
- def: def
- });
- };
- Snap.filter.blur.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.shadow
- [ method ]
- **
- * Returns an SVG markup string for the shadow filter
- **
- - dx (number) #optional horizontal shift of the shadow, in pixels
- - dy (number) #optional vertical shift of the shadow, in pixels
- - blur (number) #optional amount of blur
- - color (string) #optional color of the shadow
- - opacity (number) #optional `0..1` opacity of the shadow
- * or
- - dx (number) #optional horizontal shift of the shadow, in pixels
- - dy (number) #optional vertical shift of the shadow, in pixels
- - color (string) #optional color of the shadow
- - opacity (number) #optional `0..1` opacity of the shadow
- * which makes blur default to `4`. Or
- - dx (number) #optional horizontal shift of the shadow, in pixels
- - dy (number) #optional vertical shift of the shadow, in pixels
- - opacity (number) #optional `0..1` opacity of the shadow
- = (string) filter representation
- > Usage
- | var f = paper.filter(Snap.filter.shadow(0, 2, 3)),
- | c = paper.circle(10, 10, 10).attr({
- | filter: f
- | });
- \*/
- Snap.filter.shadow = function (dx, dy, blur, color, opacity) {
- if (typeof blur == "string") {
- color = blur;
- opacity = color;
- blur = 4;
- }
- if (typeof color != "string") {
- opacity = color;
- color = "#000";
- }
- color = color || "#000";
- if (blur == null) {
- blur = 4;
- }
- if (opacity == null) {
- opacity = 1;
- }
- if (dx == null) {
- dx = 0;
- dy = 2;
- }
- if (dy == null) {
- dy = dx;
- }
- color = Snap.color(color);
- return Snap.format('<feGaussianBlur in="SourceAlpha" stdDeviation="{blur}"/><feOffset dx="{dx}" dy="{dy}" result="offsetblur"/><feFlood flood-color="{color}"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="{opacity}"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>', {
- color: color,
- dx: dx,
- dy: dy,
- blur: blur,
- opacity: opacity
- });
- };
- Snap.filter.shadow.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.grayscale
- [ method ]
- **
- * Returns an SVG markup string for the grayscale filter
- **
- - amount (number) amount of filter (`0..1`)
- = (string) filter representation
- \*/
- Snap.filter.grayscale = function (amount) {
- if (amount == null) {
- amount = 1;
- }
- return Snap.format('<feColorMatrix type="matrix" values="{a} {b} {c} 0 0 {d} {e} {f} 0 0 {g} {b} {h} 0 0 0 0 0 1 0"/>', {
- a: 0.2126 + 0.7874 * (1 - amount),
- b: 0.7152 - 0.7152 * (1 - amount),
- c: 0.0722 - 0.0722 * (1 - amount),
- d: 0.2126 - 0.2126 * (1 - amount),
- e: 0.7152 + 0.2848 * (1 - amount),
- f: 0.0722 - 0.0722 * (1 - amount),
- g: 0.2126 - 0.2126 * (1 - amount),
- h: 0.0722 + 0.9278 * (1 - amount)
- });
- };
- Snap.filter.grayscale.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.sepia
- [ method ]
- **
- * Returns an SVG markup string for the sepia filter
- **
- - amount (number) amount of filter (`0..1`)
- = (string) filter representation
- \*/
- Snap.filter.sepia = function (amount) {
- if (amount == null) {
- amount = 1;
- }
- return Snap.format('<feColorMatrix type="matrix" values="{a} {b} {c} 0 0 {d} {e} {f} 0 0 {g} {h} {i} 0 0 0 0 0 1 0"/>', {
- a: 0.393 + 0.607 * (1 - amount),
- b: 0.769 - 0.769 * (1 - amount),
- c: 0.189 - 0.189 * (1 - amount),
- d: 0.349 - 0.349 * (1 - amount),
- e: 0.686 + 0.314 * (1 - amount),
- f: 0.168 - 0.168 * (1 - amount),
- g: 0.272 - 0.272 * (1 - amount),
- h: 0.534 - 0.534 * (1 - amount),
- i: 0.131 + 0.869 * (1 - amount)
- });
- };
- Snap.filter.sepia.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.saturate
- [ method ]
- **
- * Returns an SVG markup string for the saturate filter
- **
- - amount (number) amount of filter (`0..1`)
- = (string) filter representation
- \*/
- Snap.filter.saturate = function (amount) {
- if (amount == null) {
- amount = 1;
- }
- return Snap.format('<feColorMatrix type="saturate" values="{amount}"/>', {
- amount: 1 - amount
- });
- };
- Snap.filter.saturate.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.hueRotate
- [ method ]
- **
- * Returns an SVG markup string for the hue-rotate filter
- **
- - angle (number) angle of rotation
- = (string) filter representation
- \*/
- Snap.filter.hueRotate = function (angle) {
- angle = angle || 0;
- return Snap.format('<feColorMatrix type="hueRotate" values="{angle}"/>', {
- angle: angle
- });
- };
- Snap.filter.hueRotate.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.invert
- [ method ]
- **
- * Returns an SVG markup string for the invert filter
- **
- - amount (number) amount of filter (`0..1`)
- = (string) filter representation
- \*/
- Snap.filter.invert = function (amount) {
- if (amount == null) {
- amount = 1;
- }
-// <feColorMatrix type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" color-interpolation-filters="sRGB"/>
- return Snap.format('<feComponentTransfer><feFuncR type="table" tableValues="{amount} {amount2}"/><feFuncG type="table" tableValues="{amount} {amount2}"/><feFuncB type="table" tableValues="{amount} {amount2}"/></feComponentTransfer>', {
- amount: amount,
- amount2: 1 - amount
- });
- };
- Snap.filter.invert.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.brightness
- [ method ]
- **
- * Returns an SVG markup string for the brightness filter
- **
- - amount (number) amount of filter (`0..1`)
- = (string) filter representation
- \*/
- Snap.filter.brightness = function (amount) {
- if (amount == null) {
- amount = 1;
- }
- return Snap.format('<feComponentTransfer><feFuncR type="linear" slope="{amount}"/><feFuncG type="linear" slope="{amount}"/><feFuncB type="linear" slope="{amount}"/></feComponentTransfer>', {
- amount: amount
- });
- };
- Snap.filter.brightness.toString = function () {
- return this();
- };
- /*\
- * Snap.filter.contrast
- [ method ]
- **
- * Returns an SVG markup string for the contrast filter
- **
- - amount (number) amount of filter (`0..1`)
- = (string) filter representation
- \*/
- Snap.filter.contrast = function (amount) {
- if (amount == null) {
- amount = 1;
- }
- return Snap.format('<feComponentTransfer><feFuncR type="linear" slope="{amount}" intercept="{amount2}"/><feFuncG type="linear" slope="{amount}" intercept="{amount2}"/><feFuncB type="linear" slope="{amount}" intercept="{amount2}"/></feComponentTransfer>', {
- amount: amount,
- amount2: .5 - amount / 2
- });
- };
- Snap.filter.contrast.toString = function () {
- return this();
- };
-});
-
-// Copyright (c) 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.
-// 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 box = Snap._.box,
- is = Snap.is,
- firstLetter = /^[^a-z]*([tbmlrc])/i,
- toString = function () {
- return "T" + this.dx + "," + this.dy;
- };
- /*\
- * Element.getAlign
- [ method ]
- **
- * Returns shift needed to align the element relatively to given element.
- * If no elements specified, parent `<svg>` container will be used.
- - el (object) @optional alignment element
- - way (string) one of six values: `"top"`, `"middle"`, `"bottom"`, `"left"`, `"center"`, `"right"`
- = (object|string) Object in format `{dx: , dy: }` also has a string representation as a transformation string
- > Usage
- | el.transform(el.getAlign(el2, "top"));
- * or
- | var dy = el.getAlign(el2, "top").dy;
- \*/
- Element.prototype.getAlign = function (el, way) {
- if (way == null && is(el, "string")) {
- way = el;
- el = null;
- }
- el = el || this.paper;
- var bx = el.getBBox ? el.getBBox() : box(el),
- bb = this.getBBox(),
- out = {};
- way = way && way.match(firstLetter);
- way = way ? way[1].toLowerCase() : "c";
- switch (way) {
- case "t":
- out.dx = 0;
- out.dy = bx.y - bb.y;
- break;
- case "b":
- out.dx = 0;
- out.dy = bx.y2 - bb.y2;
- break;
- case "m":
- out.dx = 0;
- out.dy = bx.cy - bb.cy;
- break;
- case "l":
- out.dx = bx.x - bb.x;
- out.dy = 0;
- break;
- case "r":
- out.dx = bx.x2 - bb.x2;
- out.dy = 0;
- break;
- default:
- out.dx = bx.cx - bb.cx;
- out.dy = 0;
- break;
- }
- out.toString = toString;
- return out;
- };
- /*\
- * Element.align
- [ method ]
- **
- * Aligns the element relatively to given one via transformation.
- * If no elements specified, parent `<svg>` container will be used.
- - el (object) @optional alignment element
- - way (string) one of six values: `"top"`, `"middle"`, `"bottom"`, `"left"`, `"center"`, `"right"`
- = (object) this element
- > Usage
- | el.align(el2, "top");
- * or
- | el.align("middle");
- \*/
- Element.prototype.align = function (el, way) {
- return this.transform("..." + this.getAlign(el, way));
- };
-});
-
-return Snap;
-}));