`1/*` `2 * Raphaël 2.0.0 - JavaScript Vector Library` `3 *` `4 * Copyright (c) 2011 Dmitry Baranovskiy (http://raphaeljs.com)` `5 * Copyright (c) 2011 Sencha Labs (http://sencha.com)` `6 * Licensed under the MIT (http://raphaeljs.com/license.html) license.` `7 */` `8(function () {` `9 /*\` `10 * Raphael` `11 [ method ]` `12 **` `13 * Creates a canvas object on which to draw.` `14 * You must do this first, as all future calls to drawing methods` `15 * from this instance will be bound to this canvas.` `16 > Parameters` `17 **` `18 - container (HTMLElement|string) DOM element or its ID which is going to be a parent for drawing surface` `19 - width (number)` `20 - height (number)` `21 * or` `22 - x (number)` `23 - y (number)` `24 - width (number)` `25 - height (number)` `26 * or` `27 - all (array) (first 3 or 4 elements in the array are equal to [containerID, width, height] or [x, y, width, height]. The rest are element descriptions in format {type: type, <attributes>})` `28 * or` `29 - onReadyCallback (function) function that is going to be called on DOM ready event. You can also subscribe to this event via Eve’s “DOMLoad” event. In this case method returns `undefined`.` `30 = (object) @Paper` `31 > Usage` `32 | // Each of the following examples create a canvas` `33 | // that is 320px wide by 200px high.` `34 | // Canvas is created at the viewport’s 10,50 coordinate.` `35 | var paper = Raphael(10, 50, 320, 200);` `36 | // Canvas is created at the top left corner of the #notepad element` `37 | // (or its top right corner in dir="rtl" elements)` `38 | var paper = Raphael(document.getElementById("notepad"), 320, 200);` `39 | // Same as above` `40 | var paper = Raphael("notepad", 320, 200);` `41 | // Image dump` `42 | var set = Raphael(["notepad", 320, 200, {` `43 | type: "rect",` `44 | x: 10,` `45 | y: 10,` `46 | width: 25,` `47 | height: 25,` `48 | stroke: "#f00"` `49 | }, {` `50 | type: "text",` `51 | x: 30,` `52 | y: 40,` `53 | text: "Dump"` `54 | }]);` `55 \*/` `56 function R(first) {` `57 if (R.is(first, "function")) {` `58 return eve.on("DOMload", first);` `59 } else if (R.is(first, array)) {` `60 var a = first,` `61 cnv = create[apply](R, a.splice(0, 3 + R.is(a[0], nu))),` `62 res = cnv.set(),` `63 i = 0,` `64 ii = a.length,` `65 j;` `66 for (; i < ii; i++) {` `67 j = a[i] || {};` `68 elements[has](j.type) && res.push(cnv[j.type]().attr(j));` `69 }` `70 return res;` `71 }` `72 return create[apply](R, arguments);` `73 }` `74 R.version = "2.0.0";` `75 var separator = /[, ]+/,` `76 elements = {circle: 1, rect: 1, path: 1, ellipse: 1, text: 1, image: 1},` `77 formatrg = /\{(\d+)\}/g,` `78 proto = "prototype",` `79 has = "hasOwnProperty",` `80 g = {` `81 doc: document,` `82 win: window` `83 },` `84 oldRaphael = {` `85 was: Object.prototype[has].call(g.win, "Raphael"),` `86 is: g.win.Raphael` `87 },` `88 Paper = function () {},` `89 paperproto,` `90 appendChild = "appendChild",` `91 apply = "apply",` `92 concat = "concat",` `93 supportsTouch = "createTouch" in g.doc,` `94 E = "",` `95 S = " ",` `96 Str = String,` `97 split = "split",` `98 events = "click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend".split(S),` `99 touchMap = {` `100 mousedown: "touchstart",` `101 mousemove: "touchmove",` `102 mouseup: "touchend"` `103 },` `104 lowerCase = Str.prototype.toLowerCase,` `105 math = Math,` `106 mmax = math.max,` `107 mmin = math.min,` `108 abs = math.abs,` `109 pow = math.pow,` `110 PI = math.PI,` `111 nu = "number",` `112 string = "string",` `113 array = "array",` `114 toString = "toString",` `115 fillString = "fill",` `116 objectToString = Object.prototype.toString,` `117 paper = {},` `118 push = "push",` `119 ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/i,` `120 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,` `121 isnan = {"NaN": 1, "Infinity": 1, "-Infinity": 1},` `122 bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,` `123 round = math.round,` `124 setAttribute = "setAttribute",` `125 toFloat = parseFloat,` `126 toInt = parseInt,` `127 ms = " progid:DXImageTransform.Microsoft",` `128 upperCase = Str.prototype.toUpperCase,` `129 availableAttrs = {"arrow-end": "none", "arrow-start": "none", blur: 0, "clip-rect": "0 0 1e9 1e9", cursor: "default", cx: 0, cy: 0, fill: "#fff", "fill-opacity": 1, font: '10px "Arial"', "font-family": '"Arial"', "font-size": "10", "font-style": "normal", "font-weight": 400, gradient: 0, height: 0, href: "http://raphaeljs.com/", opacity: 1, path: "M0,0", r: 0, rx: 0, ry: 0, src: "", stroke: "#000", "stroke-dasharray": "", "stroke-linecap": "butt", "stroke-linejoin": "butt", "stroke-miterlimit": 0, "stroke-opacity": 1, "stroke-width": 1, target: "_blank", "text-anchor": "middle", title: "Raphael", transform: "", width: 0, x: 0, y: 0},` `130 availableAnimAttrs = {blur: nu, "clip-rect": "csv", cx: nu, cy: nu, fill: "colour", "fill-opacity": nu, "font-size": nu, height: nu, opacity: nu, path: "path", r: nu, rx: nu, ry: nu, stroke: "colour", "stroke-opacity": nu, "stroke-width": nu, transform: "transform", width: nu, x: nu, y: nu},` `131 commaSpaces = /\s*,\s*/,` `132 hsrg = {hs: 1, rg: 1},` `133 p2s = /,?([achlmqrstvxz]),?/gi,` `134 pathCommand = /([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,` `135 tCommand = /([rstm])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,` `136 pathValues = /(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,` `137 radial_gradient = /^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/,` `138 sortByKey = function (a, b) {` `139 return a.key - b.key;` `140 },` `141 sortByNumber = function (a, b) {` `142 return a - b;` `143 },` `144 fun = function () {},` `145 pipe = function (x) {` `146 return x;` `147 },` `148 rectPath = function (x, y, w, h, r) {` `149 if (r) {` `150 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"]];` `151 }` `152 return [["M", x, y], ["l", w, 0], ["l", 0, h], ["l", -w, 0], ["z"]];` `153 },` `154 ellipsePath = function (x, y, rx, ry) {` `155 if (ry == null) {` `156 ry = rx;` `157 }` `158 return [["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"]];` `159 },` `160 getPath = {` `161 path: function (el) {` `162 return el.attr("path");` `163 },` `164 circle: function (el) {` `165 var a = el.attrs;` `166 return ellipsePath(a.cx, a.cy, a.r);` `167 },` `168 ellipse: function (el) {` `169 var a = el.attrs;` `170 return ellipsePath(a.cx, a.cy, a.rx, a.ry);` `171 },` `172 rect: function (el) {` `173 var a = el.attrs;` `174 return rectPath(a.x, a.y, a.width, a.height, a.r);` `175 },` `176 image: function (el) {` `177 var a = el.attrs;` `178 return rectPath(a.x, a.y, a.width, a.height);` `179 },` `180 text: function (el) {` `181 var bbox = el._getBBox();` `182 return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);` `183 }` `184 },` `185 mapPath = function (path, matrix) {` `186 if (!matrix) {` `187 return path;` `188 }` `189 var x, y, i, j, pathi;` `190 path = path2curve(path);` `191 for (i = 0, ii = path.length; i < ii; i++) {` `192 pathi = path[i];` `193 for (j = 1, jj = pathi.length; j < jj; j += 2) {` `194 x = matrix.x(pathi[j], pathi[j + 1]);` `195 y = matrix.y(pathi[j], pathi[j + 1]);` `196 pathi[j] = x;` `197 pathi[j + 1] = y;` `198 }` `199 }` `200 return path;` `201 };` `202` `203 /*\` `204 * Raphael.type` `205 [ property (string) ]` `206 **` `207 * Can be “SVG”, “VML” or empty, depending on browser support.` `208 \*/` `209 R.type = (g.win.SVGAngle || g.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML");` `210 if (R.type == "VML") {` `211 var d = g.doc.createElement("div"),` `212 b;` `213 d.innerHTML = '<v:shape adj="1"/>';` `214 b = d.firstChild;` `215 b.style.behavior = "url(#default#VML)";` `216 if (!(b && typeof b.adj == "object")) {` `217 return R.type = E;` `218 }` `219 d = null;` `220 }` `221 /*\` `222 * Raphael.svg` `223 [ property (boolean) ]` `224 **` `225 * `true` if browser supports SVG.` `226 \*/` `227 /*\` `228 * Raphael.vml` `229 [ property (boolean) ]` `230 **` `231 * `true` if browser supports VML.` `232 \*/` `233 R.svg = !(R.vml = R.type == "VML");` `234 paperproto = Paper.prototype = R.prototype;` `235 /*\` `236 * Paper.customAttributes` `237 [ property (object) ]` `238 **` `239 * If you have a set of attributes that you would like to represent` `240 * as a function of some number you can do it easily with custom attributes:` `241 > Usage` `242 | paper.customAttributes.hue = function (num) {` `243 | num = num % 1;` `244 | return {fill: "hsb(" + num + ", .75, 1)"};` `245 | };` `246 | // Custom attribute “hue” will change fill` `247 | // to be given hue with fixed saturation and brightness.` `248 | // Now you can use it like this:` `249 | var c = paper.circle(10, 10, 10).attr({hue: .45});` `250 | // or even like this:` `251 | c.animate({hue: 1}, 1e3);` `252 |` `253 | // You could also create custom attribute` `254 | // with multiple parameters:` `255 | paper.customAttributes.hsb = function (h, s, b) {` `256 | return {fill: "hsb(" + [h, s, b].join(",") + ")"};` `257 | };` `258 | c.attr({hsb: ".5 .8 1"});` `259 | c.animate({hsb: "1 0 .5"}, 1e3);` `260 \*/` `261 paperproto.customAttributes = {};` `262 R._id = 0;` `263 R._oid = 0;` `264 /*\` `265 * Raphael.fn` `266 [ property (object) ]` `267 **` `268 * You can add your own method to the canvas. For example if you want to draw a pie chart,` `269 * you can create your own pie chart function and ship it as a Raphaël plugin. To do this` `270 * you need to extend the `Raphael.fn` object. Please note that you can create your own namespaces` `271 * inside the `fn` object — methods will be run in the context of canvas anyway. You should alter` `272 * the `fn` object before a Raphaël instance is created, otherwise it will take no effect.` `273 > Usage` `274 | Raphael.fn.arrow = function (x1, y1, x2, y2, size) {` `275 | return this.path( ... );` `276 | };` `277 | // or create namespace` `278 | Raphael.fn.mystuff = {` `279 | arrow: function () {…},` `280 | star: function () {…},` `281 | // etc…` `282 | };` `283 | var paper = Raphael(10, 10, 630, 480);` `284 | // then use it` `285 | paper.arrow(10, 10, 30, 30, 5).attr({fill: "#f00"});` `286 | paper.mystuff.arrow();` `287 | paper.mystuff.star();` `288 \*/` `289 R.fn = {};` `290 /*\` `291 * Raphael.is` `292 [ method ]` `293 **` `294 * Handfull replacement for `typeof` operator.` `295 > Parameters` `296 - o (…) any object or primitive` `297 - type (string) name of the type, i.e. “string”, “function”, “number”, etc.` `298 = (boolean) is given value is of given type` `299 \*/` `300 R.is = function (o, type) {` `301 type = lowerCase.call(type);` `302 if (type == "finite") {` `303 return !isnan[has](+o);` `304 }` `305 return (type == "null" && o === null) ||` `306 (type == typeof o) ||` `307 (type == "object" && o === Object(o)) ||` `308 (type == "array" && Array.isArray && Array.isArray(o)) ||` `309 objectToString.call(o).slice(8, -1).toLowerCase() == type;` `310 };` `311 /*\` `312 * Raphael.angle` `313 [ method ]` `314 **` `315 * Returns angle between two or three points` `316 > Parameters` `317 - x1 (number) x coord of first point` `318 - y1 (number) y coord of first point` `319 - x2 (number) x coord of second point` `320 - y2 (number) y coord of second point` `321 - x3 (number) #optional x coord of third point` `322 - y3 (number) #optional y coord of third point` `323 = (number) angle in degrees.` `324 \*/` `325 R.angle = function (x1, y1, x2, y2, x3, y3) {` `326 if (x3 == null) {` `327 var x = x1 - x2,` `328 y = y1 - y2;` `329 if (!x && !y) {` `330 return 0;` `331 }` `332 return (180 + math.atan2(-y, -x) * 180 / PI + 360) % 360;` `333 } else {` `334 return R.angle(x1, y1, x3, y3) - R.angle(x2, y2, x3, y3);` `335 }` `336 };` `337 /*\` `338 * Raphael.rad` `339 [ method ]` `340 **` `341 * Transform angle to radians` `342 > Parameters` `343 - deg (number) angle in degrees` `344 = (number) angle in radians.` `345 \*/` `346 R.rad = function (deg) {` `347 return deg % 360 * PI / 180;` `348 };` `349 /*\` `350 * Raphael.deg` `351 [ method ]` `352 **` `353 * Transform angle to degrees` `354 > Parameters` `355 - deg (number) angle in radians` `356 = (number) angle in degrees.` `357 \*/` `358 R.deg = function (rad) {` `359 return rad * 180 / PI % 360;` `360 };` `361 /*\` `362 * Raphael.snapTo` `363 [ method ]` `364 **` `365 * Snaps given value to given grid.` `366 > Parameters` `367 - values (array|number) given array of values or step of the grid` `368 - value (number) value to adjust` `369 - tolerance (number) #optional tolerance for snapping. Default is `10`.` `370 = (number) adjusted value.` `371 \*/` `372 R.snapTo = function (values, value, tolerance) {` `373 tolerance = R.is(tolerance, "finite") ? tolerance : 10;` `374 if (R.is(values, array)) {` `375 var i = values.length;` `376 while (i--) if (abs(values[i] - value) <= tolerance) {` `377 return values[i];` `378 }` `379 } else {` `380 values = +values;` `381 var rem = value % values;` `382 if (rem < tolerance) {` `383 return value - rem;` `384 }` `385 if (rem > values - tolerance) {` `386 return value - rem + values;` `387 }` `388 }` `389 return value;` `390 };` `391` `392 var createUUID = (function (uuidRegEx, uuidReplacer) {` `393 return function () {` `394 return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(uuidRegEx, uuidReplacer).toUpperCase();` `395 };` `396 })(/[xy]/g, function (c) {` `397 var r = math.random() * 16 | 0,` `398 v = c == "x" ? r : (r & 3 | 8);` `399 return v.toString(16);` `400 });` `401` `402 /*\` `403 * Raphael.setWindow` `404 [ method ]` `405 **` `406 * Used when you need to draw in `<iframe>`. Switched window to the iframe one.` `407 > Parameters` `408 - newwin (window) new window object` `409 \*/` `410 R.setWindow = function (newwin) {` `411 eve("setWindow", R, g.win, newwin);` `412 g.win = newwin;` `413 g.doc = g.win.document;` `414 if (initWin) {` `415 initWin(g.win);` `416 }` `417 };` `418 // colour utilities` `419 var toHex = function (color) {` `420 if (R.vml) {` `421 // http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/` `422 var trim = /^\s+|\s+$/g;` `423 var bod;` `424 try {` `425 var docum = new ActiveXObject("htmlfile");` `426 docum.write("<body>");` `427 docum.close();` `428 bod = docum.body;` `429 } catch(e) {` `430 bod = createPopup().document.body;` `431 }` `432 var range = bod.createTextRange();` `433 toHex = cacher(function (color) {` `434 try {` `435 bod.style.color = Str(color).replace(trim, E);` `436 var value = range.queryCommandValue("ForeColor");` `437 value = ((value & 255) << 16) | (value & 65280) | ((value & 16711680) >>> 16);` `438 return "#" + ("000000" + value.toString(16)).slice(-6);` `439 } catch(e) {` `440 return "none";` `441 }` `442 });` `443 } else {` `444 var i = g.doc.createElement("i");` `445 i.title = "Rapha\xebl Colour Picker";` `446 i.style.display = "none";` `447 g.doc.body.appendChild(i);` `448 toHex = cacher(function (color) {` `449 i.style.color = color;` `450 return g.doc.defaultView.getComputedStyle(i, E).getPropertyValue("color");` `451 });` `452 }` `453 return toHex(color);` `454 },` `455 hsbtoString = function () {` `456 return "hsb(" + [this.h, this.s, this.b] + ")";` `457 },` `458 hsltoString = function () {` `459 return "hsl(" + [this.h, this.s, this.l] + ")";` `460 },` `461 rgbtoString = function () {` `462 return this.hex;` `463 },` `464 prepareRGB = function (r, g, b) {` `465 if (g == null && R.is(r, "object") && "r" in r && "g" in r && "b" in r) {` `466 b = r.b;` `467 g = r.g;` `468 r = r.r;` `469 }` `470 if (g == null && R.is(r, string)) {` `471 var clr = R.getRGB(r);` `472 r = clr.r;` `473 g = clr.g;` `474 b = clr.b;` `475 }` `476 if (r > 1 || g > 1 || b > 1) {` `477 r /= 255;` `478 g /= 255;` `479 b /= 255;` `480 }` `481` `482 return [r, g, b];` `483 },` `484 packageRGB = function (r, g, b, o) {` `485 r *= 255;` `486 g *= 255;` `487 b *= 255;` `488 var rgb = {` `489 r: r,` `490 g: g,` `491 b: b,` `492 hex: R.rgb(r, g, b),` `493 toString: rgbtoString` `494 };` `495 R.is(o, "finite") && (rgb.opacity = o);` `496 return rgb;` `497 };` `498 /*\` `499 * Raphael.hsb2rgb` `500 [ method ]` `501 **` `502 * Converts HSB values to RGB object.` `503 > Parameters` `504 - h (number) hue` `505 - s (number) saturation` `506 - v (number) value or brightness` `507 = (object) RGB object in format:` `508 o {` `509 o r (number) red,` `510 o g (number) green,` `511 o b (number) blue,` `512 o hex (string) color in HTML/CSS format: #••••••` `513 o }` `514 \*/` `515 R.hsb2rgb = function (h, s, v, o) {` `516 if (this.is(h, "object") && "h" in h && "s" in h && "b" in h) {` `517 v = h.b;` `518 s = h.s;` `519 h = h.h;` `520 o = h.o;` `521 }` `522 h *= 360;` `523 var R, G, B, X, C;` `524 h = (h % 360) / 60;` `525 C = v * s;` `526 X = C * (1 - abs(h % 2 - 1));` `527 R = G = B = v - C;` `528` `529 h = ~~h;` `530 R += [C, X, 0, 0, X, C][h];` `531 G += [X, C, C, X, 0, 0][h];` `532 B += [0, 0, X, C, C, X][h];` `533 return packageRGB(R, G, B, o);` `534 };` `535 /*\` `536 * Raphael.hsl2rgb` `537 [ method ]` `538 **` `539 * Converts HSL values to RGB object.` `540 > Parameters` `541 - h (number) hue` `542 - s (number) saturation` `543 - l (number) luminosity` `544 = (object) RGB object in format:` `545 o {` `546 o r (number) red,` `547 o g (number) green,` `548 o b (number) blue,` `549 o hex (string) color in HTML/CSS format: #••••••` `550 o }` `551 \*/` `552 R.hsl2rgb = function (h, s, l, o) {` `553 if (this.is(h, "object") && "h" in h && "s" in h && "l" in h) {` `554 l = h.l;` `555 s = h.s;` `556 h = h.h;` `557 }` `558 if (h > 1 || s > 1 || l > 1) {` `559 h /= 360;` `560 s /= 100;` `561 l /= 100;` `562 }` `563 h *= 360;` `564 var R, G, B, X, C;` `565 h = (h % 360) / 60;` `566 C = 2 * s * (l < .5 ? l : 1 - l);` `567 X = C * (1 - abs(h % 2 - 1));` `568 R = G = B = l - C / 2;` `569` `570 h = ~~h;` `571 R += [C, X, 0, 0, X, C][h];` `572 G += [X, C, C, X, 0, 0][h];` `573 B += [0, 0, X, C, C, X][h];` `574 return packageRGB(R, G, B, o);` `575 };` `576 /*\` `577 * Raphael.rgb2hsb` `578 [ method ]` `579 **` `580 * Converts RGB values to HSB object.` `581 > Parameters` `582 - r (number) red` `583 - g (number) green` `584 - b (number) blue` `585 = (object) HSB object in format:` `586 o {` `587 o h (number) hue` `588 o s (number) saturation` `589 o b (number) brightness` `590 o }` `591 \*/` `592 R.rgb2hsb = function (r, g, b) {` `593 b = prepareRGB(r, g, b);` `594 r = b[0];` `595 g = b[1];` `596 b = b[2];` `597` `598 var H, S, V, C;` `599 V = mmax(r, g, b);` `600 C = V - mmin(r, g, b);` `601 H = (C == 0 ? null :` `602 V == r ? (g - b) / C :` `603 V == g ? (b - r) / C + 2 :` `604 (r - g) / C + 4);` `605 H = (H % 6) * 60;` `606 S = C == 0 ? 0 : C / V;` `607 return {h: H, s: S, b: V, toString: hsbtoString};` `608 };` `609 /*\` `610 * Raphael.rgb2hsl` `611 [ method ]` `612 **` `613 * Converts RGB values to HSL object.` `614 > Parameters` `615 - r (number) red` `616 - g (number) green` `617 - b (number) blue` `618 = (object) HSL object in format:` `619 o {` `620 o h (number) hue` `621 o s (number) saturation` `622 o l (number) luminosity` `623 o }` `624 \*/` `625 R.rgb2hsl = function (r, g, b) {` `626 b = prepareRGB(r, g, b);` `627 r = b[0];` `628 g = b[1];` `629 b = b[2];` `630` `631 var H, S, L, M, m, C;` `632 M = mmax(r, g, b);` `633 m = mmin(r, g, b);` `634 C = M - m;` `635 H = (C == 0 ? null :` `636 M == r ? (g - b) / C :` `637 M == g ? (b - r) / C + 2 :` `638 (r - g) / C + 4);` `639 H = (H % 6) * 60;` `640 L = (M + m) / 2;` `641 S = (C == 0 ? 0 :` `642 L < .5 ? C / (2 * L) :` `643 C / (2 - 2 * L));` `644 return {h: H, s: S, l: L, toString: hsltoString};` `645 };` `646 R._path2string = function () {` `647 return this.join(",").replace(p2s, "$1");` `648 };` `649 function cacher(f, scope, postprocessor) {` `650 function newf() {` `651 var arg = Array.prototype.slice.call(arguments, 0),` `652 args = arg.join("\u2400"),` `653 cache = newf.cache = newf.cache || {},` `654 count = newf.count = newf.count || [];` `655 if (cache[has](args)) {` `656 return postprocessor ? postprocessor(cache[args]) : cache[args];` `657 }` `658 count.length >= 1e3 && delete cache[count.shift()];` `659 count.push(args);` `660 cache[args] = f[apply](scope, arg);` `661 return postprocessor ? postprocessor(cache[args]) : cache[args];` `662 }` `663 return newf;` `664 }` `665` `666 function preload(src, f) {` `667 var img = g.doc.createElement("img");` `668 img.style.cssText = "position:absolute;left:-9999em;top-9999em";` `669 img.onload = function () {` `670 f.call(this);` `671 this.onload = null;` `672 g.doc.body.removeChild(this);` `673 };` `674 img.onerror = function () {` `675 g.doc.body.removeChild(this);` `676 };` `677 g.doc.body.appendChild(img);` `678 img.src = src;` `679 }` `680` `681 /*\` `682 * Raphael.getRGB` `683 [ method ]` `684 **` `685 * Parses colour string as RGB object` `686 > Parameters` `687 - colour (string) colour string in one of formats:` `688 # <ul>` `689 # <li>Colour name (“<code>red</code>”, “<code>green</code>”, “<code>cornflowerblue</code>”, etc)</li>` `690 # <li>#••• — shortened HTML colour: (“<code>#000</code>”, “<code>#fc0</code>”, etc)</li>` `691 # <li>#•••••• — full length HTML colour: (“<code>#000000</code>”, “<code>#bd2300</code>”)</li>` `692 # <li>rgb(•••, •••, •••) — red, green and blue channels’ values: (“<code>rgb(200, 100, 0)</code>”)</li>` `693 # <li>rgb(•••%, •••%, •••%) — same as above, but in %: (“<code>rgb(100%, 175%, 0%)</code>”)</li>` `694 # <li>hsb(•••, •••, •••) — hue, saturation and brightness values: (“<code>hsb(0.5, 0.25, 1)</code>”)</li>` `695 # <li>hsb(•••%, •••%, •••%) — same as above, but in %</li>` `696 # <li>hsl(•••, •••, •••) — same as hsb</li>` `697 # <li>hsl(•••%, •••%, •••%) — same as hsb</li>` `698 # </ul>` `699 = (object) RGB object in format:` `700 o {` `701 o r (number) red,` `702 o g (number) green,` `703 o b (number) blue` `704 o hex (string) color in HTML/CSS format: #••••••,` `705 o error (boolean) true if string can’t be parsed` `706 o }` `707 \*/` `708 R.getRGB = cacher(function (colour) {` `709 if (!colour || !!((colour = Str(colour)).indexOf("-") + 1)) {` `710 return {r: -1, g: -1, b: -1, hex: "none", error: 1};` `711 }` `712 if (colour == "none") {` `713 return {r: -1, g: -1, b: -1, hex: "none"};` `714 }` `715 !(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour));` `716 var res,` `717 red,` `718 green,` `719 blue,` `720 opacity,` `721 t,` `722 values,` `723 rgb = colour.match(colourRegExp);` `724 if (rgb) {` `725 if (rgb[2]) {` `726 blue = toInt(rgb[2].substring(5), 16);` `727 green = toInt(rgb[2].substring(3, 5), 16);` `728 red = toInt(rgb[2].substring(1, 3), 16);` `729 }` `730 if (rgb[3]) {` `731 blue = toInt((t = rgb[3].charAt(3)) + t, 16);` `732 green = toInt((t = rgb[3].charAt(2)) + t, 16);` `733 red = toInt((t = rgb[3].charAt(1)) + t, 16);` `734 }` `735 if (rgb[4]) {` `736 values = rgb[4].split(commaSpaces);` `737 red = toFloat(values[0]);` `738 values[0].slice(-1) == "%" && (red *= 2.55);` `739 green = toFloat(values[1]);` `740 values[1].slice(-1) == "%" && (green *= 2.55);` `741 blue = toFloat(values[2]);` `742 values[2].slice(-1) == "%" && (blue *= 2.55);` `743 rgb[1].toLowerCase().slice(0, 4) == "rgba" && (opacity = toFloat(values[3]));` `744 values[3] && values[3].slice(-1) == "%" && (opacity /= 100);` `745 }` `746 if (rgb[5]) {` `747 values = rgb[5].split(commaSpaces);` `748 red = toFloat(values[0]);` `749 values[0].slice(-1) == "%" && (red *= 2.55);` `750 green = toFloat(values[1]);` `751 values[1].slice(-1) == "%" && (green *= 2.55);` `752 blue = toFloat(values[2]);` `753 values[2].slice(-1) == "%" && (blue *= 2.55);` `754 (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360);` `755 rgb[1].toLowerCase().slice(0, 4) == "hsba" && (opacity = toFloat(values[3]));` `756 values[3] && values[3].slice(-1) == "%" && (opacity /= 100);` `757 return R.hsb2rgb(red, green, blue, opacity);` `758 }` `759 if (rgb[6]) {` `760 values = rgb[6].split(commaSpaces);` `761 red = toFloat(values[0]);` `762 values[0].slice(-1) == "%" && (red *= 2.55);` `763 green = toFloat(values[1]);` `764 values[1].slice(-1) == "%" && (green *= 2.55);` `765 blue = toFloat(values[2]);` `766 values[2].slice(-1) == "%" && (blue *= 2.55);` `767 (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360);` `768 rgb[1].toLowerCase().slice(0, 4) == "hsla" && (opacity = toFloat(values[3]));` `769 values[3] && values[3].slice(-1) == "%" && (opacity /= 100);` `770 return R.hsl2rgb(red, green, blue, opacity);` `771 }` `772 rgb = {r: red, g: green, b: blue};` `773 rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1);` `774 R.is(opacity, "finite") && (rgb.opacity = opacity);` `775 return rgb;` `776 }` `777 return {r: -1, g: -1, b: -1, hex: "none", error: 1};` `778 }, R);` `779 /*\` `780 * Raphael.hsb` `781 [ method ]` `782 **` `783 * Converts HSB values to hex representation of the colour.` `784 > Parameters` `785 - h (number) hue` `786 - s (number) saturation` `787 - b (number) value or brightness` `788 = (string) hex representation of the colour.` `789 \*/` `790 R.hsb = cacher(function (h, s, b) {` `791 return R.hsb2rgb(h, s, b).hex;` `792 });` `793 /*\` `794 * Raphael.hsl` `795 [ method ]` `796 **` `797 * Converts HSL values to hex representation of the colour.` `798 > Parameters` `799 - h (number) hue` `800 - s (number) saturation` `801 - l (number) luminosity` `802 = (string) hex representation of the colour.` `803 \*/` `804 R.hsl = cacher(function (h, s, l) {` `805 return R.hsl2rgb(h, s, l).hex;` `806 });` `807 /*\` `808 * Raphael.rgb` `809 [ method ]` `810 **` `811 * Converts RGB values to hex representation of the colour.` `812 > Parameters` `813 - r (number) red` `814 - g (number) green` `815 - b (number) blue` `816 = (string) hex representation of the colour.` `817 \*/` `818 R.rgb = cacher(function (r, g, b) {` `819 return "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1);` `820 });` `821 /*\` `822 * Raphael.getColor` `823 [ method ]` `824 **` `825 * On each call returns next colour in the spectrum. To reset it back to red call @Raphael.getColor.reset` `826 > Parameters` `827 - value (number) #optional brightness, default is `0.75`` `828 = (string) hex representation of the colour.` `829 \*/` `830 R.getColor = function (value) {` `831 var start = this.getColor.start = this.getColor.start || {h: 0, s: 1, b: value || .75},` `832 rgb = this.hsb2rgb(start.h, start.s, start.b);` `833 start.h += .075;` `834 if (start.h > 1) {` `835 start.h = 0;` `836 start.s -= .2;` `837 start.s <= 0 && (this.getColor.start = {h: 0, s: 1, b: start.b});` `838 }` `839 return rgb.hex;` `840 };` `841 /*\` `842 * Raphael.getColor.reset` `843 [ method ]` `844 **` `845 * Resets spectrum position for @Raphael.getColor back to red.` `846 \*/` `847 R.getColor.reset = function () {` `848 delete this.start;` `849 };` `850` `851 /*\` `852 * Raphael.parsePathString` `853 [ method ]` `854 **` `855 * Utility method` `856 **` `857 * Parses given path string into an array of arrays of path segments.` `858 > Parameters` `859 - pathString (string|array) path string or array of segments (in the last case it will be returned straight away)` `860 = (array) array of segments.` `861 \*/` `862 R.parsePathString = cacher(function (pathString) {` `863 if (!pathString) {` `864 return null;` `865 }` `866 var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0},` `867 data = [];` `868 if (R.is(pathString, array) && R.is(pathString[0], array)) { // rough assumption` `869 data = pathClone(pathString);` `870 }` `871 if (!data.length) {` `872 Str(pathString).replace(pathCommand, function (a, b, c) {` `873 var params = [],` `874 name = lowerCase.call(b);` `875 c.replace(pathValues, function (a, b) {` `876 b && params.push(+b);` `877 });` `878 if (name == "m" && params.length > 2) {` `879 data.push([b][concat](params.splice(0, 2)));` `880 name = "l";` `881 b = b == "m" ? "l" : "L";` `882 }` `883 while (params.length >= paramCounts[name]) {` `884 data.push([b][concat](params.splice(0, paramCounts[name])));` `885 if (!paramCounts[name]) {` `886 break;` `887 }` `888 }` `889 });` `890 }` `891 data.toString = R._path2string;` `892 return data;` `893 });` `894 /*\` `895 * Raphael.parseTransformString` `896 [ method ]` `897 **` `898 * Utility method` `899 **` `900 * Parses given path string into an array of transformations.` `901 > Parameters` `902 - TString (string|array) transform string or array of transformations (in the last case it will be returned straight away)` `903 = (array) array of transformations.` `904 \*/` `905 R.parseTransformString = cacher(function (TString) {` `906 if (!TString) {` `907 return null;` `908 }` `909 var paramCounts = {r: 3, s: 4, t: 2, m: 6},` `910 data = [];` `911 if (R.is(TString, array) && R.is(TString[0], array)) { // rough assumption` `912 data = pathClone(TString);` `913 }` `914 if (!data.length) {` `915 Str(TString).replace(tCommand, function (a, b, c) {` `916 var params = [],` `917 name = lowerCase.call(b);` `918 c.replace(pathValues, function (a, b) {` `919 b && params.push(+b);` `920 });` `921 data.push([name][concat](params));` `922 });` `923 }` `924 data.toString = R._path2string;` `925 return data;` `926 });` `927 /*\` `928 * Raphael.findDotsAtSegment` `929 [ method ]` `930 **` `931 * Utility method` `932 **` `933 * Find dot coordinates on the given cubic bezier curve at the given t.` `934 > Parameters` `935 - p1x (number) x of the first point of the curve` `936 - p1y (number) y of the first point of the curve` `937 - c1x (number) x of the first anchor of the curve` `938 - c1y (number) y of the first anchor of the curve` `939 - c2x (number) x of the second anchor of the curve` `940 - c2y (number) y of the second anchor of the curve` `941 - p2x (number) x of the second point of the curve` `942 - p2y (number) y of the second point of the curve` `943 - t (number) position on the curve (0..1)` `944 = (object) point information in format:` `945 o {` `946 o x: (number) x coordinate of the point` `947 o y: (number) y coordinate of the point` `948 o m: {` `949 o x: (number) x coordinate of the left anchor` `950 o y: (number) y coordinate of the left anchor` `951 o }` `952 o n: {` `953 o x: (number) x coordinate of the right anchor` `954 o y: (number) y coordinate of the right anchor` `955 o }` `956 o start: {` `957 o x: (number) x coordinate of the start of the curve` `958 o y: (number) y coordinate of the start of the curve` `959 o }` `960 o end: {` `961 o x: (number) x coordinate of the end of the curve` `962 o y: (number) y coordinate of the end of the curve` `963 o }` `964 o alpha: (number) angle of the curve derivative at the point` `965 o }` `966 \*/` `967 R.findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {` `968 var t1 = 1 - t,` `969 x = pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,` `970 y = pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y,` `971 mx = p1x + 2 * t * (c1x - p1x) + t * t * (c2x - 2 * c1x + p1x),` `972 my = p1y + 2 * t * (c1y - p1y) + t * t * (c2y - 2 * c1y + p1y),` `973 nx = c1x + 2 * t * (c2x - c1x) + t * t * (p2x - 2 * c2x + c1x),` `974 ny = c1y + 2 * t * (c2y - c1y) + t * t * (p2y - 2 * c2y + c1y),` `975 ax = (1 - t) * p1x + t * c1x,` `976 ay = (1 - t) * p1y + t * c1y,` `977 cx = (1 - t) * c2x + t * p2x,` `978 cy = (1 - t) * c2y + t * p2y,` `979 alpha = (90 - math.atan2(mx - nx, my - ny) * 180 / PI);` `980 (mx > nx || my < ny) && (alpha += 180);` `981 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};` `982 };` `983 var pathDimensions = cacher(function (path) {` `984 if (!path) {` `985 return {x: 0, y: 0, width: 0, height: 0};` `986 }` `987 path = path2curve(path);` `988 var x = 0,` `989 y = 0,` `990 X = [],` `991 Y = [],` `992 p;` `993 for (var i = 0, ii = path.length; i < ii; i++) {` `994 p = path[i];` `995 if (p[0] == "M") {` `996 x = p[1];` `997 y = p[2];` `998 X.push(x);` `999 Y.push(y);` `1000 } else {` `1001 var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);` `1002 X = X[concat](dim.min.x, dim.max.x);` `1003 Y = Y[concat](dim.min.y, dim.max.y);` `1004 x = p[5];` `1005 y = p[6];` `1006 }` `1007 }` `1008 var xmin = mmin[apply](0, X),` `1009 ymin = mmin[apply](0, Y);` `1010 return {` `1011 x: xmin,` `1012 y: ymin,` `1013 width: mmax[apply](0, X) - xmin,` `1014 height: mmax[apply](0, Y) - ymin` `1015 };` `1016 }),` `1017 pathClone = function (pathArray) {` `1018 var res = [];` `1019 if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption` `1020 pathArray = R.parsePathString(pathArray);` `1021 }` `1022 for (var i = 0, ii = pathArray.length; i < ii; i++) {` `1023 res[i] = [];` `1024 for (var j = 0, jj = pathArray[i].length; j < jj; j++) {` `1025 res[i][j] = pathArray[i][j];` `1026 }` `1027 }` `1028 res.toString = R._path2string;` `1029 return res;` `1030 },` `1031 pathToRelative = cacher(function (pathArray) {` `1032 if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption` `1033 pathArray = R.parsePathString(pathArray);` `1034 }` `1035 var res = [],` `1036 x = 0,` `1037 y = 0,` `1038 mx = 0,` `1039 my = 0,` `1040 start = 0;` `1041 if (pathArray[0][0] == "M") {` `1042 x = pathArray[0][1];` `1043 y = pathArray[0][2];` `1044 mx = x;` `1045 my = y;` `1046 start++;` `1047 res.push(["M", x, y]);` `1048 }` `1049 for (var i = start, ii = pathArray.length; i < ii; i++) {` `1050 var r = res[i] = [],` `1051 pa = pathArray[i];` `1052 if (pa[0] != lowerCase.call(pa[0])) {` `1053 r[0] = lowerCase.call(pa[0]);` `1054 switch (r[0]) {` `1055 case "a":` `1056 r[1] = pa[1];` `1057 r[2] = pa[2];` `1058 r[3] = pa[3];` `1059 r[4] = pa[4];` `1060 r[5] = pa[5];` `1061 r[6] = +(pa[6] - x).toFixed(3);` `1062 r[7] = +(pa[7] - y).toFixed(3);` `1063 break;` `1064 case "v":` `1065 r[1] = +(pa[1] - y).toFixed(3);` `1066 break;` `1067 case "m":` `1068 mx = pa[1];` `1069 my = pa[2];` `1070 default:` `1071 for (var j = 1, jj = pa.length; j < jj; j++) {` `1072 r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3);` `1073 }` `1074 }` `1075 } else {` `1076 r = res[i] = [];` `1077 if (pa[0] == "m") {` `1078 mx = pa[1] + x;` `1079 my = pa[2] + y;` `1080 }` `1081 for (var k = 0, kk = pa.length; k < kk; k++) {` `1082 res[i][k] = pa[k];` `1083 }` `1084 }` `1085 var len = res[i].length;` `1086 switch (res[i][0]) {` `1087 case "z":` `1088 x = mx;` `1089 y = my;` `1090 break;` `1091 case "h":` `1092 x += +res[i][len - 1];` `1093 break;` `1094 case "v":` `1095 y += +res[i][len - 1];` `1096 break;` `1097 default:` `1098 x += +res[i][len - 2];` `1099 y += +res[i][len - 1];` `1100 }` `1101 }` `1102 res.toString = R._path2string;` `1103 return res;` `1104 }, 0, pathClone),` `1105 pathToAbsolute = cacher(function (pathArray) {` `1106 if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption` `1107 pathArray = R.parsePathString(pathArray);` `1108 }` `1109 var res = [],` `1110 x = 0,` `1111 y = 0,` `1112 mx = 0,` `1113 my = 0,` `1114 start = 0;` `1115 if (pathArray[0][0] == "M") {` `1116 x = +pathArray[0][1];` `1117 y = +pathArray[0][2];` `1118 mx = x;` `1119 my = y;` `1120 start++;` `1121 res[0] = ["M", x, y];` `1122 }` `1123 for (var i = start, ii = pathArray.length; i < ii; i++) {` `1124 var r = res[i] = [],` `1125 pa = pathArray[i];` `1126 if (pa[0] != upperCase.call(pa[0])) {` `1127 r[0] = upperCase.call(pa[0]);` `1128 switch (r[0]) {` `1129 case "A":` `1130 r[1] = pa[1];` `1131 r[2] = pa[2];` `1132 r[3] = pa[3];` `1133 r[4] = pa[4];` `1134 r[5] = pa[5];` `1135 r[6] = +(pa[6] + x);` `1136 r[7] = +(pa[7] + y);` `1137 break;` `1138 case "V":` `1139 r[1] = +pa[1] + y;` `1140 break;` `1141 case "H":` `1142 r[1] = +pa[1] + x;` `1143 break;` `1144 case "M":` `1145 mx = +pa[1] + x;` `1146 my = +pa[2] + y;` `1147 default:` `1148 for (var j = 1, jj = pa.length; j < jj; j++) {` `1149 r[j] = +pa[j] + ((j % 2) ? x : y);` `1150 }` `1151 }` `1152 } else {` `1153 for (var k = 0, kk = pa.length; k < kk; k++) {` `1154 res[i][k] = pa[k];` `1155 }` `1156 }` `1157 switch (r[0]) {` `1158 case "Z":` `1159 x = mx;` `1160 y = my;` `1161 break;` `1162 case "H":` `1163 x = r[1];` `1164 break;` `1165 case "V":` `1166 y = r[1];` `1167 break;` `1168 case "M":` `1169 mx = res[i][res[i].length - 2];` `1170 my = res[i][res[i].length - 1];` `1171 default:` `1172 x = res[i][res[i].length - 2];` `1173 y = res[i][res[i].length - 1];` `1174 }` `1175 }` `1176 res.toString = R._path2string;` `1177 return res;` `1178 }, null, pathClone),` `1179 l2c = function (x1, y1, x2, y2) {` `1180 return [x1, y1, x2, y2, x2, y2];` `1181 },` `1182 q2c = function (x1, y1, ax, ay, x2, y2) {` `1183 var _13 = 1 / 3,` `1184 _23 = 2 / 3;` `1185 return [` `1186 _13 * x1 + _23 * ax,` `1187 _13 * y1 + _23 * ay,` `1188 _13 * x2 + _23 * ax,` `1189 _13 * y2 + _23 * ay,` `1190 x2,` `1191 y2` `1192 ];` `1193 },` `1194 a2c = function (x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {` `1195 // for more information of where this math came from visit:` `1196 // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes` `1197 var _120 = PI * 120 / 180,` `1198 rad = PI / 180 * (+angle || 0),` `1199 res = [],` `1200 xy,` `1201 rotate = cacher(function (x, y, rad) {` `1202 var X = x * math.cos(rad) - y * math.sin(rad),` `1203 Y = x * math.sin(rad) + y * math.cos(rad);` `1204 return {x: X, y: Y};` `1205 });` `1206 if (!recursive) {` `1207 xy = rotate(x1, y1, -rad);` `1208 x1 = xy.x;` `1209 y1 = xy.y;` `1210 xy = rotate(x2, y2, -rad);` `1211 x2 = xy.x;` `1212 y2 = xy.y;` `1213 var cos = math.cos(PI / 180 * angle),` `1214 sin = math.sin(PI / 180 * angle),` `1215 x = (x1 - x2) / 2,` `1216 y = (y1 - y2) / 2;` `1217 var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);` `1218 if (h > 1) {` `1219 h = math.sqrt(h);` `1220 rx = h * rx;` `1221 ry = h * ry;` `1222 }` `1223 var rx2 = rx * rx,` `1224 ry2 = ry * ry,` `1225 k = (large_arc_flag == sweep_flag ? -1 : 1) *` `1226 math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),` `1227 cx = k * rx * y / ry + (x1 + x2) / 2,` `1228 cy = k * -ry * x / rx + (y1 + y2) / 2,` `1229 f1 = math.asin(((y1 - cy) / ry).toFixed(9)),` `1230 f2 = math.asin(((y2 - cy) / ry).toFixed(9));` `1231` `1232 f1 = x1 < cx ? PI - f1 : f1;` `1233 f2 = x2 < cx ? PI - f2 : f2;` `1234 f1 < 0 && (f1 = PI * 2 + f1);` `1235 f2 < 0 && (f2 = PI * 2 + f2);` `1236 if (sweep_flag && f1 > f2) {` `1237 f1 = f1 - PI * 2;` `1238 }` `1239 if (!sweep_flag && f2 > f1) {` `1240 f2 = f2 - PI * 2;` `1241 }` `1242 } else {` `1243 f1 = recursive[0];` `1244 f2 = recursive[1];` `1245 cx = recursive[2];` `1246 cy = recursive[3];` `1247 }` `1248 var df = f2 - f1;` `1249 if (abs(df) > _120) {` `1250 var f2old = f2,` `1251 x2old = x2,` `1252 y2old = y2;` `1253 f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);` `1254 x2 = cx + rx * math.cos(f2);` `1255 y2 = cy + ry * math.sin(f2);` `1256 res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);` `1257 }` `1258 df = f2 - f1;` `1259 var c1 = math.cos(f1),` `1260 s1 = math.sin(f1),` `1261 c2 = math.cos(f2),` `1262 s2 = math.sin(f2),` `1263 t = math.tan(df / 4),` `1264 hx = 4 / 3 * rx * t,` `1265 hy = 4 / 3 * ry * t,` `1266 m1 = [x1, y1],` `1267 m2 = [x1 + hx * s1, y1 - hy * c1],` `1268 m3 = [x2 + hx * s2, y2 - hy * c2],` `1269 m4 = [x2, y2];` `1270 m2[0] = 2 * m1[0] - m2[0];` `1271 m2[1] = 2 * m1[1] - m2[1];` `1272 if (recursive) {` `1273 return [m2, m3, m4][concat](res);` `1274 } else {` `1275 res = [m2, m3, m4][concat](res).join().split(",");` `1276 var newres = [];` `1277 for (var i = 0, ii = res.length; i < ii; i++) {` `1278 newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;` `1279 }` `1280 return newres;` `1281 }` `1282 },` `1283 findDotAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {` `1284 var t1 = 1 - t;` `1285 return {` `1286 x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,` `1287 y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y` `1288 };` `1289 },` `1290 curveDim = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {` `1291 var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x),` `1292 b = 2 * (c1x - p1x) - 2 * (c2x - c1x),` `1293 c = p1x - c1x,` `1294 t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a,` `1295 t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a,` `1296 y = [p1y, p2y],` `1297 x = [p1x, p2x],` `1298 dot;` `1299 abs(t1) > "1e12" && (t1 = .5);` `1300 abs(t2) > "1e12" && (t2 = .5);` `1301 if (t1 > 0 && t1 < 1) {` `1302 dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);` `1303 x.push(dot.x);` `1304 y.push(dot.y);` `1305 }` `1306 if (t2 > 0 && t2 < 1) {` `1307 dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);` `1308 x.push(dot.x);` `1309 y.push(dot.y);` `1310 }` `1311 a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y);` `1312 b = 2 * (c1y - p1y) - 2 * (c2y - c1y);` `1313 c = p1y - c1y;` `1314 t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a;` `1315 t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a;` `1316 abs(t1) > "1e12" && (t1 = .5);` `1317 abs(t2) > "1e12" && (t2 = .5);` `1318 if (t1 > 0 && t1 < 1) {` `1319 dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);` `1320 x.push(dot.x);` `1321 y.push(dot.y);` `1322 }` `1323 if (t2 > 0 && t2 < 1) {` `1324 dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);` `1325 x.push(dot.x);` `1326 y.push(dot.y);` `1327 }` `1328 return {` `1329 min: {x: mmin[apply](0, x), y: mmin[apply](0, y)},` `1330 max: {x: mmax[apply](0, x), y: mmax[apply](0, y)}` `1331 };` `1332 }),` `1333 path2curve = cacher(function (path, path2) {` `1334 var p = pathToAbsolute(path),` `1335 p2 = path2 && pathToAbsolute(path2),` `1336 attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},` `1337 attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},` `1338 processPath = function (path, d) {` `1339 var nx, ny;` `1340 if (!path) {` `1341 return ["C", d.x, d.y, d.x, d.y, d.x, d.y];` `1342 }` `1343 !(path[0] in {T:1, Q:1}) && (d.qx = d.qy = null);` `1344 switch (path[0]) {` `1345 case "M":` `1346 d.X = path[1];` `1347 d.Y = path[2];` `1348 break;` `1349 case "A":` `1350 path = ["C"][concat](a2c[apply](0, [d.x, d.y][concat](path.slice(1))));` `1351 break;` `1352 case "S":` `1353 nx = d.x + (d.x - (d.bx || d.x));` `1354 ny = d.y + (d.y - (d.by || d.y));` `1355 path = ["C", nx, ny][concat](path.slice(1));` `1356 break;` `1357 case "T":` `1358 d.qx = d.x + (d.x - (d.qx || d.x));` `1359 d.qy = d.y + (d.y - (d.qy || d.y));` `1360 path = ["C"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));` `1361 break;` `1362 case "Q":` `1363 d.qx = path[1];` `1364 d.qy = path[2];` `1365 path = ["C"][concat](q2c(d.x, d.y, path[1], path[2], path[3], path[4]));` `1366 break;` `1367 case "L":` `1368 path = ["C"][concat](l2c(d.x, d.y, path[1], path[2]));` `1369 break;` `1370 case "H":` `1371 path = ["C"][concat](l2c(d.x, d.y, path[1], d.y));` `1372 break;` `1373 case "V":` `1374 path = ["C"][concat](l2c(d.x, d.y, d.x, path[1]));` `1375 break;` `1376 case "Z":` `1377 path = ["C"][concat](l2c(d.x, d.y, d.X, d.Y));` `1378 break;` `1379 }` `1380 return path;` `1381 },` `1382 fixArc = function (pp, i) {` `1383 if (pp[i].length > 7) {` `1384 pp[i].shift();` `1385 var pi = pp[i];` `1386 while (pi.length) {` `1387 pp.splice(i++, 0, ["C"][concat](pi.splice(0, 6)));` `1388 }` `1389 pp.splice(i, 1);` `1390 ii = mmax(p.length, p2 && p2.length || 0);` `1391 }` `1392 },` `1393 fixM = function (path1, path2, a1, a2, i) {` `1394 if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") {` `1395 path2.splice(i, 0, ["M", a2.x, a2.y]);` `1396 a1.bx = 0;` `1397 a1.by = 0;` `1398 a1.x = path1[i][1];` `1399 a1.y = path1[i][2];` `1400 ii = mmax(p.length, p2 && p2.length || 0);` `1401 }` `1402 };` `1403 for (var i = 0, ii = mmax(p.length, p2 && p2.length || 0); i < ii; i++) {` `1404 p[i] = processPath(p[i], attrs);` `1405 fixArc(p, i);` `1406 p2 && (p2[i] = processPath(p2[i], attrs2));` `1407 p2 && fixArc(p2, i);` `1408 fixM(p, p2, attrs, attrs2, i);` `1409 fixM(p2, p, attrs2, attrs, i);` `1410 var seg = p[i],` `1411 seg2 = p2 && p2[i],` `1412 seglen = seg.length,` `1413 seg2len = p2 && seg2.length;` `1414 attrs.x = seg[seglen - 2];` `1415 attrs.y = seg[seglen - 1];` `1416 attrs.bx = toFloat(seg[seglen - 4]) || attrs.x;` `1417 attrs.by = toFloat(seg[seglen - 3]) || attrs.y;` `1418 attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x);` `1419 attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y);` `1420 attrs2.x = p2 && seg2[seg2len - 2];` `1421 attrs2.y = p2 && seg2[seg2len - 1];` `1422 }` `1423 return p2 ? [p, p2] : p;` `1424 }, null, pathClone),` `1425 parseDots = cacher(function (gradient) {` `1426 var dots = [];` `1427 for (var i = 0, ii = gradient.length; i < ii; i++) {` `1428 var dot = {},` `1429 par = gradient[i].match(/^([^:]*):?([\d\.]*)/);` `1430 dot.color = R.getRGB(par[1]);` `1431 if (dot.color.error) {` `1432 return null;` `1433 }` `1434 dot.color = dot.color.hex;` `1435 par[2] && (dot.offset = par[2] + "%");` `1436 dots.push(dot);` `1437 }` `1438 for (i = 1, ii = dots.length - 1; i < ii; i++) {` `1439 if (!dots[i].offset) {` `1440 var start = toFloat(dots[i - 1].offset || 0),` `1441 end = 0;` `1442 for (var j = i + 1; j < ii; j++) {` `1443 if (dots[j].offset) {` `1444 end = dots[j].offset;` `1445 break;` `1446 }` `1447 }` `1448 if (!end) {` `1449 end = 100;` `1450 j = ii;` `1451 }` `1452 end = toFloat(end);` `1453 var d = (end - start) / (j - i + 1);` `1454 for (; i < j; i++) {` `1455 start += d;` `1456 dots[i].offset = start + "%";` `1457 }` `1458 }` `1459 }` `1460 return dots;` `1461 }),` `1462 getContainer = function (x, y, w, h) {` `1463 var container;` `1464 container = h == null && !R.is(x, "object") ? g.doc.getElementById(x) : x;` `1465 if (container == null) {` `1466 return;` `1467 }` `1468 if (container.tagName) {` `1469 if (y == null) {` `1470 return {` `1471 container: container,` `1472 width: container.style.pixelWidth || container.offsetWidth,` `1473 height: container.style.pixelHeight || container.offsetHeight` `1474 };` `1475 } else {` `1476 return {container: container, width: y, height: w};` `1477 }` `1478 }` `1479 return {container: 1, x: x, y: y, width: w, height: h};` `1480 },` `1481 plugins = function (con, add) {` `1482 var that = this;` `1483 for (var prop in add) {` `1484 if (add[has](prop) && !(prop in con)) {` `1485 switch (typeof add[prop]) {` `1486 case "function":` `1487 (function (f) {` `1488 con[prop] = con === that ? f : function () { return f[apply](that, arguments); };` `1489 })(add[prop]);` `1490 break;` `1491 case "object":` `1492 con[prop] = con[prop] || {};` `1493 plugins.call(this, con[prop], add[prop]);` `1494 break;` `1495 default:` `1496 con[prop] = add[prop];` `1497 break;` `1498 }` `1499 }` `1500 }` `1501 },` `1502 tear = function (el, paper) {` `1503 el == paper.top && (paper.top = el.prev);` `1504 el == paper.bottom && (paper.bottom = el.next);` `1505 el.next && (el.next.prev = el.prev);` `1506 el.prev && (el.prev.next = el.next);` `1507 },` `1508 tofront = function (el, paper) {` `1509 if (paper.top === el) {` `1510 return;` `1511 }` `1512 tear(el, paper);` `1513 el.next = null;` `1514 el.prev = paper.top;` `1515 paper.top.next = el;` `1516 paper.top = el;` `1517 },` `1518 toback = function (el, paper) {` `1519 if (paper.bottom === el) {` `1520 return;` `1521 }` `1522 tear(el, paper);` `1523 el.next = paper.bottom;` `1524 el.prev = null;` `1525 paper.bottom.prev = el;` `1526 paper.bottom = el;` `1527 },` `1528 insertafter = function (el, el2, paper) {` `1529 tear(el, paper);` `1530 el2 == paper.top && (paper.top = el);` `1531 el2.next && (el2.next.prev = el);` `1532 el.next = el2.next;` `1533 el.prev = el2;` `1534 el2.next = el;` `1535 },` `1536 insertbefore = function (el, el2, paper) {` `1537 tear(el, paper);` `1538 el2 == paper.bottom && (paper.bottom = el);` `1539 el2.prev && (el2.prev.next = el);` `1540 el.prev = el2.prev;` `1541 el2.prev = el;` `1542 el.next = el2;` `1543 },` `1544 removed = function (methodname) {` `1545 return function () {` `1546 throw new Error("Rapha\xebl: you are calling to method \u201c" + methodname + "\u201d of removed object");` `1547 };` `1548 },` `1549 extractTransform = function (el, tstr) {` `1550 if (tstr == null) {` `1551 return el._.transform;` `1552 }` `1553 tstr = Str(tstr).replace(/\.{3}|\u2026/g, el._.transform || E);` `1554 var tdata = R.parseTransformString(tstr),` `1555 deg = 0,` `1556 dx = 0,` `1557 dy = 0,` `1558 sx = 1,` `1559 sy = 1,` `1560 _ = el._,` `1561 m = new Matrix;` `1562 _.transform = tdata || [];` `1563 if (tdata) {` `1564 for (var i = 0, ii = tdata.length; i < ii; i++) {` `1565 var t = tdata[i],` `1566 tlen = t.length,` `1567 bb;` `1568 t[0] = Str(t[0]).toLowerCase();` `1569 if (t[0] == "t" && tlen == 3) {` `1570 m.translate(t[1], t[2]);` `1571 } else if (t[0] == "r") {` `1572 if (tlen == 2) {` `1573 bb = bb || el.getBBox(1);` `1574 m.rotate(t[1], bb.x + bb.width / 2, bb.y + bb.height / 2);` `1575 deg += t[1];` `1576 } else if (tlen == 4) {` `1577 m.rotate(t[1], t[2], t[3]);` `1578 deg += t[1];` `1579 }` `1580 } else if (t[0] == "s") {` `1581 if (tlen == 2 || tlen == 3) {` `1582 bb = bb || el.getBBox(1);` `1583 m.scale(t[1], t[tlen - 1], bb.x + bb.width / 2, bb.y + bb.height / 2);` `1584 sx *= t[1];` `1585 sy *= t[tlen - 1];` `1586 } else if (tlen == 5) {` `1587 m.scale(t[1], t[2], t[3], t[4]);` `1588 sx *= t[1];` `1589 sy *= t[2];` `1590 }` `1591 } else if (t[0] == "m" && tlen == 7) {` `1592 m.add(t[1], t[2], t[3], t[4], t[5], t[6]);` `1593 }` `1594 _.dirtyT = 1;` `1595 el.matrix = m;` `1596 }` `1597 }` `1598` `1599 el.matrix = m;` `1600` `1601 _.sx = sx;` `1602 _.sy = sy;` `1603 _.deg = deg;` `1604 _.dx = dx = m.m[0][2];` `1605 _.dy = dy = m.m[1][2];` `1606` `1607 if (sx == 1 && sy == 1 && !deg && _.bbox) {` `1608 _.bbox.x += +dx;` `1609 _.bbox.y += +dy;` `1610 } else {` `1611 _.dirtyT = 1;` `1612 }` `1613 },` `1614 getEmpty = function (item) {` `1615 switch (item[0]) {` `1616 case "t": return ["t", 0, 0];` `1617 case "m": return ["m", 1, 0, 0, 1, 0, 0];` `1618 case "r": if (item.length == 4) {` `1619 return ["r", 0, item[2], item[3]];` `1620 } else {` `1621 return ["r", 0];` `1622 }` `1623 case "s": if (item.length == 5) {` `1624 return ["s", 1, 1, item[3], item[4]];` `1625 } else if (item.length == 3) {` `1626 return ["s", 1, 1];` `1627 } else {` `1628 return ["s", 1];` `1629 }` `1630 }` `1631 },` `1632 equaliseTransform = function (t1, t2) {` `1633 t1 = R.parseTransformString(t1) || [];` `1634 t2 = R.parseTransformString(t2) || [];` `1635 var maxlength = mmax(t1.length, t2.length),` `1636 from = [],` `1637 to = [],` `1638 i = 0, j, jj,` `1639 tt1, tt2;` `1640 for (; i < maxlength; i++) {` `1641 tt1 = t1[i] || getEmpty(t2[i]);` `1642 tt2 = t2[i] || getEmpty(tt1);` `1643 if ( (tt1[0] != tt2[0]) ||` `1644 (tt1[0] == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3])) ||` `1645 (tt1[0] == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4]))` `1646 ) {` `1647 return;` `1648 }` `1649 from[i] = [];` `1650 to[i] = [];` `1651 for (j = 0, jj = mmax(tt1.length, tt2.length); j < jj; j++) {` `1652 j in tt1 && (from[i][j] = tt1[j]);` `1653 j in tt2 && (to[i][j] = tt2[j]);` `1654 }` `1655 }` `1656 return {` `1657 from: from,` `1658 to: to` `1659 };` `1660 };` `1661 /*\` `1662 * Raphael.pathToRelative` `1663 [ method ]` `1664 **` `1665 * Utility method` `1666 **` `1667 * Converts path to relative form` `1668 > Parameters` `1669 - pathString (string|array) path string or array of segments` `1670 = (array) array of segments.` `1671 \*/` `1672 R.pathToRelative = pathToRelative;` `1673 /*\` `1674 * Raphael.path2curve` `1675 [ method ]` `1676 **` `1677 * Utility method` `1678 **` `1679 * Converts path to a new path where all segments are cubic bezier curves.` `1680 > Parameters` `1681 - pathString (string|array) path string or array of segments` `1682 = (array) array of segments.` `1683 \*/` `1684 R.path2curve = path2curve;` `1685 // Matrix` `1686 // var m = document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix();` `1687 function Matrix(a, b, c, d, e, f) {` `1688 if (a != null) {` `1689 this.m = [[a, c, e], [b, d, f], [0, 0, 1]];` `1690 } else {` `1691 this.m = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];` `1692 }` `1693 }` `1694 var matrixproto = Matrix.prototype;` `1695 matrixproto.add = function (a, b, c, d, e, f) {` `1696 var out = [[], [], []],` `1697 matrix = [[a, c, e], [b, d, f], [0, 0, 1]],` `1698 x, y, z, res;` `1699` `1700 for (x = 0; x < 3; x++) {` `1701 for (y = 0; y < 3; y++) {` `1702 res = 0;` `1703 for (z = 0; z < 3; z++) {` `1704 res += this.m[x][z] * matrix[z][y];` `1705 }` `1706 out[x][y] = res;` `1707 }` `1708 }` `1709 this.m = out;` `1710 };` `1711 matrixproto.invert = function () {` `1712 var a = this.m[0][0],` `1713 b = this.m[1][0],` `1714 c = this.m[0][1],` `1715 d = this.m[1][1],` `1716 e = this.m[0][2],` `1717 f = this.m[1][2],` `1718 x = a * d - b * c;` `1719 return new Matrix(d / x, -b / x, -c / x, a / x, (c * f - d * e) / x, (b * e - a * f) / x);` `1720 };` `1721 matrixproto.clone = function () {` `1722 var a = this.m[0][0],` `1723 b = this.m[1][0],` `1724 c = this.m[0][1],` `1725 d = this.m[1][1],` `1726 e = this.m[0][2],` `1727 f = this.m[1][2];` `1728 return new Matrix(a, b, c, d, e, f);` `1729 };` `1730 matrixproto.translate = function (x, y) {` `1731 this.add(1, 0, 0, 1, x, y);` `1732 };` `1733 matrixproto.scale = function (x, y, cx, cy) {` `1734 y == null && (y = x);` `1735 this.add(1, 0, 0, 1, cx, cy);` `1736 this.add(x, 0, 0, y, 0, 0);` `1737 this.add(1, 0, 0, 1, -cx, -cy);` `1738 };` `1739 matrixproto.rotate = function (a, x, y) {` `1740 a = R.rad(a);` `1741 var cos = +math.cos(a).toFixed(9),` `1742 sin = +math.sin(a).toFixed(9);` `1743 this.add(cos, sin, -sin, cos, x, y);` `1744 this.add(1, 0, 0, 1, -x, -y);` `1745 };` `1746 matrixproto.x = function (x, y) {` `1747 return x * this.m[0][0] + y * this.m[0][1] + this.m[0][2];` `1748 };` `1749 matrixproto.y = function (x, y) {` `1750 return x * this.m[1][0] + y * this.m[1][1] + this.m[1][2];` `1751 };` `1752 matrixproto.get = function (i, j) {` `1753 return +this.m[i][j].toFixed(4);` `1754 };` `1755 matrixproto.toString = function () {` `1756 return R.svg ?` `1757 "matrix(" + [this.get(0, 0), this.get(1, 0), this.get(0, 1), this.get(1, 1), this.get(0, 2), this.get(1, 2)].join() + ")" :` `1758 [this.get(0, 0), this.get(0, 1), this.get(1, 0), this.get(1, 1), 0, 0].join();` `1759 };` `1760 matrixproto.toFilter = function () {` `1761 return "progid:DXImageTransform.Microsoft.Matrix(M11=" + this.get(0, 0) +` `1762 ", M12=" + this.get(0, 1) + ", M21=" + this.get(1, 0) + ", M22=" + this.get(1, 1) +` `1763 ", Dx=" + this.get(0, 2) + ", Dy=" + this.get(1, 2) + ", sizingmedthod='auto expand')";` `1764 };` `1765 matrixproto.offset = function () {` `1766 return [this.m[0][2].toFixed(4), this.m[1][2].toFixed(4)];` `1767 };` `1768` `1769 R.Matrix = Matrix;` `1770` `1771 // SVG` `1772 if (R.svg) {` `1773 var xlink = "http://www.w3.org/1999/xlink",` `1774 markers = {` `1775 block: "M5,0 0,2.5 5,5z",` `1776 classic: "M5,0 0,2.5 5,5 3.5,3 3.5,2z",` `1777 diamond: "M2.5,0 5,2.5 2.5,5 0,2.5z",` `1778 open: "M6,1 1,3.5 6,6",` `1779 oval: "M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"` `1780 },` `1781 markerCounter = {};` `1782 R.toString = function () {` `1783 return "Your browser supports SVG.\nYou are running Rapha\xebl " + this.version;` `1784 };` `1785 var $ = function (el, attr) {` `1786 if (attr) {` `1787 if (typeof el == "string") {` `1788 el = $(el);` `1789 }` `1790 for (var key in attr) if (attr[has](key)) {` `1791 if (key.substring(0, 6) == "xlink:") {` `1792 el.setAttributeNS(xlink, key.substring(6), Str(attr[key]));` `1793 } else {` `1794 el[setAttribute](key, Str(attr[key]));` `1795 }` `1796 }` `1797 } else {` `1798 el = g.doc.createElementNS("http://www.w3.org/2000/svg", el);` `1799 el.style && (el.style.webkitTapHighlightColor = "rgba(0,0,0,0)");` `1800 }` `1801 return el;` `1802 },` `1803 thePath = function (pathString, SVG) {` `1804 var el = $("path");` `1805 SVG.canvas && SVG.canvas.appendChild(el);` `1806 var p = new Element(el, SVG);` `1807 p.type = "path";` `1808 setFillAndStroke(p, {fill: "none", stroke: "#000", path: pathString});` `1809 return p;` `1810 },` `1811 gradients = {},` `1812 rgGrad = /^url\(#(.*)\)$/,` `1813 removeGradientFill = function (node, paper) {` `1814 var oid = node.getAttribute(fillString);` `1815 oid = oid && oid.match(rgGrad);` `1816 if (oid && !--gradients[oid[1]]) {` `1817 delete gradients[oid[1]];` `1818 paper.defs.removeChild(g.doc.getElementById(oid[1]));` `1819 }` `1820 },` `1821 addGradientFill = function (element, gradient) {` `1822 var type = "linear",` `1823 id = element.id + gradient,` `1824 fx = .5, fy = .5,` `1825 o = element.node,` `1826 SVG = element.paper,` `1827 s = o.style,` `1828 el = g.doc.getElementById(id);` `1829 if (!el) {` `1830 gradient = Str(gradient).replace(radial_gradient, function (all, _fx, _fy) {` `1831 type = "radial";` `1832 if (_fx && _fy) {` `1833 fx = toFloat(_fx);` `1834 fy = toFloat(_fy);` `1835 var dir = ((fy > .5) * 2 - 1);` `1836 pow(fx - .5, 2) + pow(fy - .5, 2) > .25 &&` `1837 (fy = math.sqrt(.25 - pow(fx - .5, 2)) * dir + .5) &&` `1838 fy != .5 &&` `1839 (fy = fy.toFixed(5) - 1e-5 * dir);` `1840 }` `1841 return E;` `1842 });` `1843 gradient = gradient.split(/\s*\-\s*/);` `1844 if (type == "linear") {` `1845 var angle = gradient.shift();` `1846 angle = -toFloat(angle);` `1847 if (isNaN(angle)) {` `1848 return null;` `1849 }` `1850 var vector = [0, 0, math.cos(R.rad(angle)), math.sin(R.rad(angle))],` `1851 max = 1 / (mmax(abs(vector[2]), abs(vector[3])) || 1);` `1852 vector[2] *= max;` `1853 vector[3] *= max;` `1854 if (vector[2] < 0) {` `1855 vector[0] = -vector[2];` `1856 vector[2] = 0;` `1857 }` `1858 if (vector[3] < 0) {` `1859 vector[1] = -vector[3];` `1860 vector[3] = 0;` `1861 }` `1862 }` `1863 var dots = parseDots(gradient);` `1864 if (!dots) {` `1865 return null;` `1866 }` `1867 if (element.gradient) {` `1868 SVG.defs.removeChild(element.gradient);` `1869 delete element.gradient;` `1870 }` `1871` `1872 el = $(type + "Gradient", {id: id});` `1873 element.gradient = el;` `1874 $(el, type == "radial" ? {` `1875 fx: fx,` `1876 fy: fy` `1877 } : {` `1878 x1: vector[0],` `1879 y1: vector[1],` `1880 x2: vector[2],` `1881 y2: vector[3],` `1882 gradientTransform: element.matrix.invert()` `1883 });` `1884 SVG.defs.appendChild(el);` `1885 for (var i = 0, ii = dots.length; i < ii; i++) {` `1886 el.appendChild($("stop", {` `1887 offset: dots[i].offset ? dots[i].offset : i ? "100%" : "0%",` `1888 "stop-color": dots[i].color || "#fff"` `1889 }));` `1890 }` `1891 }` `1892 $(o, {` `1893 fill: "url(#" + id + ")",` `1894 opacity: 1,` `1895 "fill-opacity": 1` `1896 });` `1897 s.fill = E;` `1898 s.opacity = 1;` `1899 s.fillOpacity = 1;` `1900 return 1;` `1901 },` `1902 updatePosition = function (o) {` `1903 var bbox = o.getBBox(1);` `1904 $(o.pattern, {patternTransform: o.matrix.invert() + " translate(" + bbox.x + "," + bbox.y + ")"});` `1905 },` `1906 addArrow = function (o, value, isEnd) {` `1907 if (o.type == "path") {` `1908 var values = Str(value).toLowerCase().split("-"),` `1909 p = o.paper,` `1910 se = isEnd ? "end" : "start",` `1911 node = o.node,` `1912 attrs = o.attrs,` `1913 stroke = attrs["stroke-width"],` `1914 i = values.length,` `1915 type = "classic",` `1916 from,` `1917 to,` `1918 dx,` `1919 refX,` `1920 attr,` `1921 w = 3,` `1922 h = 3,` `1923 t = 5;` `1924 while (i--) {` `1925 switch (values[i]) {` `1926 case "block":` `1927 case "classic":` `1928 case "oval":` `1929 case "diamond":` `1930 case "open":` `1931 case "none":` `1932 type = values[i];` `1933 break;` `1934 case "wide": h = 5; break;` `1935 case "narrow": h = 2; break;` `1936 case "long": w = 5; break;` `1937 case "short": w = 2; break;` `1938 }` `1939 }` `1940 if (type == "open") {` `1941 w += 2;` `1942 h += 2;` `1943 t += 2;` `1944 dx = 1;` `1945 refX = isEnd ? 4 : 1;` `1946 attr = {` `1947 fill: "none",` `1948 stroke: attrs.stroke` `1949 };` `1950 } else {` `1951 refX = dx = w / 2;` `1952 attr = {` `1953 fill: attrs.stroke,` `1954 stroke: "none"` `1955 };` `1956 }` `1957 if (o._.arrows) {` `1958 if (isEnd) {` `1959 o._.arrows.endPath && markerCounter[o._.arrows.endPath]--;` `1960 o._.arrows.endMarker && markerCounter[o._.arrows.endMarker]--;` `1961 } else {` `1962 o._.arrows.startPath && markerCounter[o._.arrows.startPath]--;` `1963 o._.arrows.startMarker && markerCounter[o._.arrows.startMarker]--;` `1964 }` `1965 } else {` `1966 o._.arrows = {};` `1967 }` `1968 if (type != "none") {` `1969 var pathId = "raphael-marker-" + type,` `1970 markerId = "raphael-marker-" + se + type + w + h;` `1971 if (!g.doc.getElementById(pathId)) {` `1972 p.defs.appendChild($($("path"), {` `1973 "stroke-linecap": "round",` `1974 d: markers[type],` `1975 id: pathId` `1976 }));` `1977 markerCounter[pathId] = 1;` `1978 } else {` `1979 markerCounter[pathId]++;` `1980 }` `1981 var marker = g.doc.getElementById(markerId),` `1982 use;` `1983 if (!marker) {` `1984 marker = $($("marker"), {` `1985 id: markerId,` `1986 markerHeight: h,` `1987 markerWidth: w,` `1988 orient: "auto",` `1989 refX: refX,` `1990 refY: h / 2` `1991 });` `1992 use = $($("use"), {` `1993 "xlink:href": "#" + pathId,` `1994 transform: (isEnd ? " rotate(180 " + w / 2 + " " + h / 2 + ") " : S) + "scale(" + w / t + "," + h / t + ")",` `1995 "stroke-width": 1 / ((w / t + h / t) / 2)` `1996 });` `1997 marker.appendChild(use);` `1998 p.defs.appendChild(marker);` `1999 markerCounter[markerId] = 1;` `2000 } else {` `2001 markerCounter[markerId]++;` `2002 use = marker.getElementsByTagName("use")[0];` `2003 }` `2004 $(use, attr);` `2005 var delta = dx * (type != "diamond" && type != "oval");` `2006 if (isEnd) {` `2007 from = o._.arrows.startdx * stroke || 0;` `2008 to = R.getTotalLength(attrs.path) - delta * stroke;` `2009 } else {` `2010 from = delta * stroke;` `2011 to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0);` `2012 }` `2013 attr = {};` `2014 attr["marker-" + se] = "url(#" + markerId + ")";` `2015 if (to || from) {` `2016 attr.d = Raphael.getSubpath(attrs.path, from, to);` `2017 }` `2018 $(node, attr);` `2019 o._.arrows[se + "Path"] = pathId;` `2020 o._.arrows[se + "Marker"] = markerId;` `2021 o._.arrows[se + "dx"] = delta;` `2022 o._.arrows[se + "Type"] = type;` `2023 o._.arrows[se + "String"] = value;` `2024 } else {` `2025 if (isEnd) {` `2026 from = o._.arrows.startdx * stroke || 0;` `2027 to = R.getTotalLength(attrs.path) - from;` `2028 } else {` `2029 from = 0;` `2030 to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0);` `2031 }` `2032 o._.arrows[se + "Path"] && $(node, {d: Raphael.getSubpath(attrs.path, from, to)});` `2033 delete o._.arrows[se + "Path"];` `2034 delete o._.arrows[se + "Marker"];` `2035 delete o._.arrows[se + "dx"];` `2036 delete o._.arrows[se + "Type"];` `2037 delete o._.arrows[se + "String"];` `2038 }` `2039 for (attr in markerCounter) if (markerCounter[has](attr) && !markerCounter[attr]) {` `2040 var item = g.doc.getElementById(attr);` `2041 item && item.parentNode.removeChild(item);` `2042 }` `2043 }` `2044 },` `2045 setFillAndStroke = function (o, params) {` `2046 var dasharray = {` `2047 "": [0],` `2048 "none": [0],` `2049 "-": [3, 1],` `2050 ".": [1, 1],` `2051 "-.": [3, 1, 1, 1],` `2052 "-..": [3, 1, 1, 1, 1, 1],` `2053 ". ": [1, 3],` `2054 "- ": [4, 3],` `2055 "--": [8, 3],` `2056 "- .": [4, 3, 1, 3],` `2057 "--.": [8, 3, 1, 3],` `2058 "--..": [8, 3, 1, 3, 1, 3]` `2059 },` `2060 node = o.node,` `2061 attrs = o.attrs,` `2062 addDashes = function (o, value) {` `2063 value = dasharray[lowerCase.call(value)];` `2064 if (value) {` `2065 var width = o.attrs["stroke-width"] || "1",` `2066 butt = {round: width, square: width, butt: 0}[o.attrs["stroke-linecap"] || params["stroke-linecap"]] || 0,` `2067 dashes = [],` `2068 i = value.length;` `2069 while (i--) {` `2070 dashes[i] = value[i] * width + ((i % 2) ? 1 : -1) * butt;` `2071 }` `2072 $(node, {"stroke-dasharray": dashes.join(",")});` `2073 }` `2074 };` `2075 for (var att in params) {` `2076 if (params[has](att)) {` `2077 if (!availableAttrs[has](att)) {` `2078 continue;` `2079 }` `2080 var value = params[att];` `2081 attrs[att] = value;` `2082 switch (att) {` `2083 case "blur":` `2084 o.blur(value);` `2085 break;` `2086 case "href":` `2087 case "title":` `2088 case "target":` `2089 var pn = node.parentNode;` `2090 if (lowerCase.call(pn.tagName) != "a") {` `2091 var hl = $("a");` `2092 pn.insertBefore(hl, node);` `2093 hl.appendChild(node);` `2094 pn = hl;` `2095 }` `2096 if (att == "target" && value == "blank") {` `2097 pn.setAttributeNS(xlink, "show", "new");` `2098 } else {` `2099 pn.setAttributeNS(xlink, att, value);` `2100 }` `2101 break;` `2102 case "cursor":` `2103 node.style.cursor = value;` `2104 break;` `2105 case "transform":` `2106 o.transform(value);` `2107 break;` `2108 case "arrow-start":` `2109 addArrow(o, value);` `2110 break;` `2111 case "arrow-end":` `2112 addArrow(o, value, 1);` `2113 break;` `2114 case "clip-rect":` `2115 var rect = Str(value).split(separator);` `2116 if (rect.length == 4) {` `2117 o.clip && o.clip.parentNode.parentNode.removeChild(o.clip.parentNode);` `2118 var el = $("clipPath"),` `2119 rc = $("rect");` `2120 el.id = createUUID();` `2121 $(rc, {` `2122 x: rect[0],` `2123 y: rect[1],` `2124 width: rect[2],` `2125 height: rect[3]` `2126 });` `2127 el.appendChild(rc);` `2128 o.paper.defs.appendChild(el);` `2129 $(node, {"clip-path": "url(#" + el.id + ")"});` `2130 o.clip = rc;` `2131 }` `2132 if (!value) {` `2133 var clip = g.doc.getElementById(node.getAttribute("clip-path").replace(/(^url\(#|\)$)/g, E));` `2134 clip && clip.parentNode.removeChild(clip);` `2135 $(node, {"clip-path": E});` `2136 delete o.clip;` `2137 }` `2138 break;` `2139 case "path":` `2140 if (o.type == "path") {` `2141 $(node, {d: value ? attrs.path = pathToAbsolute(value) : "M0,0"});` `2142 o._.dirty = 1;` `2143 if (o._.arrows) {` `2144 "startString" in o._.arrows && addArrow(o, o._.arrows.startString);` `2145 "endString" in o._.arrows && addArrow(o, o._.arrows.endString, 1);` `2146 }` `2147 }` `2148 break;` `2149 case "width":` `2150 node[setAttribute](att, value);` `2151 o._.dirty = 1;` `2152 if (attrs.fx) {` `2153 att = "x";` `2154 value = attrs.x;` `2155 } else {` `2156 break;` `2157 }` `2158 case "x":` `2159 if (attrs.fx) {` `2160 value = -attrs.x - (attrs.width || 0);` `2161 }` `2162 case "rx":` `2163 if (att == "rx" && o.type == "rect") {` `2164 break;` `2165 }` `2166 case "cx":` `2167 node[setAttribute](att, value);` `2168 o.pattern && updatePosition(o);` `2169 o._.dirty = 1;` `2170 break;` `2171 case "height":` `2172 node[setAttribute](att, value);` `2173 o._.dirty = 1;` `2174 if (attrs.fy) {` `2175 att = "y";` `2176 value = attrs.y;` `2177 } else {` `2178 break;` `2179 }` `2180 case "y":` `2181 if (attrs.fy) {` `2182 value = -attrs.y - (attrs.height || 0);` `2183 }` `2184 case "ry":` `2185 if (att == "ry" && o.type == "rect") {` `2186 break;` `2187 }` `2188 case "cy":` `2189 node[setAttribute](att, value);` `2190 o.pattern && updatePosition(o);` `2191 o._.dirty = 1;` `2192 break;` `2193 case "r":` `2194 if (o.type == "rect") {` `2195 $(node, {rx: value, ry: value});` `2196 } else {` `2197 node[setAttribute](att, value);` `2198 }` `2199 o._.dirty = 1;` `2200 break;` `2201 case "src":` `2202 if (o.type == "image") {` `2203 node.setAttributeNS(xlink, "href", value);` `2204 }` `2205 break;` `2206 case "stroke-width":` `2207 if (o._.sx != 1 || o._.sy != 1) {` `2208 value /= mmax(abs(o._.sx), abs(o._.sy)) || 1;` `2209 }` `2210 if (o.paper._vbSize) {` `2211 value *= o.paper._vbSize;` `2212 }` `2213 node[setAttribute](att, value);` `2214 if (attrs["stroke-dasharray"]) {` `2215 addDashes(o, attrs["stroke-dasharray"]);` `2216 }` `2217 if (o._.arrows) {` `2218 "startString" in o._.arrows && addArrow(o, o._.arrows.startString);` `2219 "endString" in o._.arrows && addArrow(o, o._.arrows.endString, 1);` `2220 }` `2221 break;` `2222 case "stroke-dasharray":` `2223 addDashes(o, value);` `2224 break;` `2225 case fillString:` `2226 var isURL = Str(value).match(ISURL);` `2227 if (isURL) {` `2228 el = $("pattern");` `2229 var ig = $("image");` `2230 el.id = createUUID();` `2231 $(el, {x: 0, y: 0, patternUnits: "userSpaceOnUse", height: 1, width: 1});` `2232 $(ig, {x: 0, y: 0, "xlink:href": isURL[1]});` `2233 el.appendChild(ig);` `2234` `2235 (function (el) {` `2236 preload(isURL[1], function () {` `2237 var w = this.offsetWidth,` `2238 h = this.offsetHeight;` `2239 $(el, {width: w, height: h});` `2240 $(ig, {width: w, height: h});` `2241 o.paper.safari();` `2242 });` `2243 })(el);` `2244 o.paper.defs.appendChild(el);` `2245 node.style.fill = "url(#" + el.id + ")";` `2246 $(node, {fill: "url(#" + el.id + ")"});` `2247 o.pattern = el;` `2248 o.pattern && updatePosition(o);` `2249 break;` `2250 }` `2251 var clr = R.getRGB(value);` `2252 if (!clr.error) {` `2253 delete params.gradient;` `2254 delete attrs.gradient;` `2255 !R.is(attrs.opacity, "undefined") &&` `2256 R.is(params.opacity, "undefined") &&` `2257 $(node, {opacity: attrs.opacity});` `2258 !R.is(attrs["fill-opacity"], "undefined") &&` `2259 R.is(params["fill-opacity"], "undefined") &&` `2260 $(node, {"fill-opacity": attrs["fill-opacity"]});` `2261 } else if ((o.type == "circle" || o.type == "ellipse" || Str(value).charAt() != "r") && addGradientFill(o, value)) {` `2262 if ("opacity" in attrs || "fill-opacity" in attrs) {` `2263 var gradient = g.doc.getElementById(node.getAttribute(fillString).replace(/^url\(#|\)$/g, E));` `2264 if (gradient) {` `2265 var stops = gradient.getElementsByTagName("stop");` `2266 $(stops[stops.length - 1], {"stop-opacity": ("opacity" in attrs ? attrs.opacity : 1) * ("fill-opacity" in attrs ? attrs["fill-opacity"] : 1)});` `2267 }` `2268 }` `2269 attrs.gradient = value;` `2270 attrs.fill = "none";` `2271 break;` `2272 }` `2273 clr[has]("opacity") && $(node, {"fill-opacity": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity});` `2274 case "stroke":` `2275 clr = R.getRGB(value);` `2276 node[setAttribute](att, clr.hex);` `2277 att == "stroke" && clr[has]("opacity") && $(node, {"stroke-opacity": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity});` `2278 if (att == "stroke" && o._.arrows) {` `2279 "startString" in o._.arrows && addArrow(o, o._.arrows.startString);` `2280 "endString" in o._.arrows && addArrow(o, o._.arrows.endString, 1);` `2281 }` `2282 break;` `2283 case "gradient":` `2284 (o.type == "circle" || o.type == "ellipse" || Str(value).charAt() != "r") && addGradientFill(o, value);` `2285 break;` `2286 case "opacity":` `2287 if (attrs.gradient && !attrs[has]("stroke-opacity")) {` `2288 $(node, {"stroke-opacity": value > 1 ? value / 100 : value});` `2289 }` `2290 // fall` `2291 case "fill-opacity":` `2292 if (attrs.gradient) {` `2293 gradient = g.doc.getElementById(node.getAttribute(fillString).replace(/^url\(#|\)$/g, E));` `2294 if (gradient) {` `2295 stops = gradient.getElementsByTagName("stop");` `2296 $(stops[stops.length - 1], {"stop-opacity": value});` `2297 }` `2298 break;` `2299 }` `2300 default:` `2301 att == "font-size" && (value = toInt(value, 10) + "px");` `2302 var cssrule = att.replace(/(\-.)/g, function (w) {` `2303 return upperCase.call(w.substring(1));` `2304 });` `2305 node.style[cssrule] = value;` `2306 o._.dirty = 1;` `2307 node[setAttribute](att, value);` `2308 break;` `2309 }` `2310 }` `2311 }` `2312` `2313 tuneText(o, params);` `2314 },` `2315 leading = 1.2,` `2316 tuneText = function (el, params) {` `2317 if (el.type != "text" || !(params[has]("text") || params[has]("font") || params[has]("font-size") || params[has]("x") || params[has]("y"))) {` `2318 return;` `2319 }` `2320 var a = el.attrs,` `2321 node = el.node,` `2322 fontSize = node.firstChild ? toInt(g.doc.defaultView.getComputedStyle(node.firstChild, E).getPropertyValue("font-size"), 10) : 10;` `2323` `2324 if (params[has]("text")) {` `2325 a.text = params.text;` `2326 while (node.firstChild) {` `2327 node.removeChild(node.firstChild);` `2328 }` `2329 var texts = Str(params.text).split("\n"),` `2330 tspans = [],` `2331 tspan;` `2332 for (var i = 0, ii = texts.length; i < ii; i++) if (texts[i]) {` `2333 tspan = $("tspan");` `2334 i && $(tspan, {dy: fontSize * leading, x: a.x});` `2335 tspan.appendChild(g.doc.createTextNode(texts[i]));` `2336 node.appendChild(tspan);` `2337 tspans[i] = tspan;` `2338 }` `2339 } else {` `2340 tspans = node.getElementsByTagName("tspan");` `2341 for (i = 0, ii = tspans.length; i < ii; i++) {` `2342 i && $(tspans[i], {dy: fontSize * leading, x: a.x});` `2343 }` `2344 }` `2345 $(node, {y: a.y});` `2346 el._.dirty = 1;` `2347 var bb = el._getBBox(),` `2348 dif = a.y - (bb.y + bb.height / 2);` `2349 dif && R.is(dif, "finite") && $(tspans[0], {dy: a.y + dif});` `2350 },` `2351 Element = function (node, svg) {` `2352 var X = 0,` `2353 Y = 0;` `2354 /*\` `2355 * Element.node` `2356 [ property (object) ]` `2357 **` `2358 * Gives you a reference to the DOM object, so you can assign event handlers or just mess around.` `2359 > Usage` `2360 | // draw a circle at coordinate 10,10 with radius of 10` `2361 | var c = paper.circle(10, 10, 10);` `2362 | c.node.onclick = function () {` `2363 | c.attr("fill", "red");` `2364 | };` `2365 \*/` `2366 this[0] = this.node = node;` `2367 /*\` `2368 * Element.raphael` `2369 [ property (object) ]` `2370 **` `2371 * Internal reference to @Raphael object. In case it is not available.` `2372 > Usage` `2373 | Raphael.el.red = function () {` `2374 | var hsb = this.paper.raphael.rgb2hsb(this.attr("fill"));` `2375 | hsb.h = 1;` `2376 | this.attr({fill: this.paper.raphael.hsb2rgb(hsb).hex});` `2377 | }` `2378 \*/` `2379 node.raphael = true;` `2380 /*\` `2381 * Element.id` `2382 [ property (number) ]` `2383 **` `2384 * Unique id of the element. Especially usesful when you want to listen to events of the element,` `2385 * because all events are fired in format `<module>.<action>.<id>`. Also useful for @Paper.getById method.` `2386 \*/` `2387 this.id = R._oid++;` `2388 node.raphaelid = this.id;` `2389 this.matrix = new Matrix;` `2390 this.realPath = null;` `2391 /*\` `2392 * Element.paper` `2393 [ property (object) ]` `2394 **` `2395 * Internal reference to “paper” where object drawn. Mainly for use in plugins and element extensions.` `2396 > Usage` `2397 | Raphael.el.cross = function () {` `2398 | this.attr({fill: "red"});` `2399 | this.paper.path("M10,10L50,50M50,10L10,50")` `2400 | .attr({stroke: "red"});` `2401 | }` `2402 \*/` `2403 this.paper = svg;` `2404 this.attrs = this.attrs || {};` `2405 this._ = {` `2406 transform: [],` `2407 sx: 1,` `2408 sy: 1,` `2409 deg: 0,` `2410 dx: 0,` `2411 dy: 0,` `2412 dirty: 1` `2413 };` `2414 !svg.bottom && (svg.bottom = this);` `2415 /*\` `2416 * Element.prev` `2417 [ property (object) ]` `2418 **` `2419 * Reference to the previous element in the hierarchy.` `2420 \*/` `2421 this.prev = svg.top;` `2422 svg.top && (svg.top.next = this);` `2423 svg.top = this;` `2424 /*\` `2425 * Element.next` `2426 [ property (object) ]` `2427 **` `2428 * Reference to the next element in the hierarchy.` `2429 \*/` `2430 this.next = null;` `2431 },` `2432 elproto = Element.prototype;` `2433 /*\` `2434 * Element.rotate` `2435 [ method ]` `2436 **` `2437 * Adds rotation by given angle around given point to the list of` `2438 * transformations of the element.` `2439 > Parameters` `2440 - deg (number) angle in degrees` `2441 - cx (number) #optional x coordinate of the centre of rotation` `2442 - cy (number) #optional y coordinate of the centre of rotation` `2443 * If cx & cy aren’t specified centre of the shape is used as a point of rotation.` `2444 = (object) @Element` `2445 \*/` `2446 elproto.rotate = function (deg, cx, cy) {` `2447 if (this.removed) {` `2448 return this;` `2449 }` `2450 deg = Str(deg).split(separator);` `2451 if (deg.length - 1) {` `2452 cx = toFloat(deg[1]);` `2453 cy = toFloat(deg[2]);` `2454 }` `2455 deg = toFloat(deg[0]);` `2456 (cy == null) && (cx = cy);` `2457 if (cx == null || cy == null) {` `2458 var bbox = this.getBBox(1);` `2459 cx = bbox.x + bbox.width / 2;` `2460 cy = bbox.y + bbox.height / 2;` `2461 }` `2462 this.transform(this._.transform.concat([["r", deg, cx, cy]]));` `2463 return this;` `2464 };` `2465 /*\` `2466 * Element.scale` `2467 [ method ]` `2468 **` `2469 * Adds scale by given amount relative to given point to the list of` `2470 * transformations of the element.` `2471 > Parameters` `2472 - sx (number) horisontal scale amount` `2473 - sy (number) vertical scale amount` `2474 - cx (number) #optional x coordinate of the centre of scale` `2475 - cy (number) #optional y coordinate of the centre of scale` `2476 * If cx & cy aren’t specified centre of the shape is used instead.` `2477 = (object) @Element` `2478 \*/` `2479 elproto.scale = function (sx, sy, cx, cy) {` `2480 if (this.removed) {` `2481 return this;` `2482 }` `2483 sx = Str(sx).split(separator);` `2484 if (sx.length - 1) {` `2485 sy = toFloat(sx[1]);` `2486 cx = toFloat(sx[2]);` `2487 cy = toFloat(sx[3]);` `2488 }` `2489 sx = toFloat(sx[0]);` `2490 (sy == null) && (sy = sx);` `2491 (cy == null) && (cx = cy);` `2492 if (cx == null || cy == null) {` `2493 var bbox = this.getBBox(1);` `2494 }` `2495 cx = cx == null ? bbox.x + bbox.width / 2 : cx;` `2496 cy = cy == null ? bbox.y + bbox.height / 2 : cy;` `2497 this.transform(this._.transform.concat([["s", sx, sy, cx, cy]]));` `2498 return this;` `2499 };` `2500 /*\` `2501 * Element.translate` `2502 [ method ]` `2503 **` `2504 * Adds translation by given amount to the list of transformations of the element.` `2505 > Parameters` `2506 - dx (number) horisontal shift` `2507 - dy (number) vertical shift` `2508 = (object) @Element` `2509 \*/` `2510 elproto.translate = function (dx, dy) {` `2511 if (this.removed) {` `2512 return this;` `2513 }` `2514 dx = Str(dx).split(separator);` `2515 if (dx.length - 1) {` `2516 dy = toFloat(dx[1]);` `2517 }` `2518 dx = toFloat(dx[0]) || 0;` `2519 dy = +dy || 0;` `2520 this.transform(this._.transform.concat([["t", dx, dy]]));` `2521 return this;` `2522 };` `2523 /*\` `2524 * Element.transform` `2525 [ method ]` `2526 **` `2527 * Adds transformation to the element which is separate to other attributes,` `2528 * i.e. translation doesn’t change `x` or `y` of the rectange. The format` `2529 * of transformation string is similar to the path string syntax:` `2530 | "t100,100r30,100,100s2,2,100,100r45s1.5"` `2531 * Each letter is a command. There are four commands: `t` is for translate, `r` is for rotate, `s` is for` `2532 * scale and `m` is for matrix.` `2533 *` `2534 * So, the example line above could be read like “translate by 100, 100; rotate 30° around 100, 100; scale twice around 100, 100;` `2535 * rotate 45° around centre; scale 1.5 times relative to centre”. As you can see rotate and scale commands have origin` `2536 * coordinates as optional parameters, the default is the centre point of the element.` `2537 * Matrix accepts six parameters.` `2538 > Usage` `2539 | var el = paper.rect(10, 20, 300, 200);` `2540 | // translate 100, 100, rotate 45°, translate -100, 0` `2541 | el.transform("t100,100r45t-100,0");` `2542 | // if you want you can append or prepend transformations` `2543 | el.transform("...t50,50");` `2544 | el.transform("s2...");` `2545 | // or even wrap` `2546 | el.transform("t50,50...t-50-50");` `2547 | // to reset transformation call method with empty string` `2548 | el.transform("");` `2549 | // to get current value call it without parameters` `2550 | console.log(el.transform());` `2551 > Parameters` `2552 - tstr (string) #optional transformation string` `2553 * If tstr isn’t specified` `2554 = (string) current transformation string` `2555 * else` `2556 = (object) @Element` `2557 \*/` `2558 elproto.transform = function (tstr) {` `2559 var _ = this._;` `2560 if (!tstr) {` `2561 return _.transform;` `2562 }` `2563 extractTransform(this, tstr);` `2564` `2565 this.clip && $(this.clip, {transform: this.matrix.invert()});` `2566 // this.gradient && $(this.gradient, {gradientTransform: this.matrix.invert()});` `2567 this.pattern && updatePosition(this);` `2568 this.node && $(this.node, {transform: this.matrix});` `2569` `2570 if (_.sx != 1 || _.sy != 1) {` `2571 var sw = this.attrs[has]("stroke-width") ? this.attrs["stroke-width"] : 1;` `2572 this.attr({"stroke-width": sw});` `2573 }` `2574` `2575 return this;` `2576 };` `2577 /*\` `2578 * Element.hide` `2579 [ method ]` `2580 **` `2581 * Makes element invisible. See @Element.show.` `2582 = (object) @Element` `2583 \*/` `2584 elproto.hide = function () {` `2585 !this.removed && this.paper.safari(this.node.style.display = "none");` `2586 return this;` `2587 };` `2588 /*\` `2589 * Element.show` `2590 [ method ]` `2591 **` `2592 * Makes element visible. See @Element.hide.` `2593 = (object) @Element` `2594 \*/` `2595 elproto.show = function () {` `2596 !this.removed && this.paper.safari(this.node.style.display = "");` `2597 return this;` `2598 };` `2599 /*\` `2600 * Element.remove` `2601 [ method ]` `2602 **` `2603 * Removes element form the paper.` `2604 \*/` `2605 elproto.remove = function () {` `2606 if (this.removed) {` `2607 return;` `2608 }` `2609 eve.unbind("*.*." + this.id);` `2610 tear(this, this.paper);` `2611 this.node.parentNode.removeChild(this.node);` `2612 for (var i in this) {` `2613 delete this[i];` `2614 }` `2615 this.removed = true;` `2616 };` `2617 elproto._getBBox = function () {` `2618 if (this.node.style.display == "none") {` `2619 this.show();` `2620 var hide = true;` `2621 }` `2622 var bbox = {};` `2623 try {` `2624 bbox = this.node.getBBox();` `2625 } catch(e) {` `2626 // Firefox 3.0.x plays badly here` `2627 } finally {` `2628 bbox = bbox || {};` `2629 }` `2630 hide && this.hide();` `2631 return bbox;` `2632 };` `2633 /*\` `2634 * Element.attr` `2635 [ method ]` `2636 **` `2637 * Sets the attributes of the element.` `2638 > Parameters` `2639 - attrName (string) attribute’s name` `2640 - value (string) value` `2641 * or` `2642 - params (object) object of name/value pairs` `2643 * or` `2644 - attrName (string) attribute’s name` `2645 * or` `2646 - attrNames (array) in this case method returns array of current values for given attribute names` `2647 = (object) @Element if attrsName & value or params are passed in.` `2648 = (...) value of the attribute if only attrsName is passed in.` `2649 = (array) array of values of the attribute if attrsNames is passed in.` `2650 = (object) object of attributes if nothing is passed in.` `2651 > Possible parameters` `2652 # <p>Please refer to the <a href="http://www.w3.org/TR/SVG/" title="The W3C Recommendation for the SVG language describes these properties in detail.">SVG specification</a> for an explanation of these parameters.</p>` `2653 o arrow-end (string) arrowhead on the end of the path. The format for string is `<type>[-<width>[-<length>]]`. Possible types: `classic`, `block`, `open`, `oval`, `diamond`, `none`, width: `wide`, `narrow`, `midium`, length: `long`, `short`, `midium`.` `2654 o clip-rect (string) comma or space separated values: x, y, width and height` `2655 o cursor (string) CSS type of the cursor` `2656 o cx (number)` `2657 o cy (number)` `2658 o fill (string) colour, gradient or image` `2659 o fill-opacity (number)` `2660 o font (string)` `2661 o font-family (string)` `2662 o font-size (number) font size in pixels` `2663 o font-weight (string)` `2664 o height (number)` `2665 o href (string) URL, if specified element behaves as hyperlink` `2666 o opacity (number)` `2667 o path (string) SVG path string format` `2668 o r (number)` `2669 o rx (number)` `2670 o ry (number)` `2671 o src (string) image URL, only works for @Element.image element` `2672 o stroke (string) stroke colour` `2673 o stroke-dasharray (string) [“”, “`-`”, “`.`”, “`-.`”, “`-..`”, “`. `”, “`- `”, “`--`”, “`- .`”, “`--.`”, “`--..`”]` `2674 o stroke-linecap (string) [“`butt`”, “`square`”, “`round`”]` `2675 o stroke-linejoin (string) [“`bevel`”, “`round`”, “`miter`”]` `2676 o stroke-miterlimit (number)` `2677 o stroke-opacity (number)` `2678 o stroke-width (number) stroke width in pixels, default is '1'` `2679 o target (string) used with href` `2680 o text (string) contents of the text element. Use `\n` for multiline text` `2681 o text-anchor (string) [“`start`”, “`middle`”, “`end`”], default is “`middle`”` `2682 o title (string) will create tooltip with a given text` `2683 o transform (string) see @Element.transform` `2684 o width (number)` `2685 o x (number)` `2686 o y (number)` `2687 > Gradients` `2688 * Linear gradient format: “`‹angle›-‹colour›[-‹colour›[:‹offset›]]*-‹colour›`”, example: “`90-#fff-#000`” – 90°` `2689 * gradient from white to black or “`0-#fff-#f00:20-#000`” – 0° gradient from white via red (at 20%) to black.` `2690 *` `2691 * radial gradient: “`r[(‹fx›, ‹fy›)]‹colour›[-‹colour›[:‹offset›]]*-‹colour›`”, example: “`r#fff-#000`” –` `2692 * gradient from white to black or “`r(0.25, 0.75)#fff-#000`” – gradient from white to black with focus point` `2693 * at 0.25, 0.75. Focus point coordinates are in 0..1 range. Radial gradients can only be applied to circles and ellipses.` `2694 > Path String` `2695 # <p>Please refer to <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 documentation regarding path string</a>. Raphaël fully supports it.</p>` `2696 > Colour Parsing` `2697 # <ul>` `2698 # <li>Colour name (“<code>red</code>”, “<code>green</code>”, “<code>cornflowerblue</code>”, etc)</li>` `2699 # <li>#••• — shortened HTML colour: (“<code>#000</code>”, “<code>#fc0</code>”, etc)</li>` `2700 # <li>#•••••• — full length HTML colour: (“<code>#000000</code>”, “<code>#bd2300</code>”)</li>` `2701 # <li>rgb(•••, •••, •••) — red, green and blue channels’ values: (“<code>rgb(200, 100, 0)</code>”)</li>` `2702 # <li>rgb(•••%, •••%, •••%) — same as above, but in %: (“<code>rgb(100%, 175%, 0%)</code>”)</li>` `2703 # <li>rgba(•••, •••, •••, •••) — red, green and blue channels’ values: (“<code>rgba(200, 100, 0, .5)</code>”)</li>` `2704 # <li>rgba(•••%, •••%, •••%, •••%) — same as above, but in %: (“<code>rgba(100%, 175%, 0%, 50%)</code>”)</li>` `2705 # <li>hsb(•••, •••, •••) — hue, saturation and brightness values: (“<code>hsb(0.5, 0.25, 1)</code>”)</li>` `2706 # <li>hsb(•••%, •••%, •••%) — same as above, but in %</li>` `2707 # <li>hsba(•••, •••, •••, •••) — same as above, but with opacity</li>` `2708 # <li>hsl(•••, •••, •••) — almost the same as hsb, see <a href="http://en.wikipedia.org/wiki/HSL_and_HSV" title="HSL and HSV - Wikipedia, the free encyclopedia">Wikipedia page</a></li>` `2709 # <li>hsl(•••%, •••%, •••%) — same as above, but in %</li>` `2710 # <li>hsla(•••, •••, •••) — same as above, but with opacity</li>` `2711 # <li>Optionally for hsb and hsl you could specify hue as a degree: “<code>hsl(240deg, 1, .5)</code>” or, if you want to go fancy, “<code>hsl(240°, 1, .5)</code>”</li>` `2712 # </ul>` `2713 \*/` `2714 elproto.attr = function (name, value) {` `2715 if (this.removed) {` `2716 return this;` `2717 }` `2718 if (name == null) {` `2719 var res = {};` `2720 for (var i in this.attrs) if (this.attrs[has](i)) {` `2721 res[i] = this.attrs[i];` `2722 }` `2723 res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient;` `2724 res.transform = this._.transform;` `2725 return res;` `2726 }` `2727 if (value == null && R.is(name, string)) {` `2728 if (name == fillString && this.attrs.fill == "none" && this.attrs.gradient) {` `2729 return this.attrs.gradient;` `2730 }` `2731 if (name == "transform") {` `2732 return this._.transform;` `2733 }` `2734 if (name in this.attrs) {` `2735 return this.attrs[name];` `2736 } else if (R.is(this.paper.customAttributes[name], "function")) {` `2737 return this.paper.customAttributes[name].def;` `2738 } else {` `2739 return availableAttrs[name];` `2740 }` `2741 }` `2742 if (value == null && R.is(name, array)) {` `2743 var values = {};` `2744 for (var j = 0, jj = name.length; j < jj; j++) {` `2745 values[name[j]] = this.attr(name[j]);` `2746 }` `2747 return values;` `2748 }` `2749 if (value != null) {` `2750 var params = {};` `2751 params[name] = value;` `2752 } else if (name != null && R.is(name, "object")) {` `2753 params = name;` `2754 }` `2755 for (var key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], "function")) {` `2756 var par = this.paper.customAttributes[key].apply(this, [][concat](params[key]));` `2757 this.attrs[key] = params[key];` `2758 for (var subkey in par) if (par[has](subkey)) {` `2759 params[subkey] = par[subkey];` `2760 }` `2761 }` `2762 setFillAndStroke(this, params);` `2763 return this;` `2764 };` `2765 /*\` `2766 * Element.toFront` `2767 [ method ]` `2768 **` `2769 * Moves the element so it is the closest to the viewer’s eyes, on top of other elements.` `2770 = (object) @Element` `2771 \*/` `2772 elproto.toFront = function () {` `2773 if (this.removed) {` `2774 return this;` `2775 }` `2776 this.node.parentNode.appendChild(this.node);` `2777 var svg = this.paper;` `2778 svg.top != this && tofront(this, svg);` `2779 return this;` `2780 };` `2781 /*\` `2782 * Element.toBack` `2783 [ method ]` `2784 **` `2785 * Moves the element so it is the furthest from the viewer’s eyes, behind other elements.` `2786 = (object) @Element` `2787 \*/` `2788 elproto.toBack = function () {` `2789 if (this.removed) {` `2790 return this;` `2791 }` `2792 if (this.node.parentNode.firstChild != this.node) {` `2793 this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild);` `2794 toback(this, this.paper);` `2795 var svg = this.paper;` `2796 }` `2797 return this;` `2798 };` `2799 /*\` `2800 * Element.insertAfter` `2801 [ method ]` `2802 **` `2803 * Inserts current object after the given one.` `2804 = (object) @Element` `2805 \*/` `2806 elproto.insertAfter = function (element) {` `2807 if (this.removed) {` `2808 return this;` `2809 }` `2810 var node = element.node || element[element.length - 1].node;` `2811 if (node.nextSibling) {` `2812 node.parentNode.insertBefore(this.node, node.nextSibling);` `2813 } else {` `2814 node.parentNode.appendChild(this.node);` `2815 }` `2816 insertafter(this, element, this.paper);` `2817 return this;` `2818 };` `2819 /*\` `2820 * Element.insertBefore` `2821 [ method ]` `2822 **` `2823 * Inserts current object before the given one.` `2824 = (object) @Element` `2825 \*/` `2826 elproto.insertBefore = function (element) {` `2827 if (this.removed) {` `2828 return this;` `2829 }` `2830 var node = element.node || element[0].node;` `2831 node.parentNode.insertBefore(this.node, node);` `2832 insertbefore(this, element, this.paper);` `2833 return this;` `2834 };` `2835 elproto.blur = function (size) {` `2836 // Experimental. No Safari support. Use it on your own risk.` `2837 var t = this;` `2838 if (+size !== 0) {` `2839 var fltr = $("filter"),` `2840 blur = $("feGaussianBlur");` `2841 t.attrs.blur = size;` `2842 fltr.id = createUUID();` `2843 $(blur, {stdDeviation: +size || 1.5});` `2844 fltr.appendChild(blur);` `2845 t.paper.defs.appendChild(fltr);` `2846 t._blur = fltr;` `2847 $(t.node, {filter: "url(#" + fltr.id + ")"});` `2848 } else {` `2849 if (t._blur) {` `2850 t._blur.parentNode.removeChild(t._blur);` `2851 delete t._blur;` `2852 delete t.attrs.blur;` `2853 }` `2854 t.node.removeAttribute("filter");` `2855 }` `2856 };` `2857 var theCircle = function (svg, x, y, r) {` `2858 var el = $("circle");` `2859 svg.canvas && svg.canvas.appendChild(el);` `2860 var res = new Element(el, svg);` `2861 res.attrs = {cx: x, cy: y, r: r, fill: "none", stroke: "#000"};` `2862 res.type = "circle";` `2863 $(el, res.attrs);` `2864 return res;` `2865 },` `2866 theRect = function (svg, x, y, w, h, r) {` `2867 var el = $("rect");` `2868 svg.canvas && svg.canvas.appendChild(el);` `2869 var res = new Element(el, svg);` `2870 res.attrs = {x: x, y: y, width: w, height: h, r: r || 0, rx: r || 0, ry: r || 0, fill: "none", stroke: "#000"};` `2871 res.type = "rect";` `2872 $(el, res.attrs);` `2873 return res;` `2874 },` `2875 theEllipse = function (svg, x, y, rx, ry) {` `2876 var el = $("ellipse");` `2877 svg.canvas && svg.canvas.appendChild(el);` `2878 var res = new Element(el, svg);` `2879 res.attrs = {cx: x, cy: y, rx: rx, ry: ry, fill: "none", stroke: "#000"};` `2880 res.type = "ellipse";` `2881 $(el, res.attrs);` `2882 return res;` `2883 },` `2884 theImage = function (svg, src, x, y, w, h) {` `2885 var el = $("image");` `2886 $(el, {x: x, y: y, width: w, height: h, preserveAspectRatio: "none"});` `2887 el.setAttributeNS(xlink, "href", src);` `2888 svg.canvas && svg.canvas.appendChild(el);` `2889 var res = new Element(el, svg);` `2890 res.attrs = {x: x, y: y, width: w, height: h, src: src};` `2891 res.type = "image";` `2892 return res;` `2893 },` `2894 theText = function (svg, x, y, text) {` `2895 var el = $("text");` `2896 $(el, {x: x, y: y, "text-anchor": "middle"});` `2897 svg.canvas && svg.canvas.appendChild(el);` `2898 var res = new Element(el, svg);` `2899 res.attrs = {x: x, y: y, "text-anchor": "middle", text: text, font: availableAttrs.font, stroke: "none", fill: "#000"};` `2900 res.type = "text";` `2901 setFillAndStroke(res, res.attrs);` `2902 return res;` `2903 },` `2904 setSize = function (width, height) {` `2905 this.width = width || this.width;` `2906 this.height = height || this.height;` `2907 this.canvas[setAttribute]("width", this.width);` `2908 this.canvas[setAttribute]("height", this.height);` `2909 if (this._viewBox) {` `2910 this.setViewBox.apply(this, this._viewBox);` `2911 }` `2912 return this;` `2913 },` `2914 create = function () {` `2915 var con = getContainer[apply](0, arguments),` `2916 container = con && con.container,` `2917 x = con.x,` `2918 y = con.y,` `2919 width = con.width,` `2920 height = con.height;` `2921 if (!container) {` `2922 throw new Error("SVG container not found.");` `2923 }` `2924 var cnvs = $("svg"),` `2925 css = "overflow:hidden;",` `2926 isFloating;` `2927 x = x || 0;` `2928 y = y || 0;` `2929 width = width || 512;` `2930 height = height || 342;` `2931 $(cnvs, {` `2932 height: height,` `2933 version: 1.1,` `2934 width: width,` `2935 xmlns: "http://www.w3.org/2000/svg"` `2936 });` `2937 if (container == 1) {` `2938 cnvs.style.cssText = css + "position:absolute;left:" + x + "px;top:" + y + "px";` `2939 g.doc.body.appendChild(cnvs);` `2940 isFloating = 1;` `2941 } else {` `2942 cnvs.style.cssText = css + "position:relative";` `2943 if (container.firstChild) {` `2944 container.insertBefore(cnvs, container.firstChild);` `2945 } else {` `2946 container.appendChild(cnvs);` `2947 }` `2948 }` `2949 container = new Paper;` `2950 container.width = width;` `2951 container.height = height;` `2952 container.canvas = cnvs;` `2953 plugins.call(container, container, R.fn);` `2954 container.clear();` `2955 container._left = container._top = 0;` `2956 isFloating && (container.renderfix = fun);` `2957 container.renderfix();` `2958 return container;` `2959 },` `2960 setViewBox = function (x, y, w, h, fit) {` `2961 eve("setViewBox", this, this._viewBox, [x, y, w, h, fit]);` `2962 var size = mmax(w / this.width, h / this.height),` `2963 top = this.top,` `2964 aspectRatio = fit ? "meet" : "xMinYMin",` `2965 vb,` `2966 sw;` `2967 if (x == null) {` `2968 if (this._vbSize) {` `2969 size = 1;` `2970 }` `2971 delete this._vbSize;` `2972 vb = "0 0 " + this.width + S + this.height;` `2973 } else {` `2974 this._vbSize = size;` `2975 vb = x + S + y + S + w + S + h;` `2976 }` `2977 $(this.canvas, {` `2978 viewBox: vb,` `2979 preserveAspectRatio: aspectRatio` `2980 });` `2981 while (size && top) {` `2982 sw = "stroke-width" in top.attrs ? top.attrs["stroke-width"] : 1;` `2983 top.attr({"stroke-width": sw});` `2984 top._.dirty = 1;` `2985 top._.dirtyT = 1;` `2986 top = top.prev;` `2987 }` `2988 this._viewBox = [x, y, w, h, !!fit];` `2989 return this;` `2990 };` `2991 /*\` `2992 * Paper.renderfix` `2993 [ method ]` `2994 **` `2995 * Fixes the issue of Firefox and IE9 regarding subpixel rendering. If paper is dependant` `2996 * on other elements after reflow it could shift half pixel which cause for lines to lost their crispness.` `2997 * This method fixes the issue.` `2998 **` `2999 Special thanks to Mariusz Nowak (http://www.medikoo.com/) for this method.` `3000 \*/` `3001 paperproto.renderfix = function () {` `3002 var cnvs = this.canvas,` `3003 s = cnvs.style,` `3004 pos = cnvs.getScreenCTM(),` `3005 left = -pos.e % 1,` `3006 top = -pos.f % 1;` `3007 if (left || top) {` `3008 if (left) {` `3009 this._left = (this._left + left) % 1;` `3010 s.left = this._left + "px";` `3011 }` `3012 if (top) {` `3013 this._top = (this._top + top) % 1;` `3014 s.top = this._top + "px";` `3015 }` `3016 }` `3017 };` `3018 /*\` `3019 * Paper.clear` `3020 [ method ]` `3021 **` `3022 * Clears the paper, i.e. removes all the elements.` `3023 \*/` `3024 paperproto.clear = function () {` `3025 eve("clear", this);` `3026 var c = this.canvas;` `3027 while (c.firstChild) {` `3028 c.removeChild(c.firstChild);` `3029 }` `3030 this.bottom = this.top = null;` `3031 (this.desc = $("desc")).appendChild(g.doc.createTextNode("Created with Rapha\xebl " + R.version));` `3032 c.appendChild(this.desc);` `3033 c.appendChild(this.defs = $("defs"));` `3034 };` `3035 /*\` `3036 * Paper.remove` `3037 [ method ]` `3038 **` `3039 * Removes the paper from the DOM.` `3040 \*/` `3041 paperproto.remove = function () {` `3042 eve("remove", this);` `3043 this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas);` `3044 for (var i in this) {` `3045 this[i] = removed(i);` `3046 }` `3047 };` `3048 }` `3049` `3050 // VML` `3051 if (R.vml) {` `3052 var map = {M: "m", L: "l", C: "c", Z: "x", m: "t", l: "r", c: "v", z: "x"},` `3053 bites = /([clmz]),?([^clmz]*)/gi,` `3054 blurregexp = / progid:\S+Blur\([^\)]+\)/g,` `3055 val = /-?[^,\s-]+/g,` `3056 cssDot = "position:absolute;left:0;top:0;width:1px;height:1px",` `3057 zoom = 21600,` `3058 pathTypes = {path: 1, rect: 1},` `3059 ovalTypes = {circle: 1, ellipse: 1},` `3060 path2vml = function (path) {` `3061 var total = /[ahqstv]/ig,` `3062 command = pathToAbsolute;` `3063 Str(path).match(total) && (command = path2curve);` `3064 total = /[clmz]/g;` `3065 if (command == pathToAbsolute && !Str(path).match(total)) {` `3066 var res = Str(path).replace(bites, function (all, command, args) {` `3067 var vals = [],` `3068 isMove = lowerCase.call(command) == "m",` `3069 res = map[command];` `3070 args.replace(val, function (value) {` `3071 if (isMove && vals.length == 2) {` `3072 res += vals + map[command == "m" ? "l" : "L"];` `3073 vals = [];` `3074 }` `3075 vals.push(round(value * zoom));` `3076 });` `3077 return res + vals;` `3078 });` `3079 return res;` `3080 }` `3081 var pa = command(path), p, r;` `3082 res = [];` `3083 for (var i = 0, ii = pa.length; i < ii; i++) {` `3084 p = pa[i];` `3085 r = lowerCase.call(pa[i][0]);` `3086 r == "z" && (r = "x");` `3087 for (var j = 1, jj = p.length; j < jj; j++) {` `3088 r += round(p[j] * zoom) + (j != jj - 1 ? "," : E);` `3089 }` `3090 res.push(r);` `3091 }` `3092 return res.join(S);` `3093 },` `3094 compensation = function (deg, dx, dy) {` `3095 var m = new Matrix;` `3096 m.rotate(-deg, .5, .5);` `3097 return {` `3098 dx: m.x(dx, dy),` `3099 dy: m.y(dx, dy)` `3100 };` `3101 },` `3102 setCoords = function (p) {` `3103 var _ = p._,` `3104 sx = _.sx,` `3105 sy = _.sy,` `3106 deg = _.deg,` `3107 dx = _.dx,` `3108 dy = _.dy,` `3109 fillpos = _.fillpos,` `3110 o = p.node,` `3111 s = o.style,` `3112 y = 1,` `3113 m = p.matrix,` `3114 flip = "",` `3115 dxdy,` `3116 kx = zoom / sx,` `3117 ky = zoom / sy;` `3118 s.visibility = "hidden";` `3119 o.coordsize = abs(kx) + S + abs(ky);` `3120 s.rotation = deg * (sx * sy < 0 ? -1 : 1);` `3121 if (deg) {` `3122 var c = compensation(deg, dx, dy);` `3123 dx = c.dx;` `3124 dy = c.dy;` `3125 }` `3126 sx < 0 && (flip += "x");` `3127 sy < 0 && (flip += " y") && (y = -1);` `3128 s.flip = flip;` `3129 o.coordorigin = (dx * -kx) + S + (dy * -ky);` `3130 if (fillpos || _.fillsize) {` `3131 var fill = o.getElementsByTagName(fillString);` `3132 fill = fill && fill[0];` `3133 o.removeChild(fill);` `3134 if (fillpos) {` `3135 c = compensation(deg, m.x(fillpos[0], fillpos[1]), m.y(fillpos[0], fillpos[1]));` `3136 fill.position = c.dx * y + S + c.dy * y;` `3137 }` `3138 if (_.fillsize) {` `3139 fill.size = _.fillsize[0] * abs(sx) + S + _.fillsize[1] * abs(sy);` `3140 }` `3141 o.appendChild(fill);` `3142 }` `3143 s.visibility = "visible";` `3144 };` `3145 R.toString = function () {` `3146 return "Your browser doesn\u2019t support SVG. Falling down to VML.\nYou are running Rapha\xebl " + this.version;` `3147 };` `3148 addArrow = function (o, value, isEnd) {` `3149 var values = Str(value).toLowerCase().split("-"),` `3150 se = isEnd ? "end" : "start",` `3151 i = values.length,` `3152 type = "classic",` `3153 w = "medium",` `3154 h = "medium";` `3155 while (i--) {` `3156 switch (values[i]) {` `3157 case "block":` `3158 case "classic":` `3159 case "oval":` `3160 case "diamond":` `3161 case "open":` `3162 case "none":` `3163 type = values[i];` `3164 break;` `3165 case "wide":` `3166 case "narrow": h = values[i]; break;` `3167 case "long":` `3168 case "short": w = values[i]; break;` `3169 }` `3170 }` `3171 var stroke = o.node.getElementsByTagName("stroke")[0];` `3172 stroke[se + "arrow"] = type;` `3173 stroke[se + "arrowlength"] = w;` `3174 stroke[se + "arrowwidth"] = h;` `3175 };` `3176 setFillAndStroke = function (o, params) {` `3177 o.paper.canvas.style.display = "none";` `3178 o.attrs = o.attrs || {};` `3179 var node = o.node,` `3180 a = o.attrs,` `3181 s = node.style,` `3182 xy,` `3183 newpath = pathTypes[o.type] && (params.x != a.x || params.y != a.y || params.width != a.width || params.height != a.height || params.cx != a.cx || params.cy != a.cy || params.rx != a.rx || params.ry != a.ry || params.r != a.r),` `3184 isOval = ovalTypes[o.type] && (a.cx != params.cx || a.cy != params.cy || a.r != params.r || a.rx != params.rx || a.ry != params.ry),` `3185 res = o;` `3186` `3187` `3188 for (var par in params) if (params[has](par)) {` `3189 a[par] = params[par];` `3190 }` `3191 if (newpath) {` `3192 a.path = getPath[o.type](o);` `3193 o._.dirty = 1;` `3194 }` `3195 params.href && (node.href = params.href);` `3196 params.title && (node.title = params.title);` `3197 params.target && (node.target = params.target);` `3198 params.cursor && (s.cursor = params.cursor);` `3199 "blur" in params && o.blur(params.blur);` `3200 "transform" in params && o.transform(params.transform);` `3201 if (params.path && o.type == "path" || newpath) {` `3202 node.path = path2vml(a.path);` `3203 }` `3204 if (isOval) {` `3205 var cx = a.cx,` `3206 cy = a.cy,` `3207 rx = a.rx || a.r || 0,` `3208 ry = a.ry || a.r || 0;` `3209 node.path = R.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x", round((cx - rx) * zoom), round((cy - ry) * zoom), round((cx + rx) * zoom), round((cy + ry) * zoom), round(cx * zoom));` `3210 }` `3211 if ("clip-rect" in params) {` `3212 var rect = Str(params["clip-rect"]).split(separator);` `3213 if (rect.length == 4) {` `3214 rect[2] = +rect[2] + (+rect[0]);` `3215 rect[3] = +rect[3] + (+rect[1]);` `3216 var div = node.clipRect || g.doc.createElement("div"),` `3217 dstyle = div.style,` `3218 group = node.parentNode;` `3219 dstyle.clip = R.format("rect({1}px {2}px {3}px {0}px)", rect);` `3220 if (!node.clipRect) {` `3221 dstyle.position = "absolute";` `3222 dstyle.top = 0;` `3223 dstyle.left = 0;` `3224 dstyle.width = o.paper.width + "px";` `3225 dstyle.height = o.paper.height + "px";` `3226 group.parentNode.insertBefore(div, group);` `3227 div.appendChild(group);` `3228 node.clipRect = div;` `3229 }` `3230 }` `3231 if (!params["clip-rect"]) {` `3232 node.clipRect && (node.clipRect.style.clip = E);` `3233 }` `3234 }` `3235 if (o.textpath) {` `3236 var textpathStyle = o.textpath.style;` `3237 params.font && (textpathStyle.font = params.font);` `3238 params["font-family"] && (textpathStyle.fontFamily = '"' + params["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g, E) + '"');` `3239 params["font-size"] && (textpathStyle.fontSize = params["font-size"]);` `3240 params["font-weight"] && (textpathStyle.fontWeight = params["font-weight"]);` `3241 params["font-style"] && (textpathStyle.fontStyle = params["font-style"]);` `3242 }` `3243 if ("arrow-start" in params) {` `3244 addArrow(res, params["arrow-start"]);` `3245 }` `3246 if ("arrow-end" in params) {` `3247 addArrow(res, params["arrow-end"], 1);` `3248 }` `3249 if (params.opacity != null ||` `3250 params["stroke-width"] != null ||` `3251 params.fill != null ||` `3252 params.src != null ||` `3253 params.stroke != null ||` `3254 params["stroke-width"] != null ||` `3255 params["stroke-opacity"] != null ||` `3256 params["fill-opacity"] != null ||` `3257 params["stroke-dasharray"] != null ||` `3258 params["stroke-miterlimit"] != null ||` `3259 params["stroke-linejoin"] != null ||` `3260 params["stroke-linecap"] != null) {` `3261 var fill = node.getElementsByTagName(fillString),` `3262 newfill = false;` `3263 fill = fill && fill[0];` `3264 !fill && (newfill = fill = createNode(fillString));` `3265 if (o.type == "image" && params.src) {` `3266 fill.src = params.src;` `3267 }` `3268 if ("fill-opacity" in params || "opacity" in params) {` `3269 var opacity = ((+a["fill-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+R.getRGB(params.fill).o + 1 || 2) - 1);` `3270 opacity = mmin(mmax(opacity, 0), 1);` `3271 fill.opacity = opacity;` `3272 }` `3273 params.fill && (fill.on = true);` `3274 if (fill.on == null || params.fill == "none" || params.fill === null) {` `3275 fill.on = false;` `3276 }` `3277 if (fill.on && params.fill) {` `3278 var isURL = params.fill.match(ISURL);` `3279 if (isURL) {` `3280 fill.parentNode == node && node.removeChild(fill);` `3281 fill.rotate = true;` `3282 fill.src = isURL[1];` `3283 fill.type = "tile";` `3284 var bbox = o.getBBox(1);` `3285 fill.position = bbox.x + S + bbox.y;` `3286 o._.fillpos = [bbox.x, bbox.y];` `3287` `3288 preload(isURL[1], function () {` `3289 o._.fillsize = [this.offsetWidth, this.offsetHeight];` `3290 });` `3291 } else {` `3292 fill.color = R.getRGB(params.fill).hex;` `3293 fill.src = E;` `3294 fill.type = "solid";` `3295 if (R.getRGB(params.fill).error && (res.type in {circle: 1, ellipse: 1} || Str(params.fill).charAt() != "r") && addGradientFill(res, params.fill, fill)) {` `3296 a.fill = "none";` `3297 a.gradient = params.fill;` `3298 fill.rotate = false;` `3299 }` `3300 }` `3301 }` `3302 node.appendChild(fill);` `3303 var stroke = (node.getElementsByTagName("stroke") && node.getElementsByTagName("stroke")[0]),` `3304 newstroke = false;` `3305 !stroke && (newstroke = stroke = createNode("stroke"));` `3306 if ((params.stroke && params.stroke != "none") ||` `3307 params["stroke-width"] ||` `3308 params["stroke-opacity"] != null ||` `3309 params["stroke-dasharray"] ||` `3310 params["stroke-miterlimit"] ||` `3311 params["stroke-linejoin"] ||` `3312 params["stroke-linecap"]) {` `3313 stroke.on = true;` `3314 }` `3315 (params.stroke == "none" || params.stroke === null || stroke.on == null || params.stroke == 0 || params["stroke-width"] == 0) && (stroke.on = false);` `3316 var strokeColor = R.getRGB(params.stroke);` `3317 stroke.on && params.stroke && (stroke.color = strokeColor.hex);` `3318 opacity = ((+a["stroke-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+strokeColor.o + 1 || 2) - 1);` `3319 var width = (toFloat(params["stroke-width"]) || 1) * .75;` `3320 opacity = mmin(mmax(opacity, 0), 1);` `3321 params["stroke-width"] == null && (width = a["stroke-width"]);` `3322 params["stroke-width"] && (stroke.weight = width);` `3323 width && width < 1 && (opacity *= width) && (stroke.weight = 1);` `3324 stroke.opacity = opacity;` `3325` `3326 params["stroke-linejoin"] && (stroke.joinstyle = params["stroke-linejoin"] || "miter");` `3327 stroke.miterlimit = params["stroke-miterlimit"] || 8;` `3328 params["stroke-linecap"] && (stroke.endcap = params["stroke-linecap"] == "butt" ? "flat" : params["stroke-linecap"] == "square" ? "square" : "round");` `3329 if (params["stroke-dasharray"]) {` `3330 var dasharray = {` `3331 "-": "shortdash",` `3332 ".": "shortdot",` `3333 "-.": "shortdashdot",` `3334 "-..": "shortdashdotdot",` `3335 ". ": "dot",` `3336 "- ": "dash",` `3337 "--": "longdash",` `3338 "- .": "dashdot",` `3339 "--.": "longdashdot",` `3340 "--..": "longdashdotdot"` `3341 };` `3342 stroke.dashstyle = dasharray[has](params["stroke-dasharray"]) ? dasharray[params["stroke-dasharray"]] : E;` `3343 }` `3344 newstroke && node.appendChild(stroke);` `3345 }` `3346 if (res.type == "text") {` `3347 res.paper.canvas.style.display = E;` `3348 var span = res.paper.span,` `3349 m = 100,` `3350 fontSize = a.font && a.font.match(/\d+(?:\.\d*)?(?=px)/);` `3351 s = span.style;` `3352 a.font && (s.font = a.font);` `3353 a["font-family"] && (s.fontFamily = a["font-family"]);` `3354 a["font-weight"] && (s.fontWeight = a["font-weight"]);` `3355 a["font-style"] && (s.fontStyle = a["font-style"]);` `3356 fontSize = toFloat(fontSize ? fontSize[0] : a["font-size"]);` `3357 s.fontSize = fontSize * m + "px";` `3358 res.textpath.string && (span.innerHTML = Str(res.textpath.string).replace(/</g, "&#60;").replace(/&/g, "&#38;").replace(/\n/g, "<br>"));` `3359 var brect = span.getBoundingClientRect();` `3360 res.W = a.w = (brect.right - brect.left) / m;` `3361 res.H = a.h = (brect.bottom - brect.top) / m;` `3362 res.paper.canvas.style.display = "none";` `3363 res.X = a.x;` `3364 res.Y = a.y + res.H / 2;` `3365` `3366 ("x" in params || "y" in params) && (res.path.v = R.format("m{0},{1}l{2},{1}", round(a.x * zoom), round(a.y * zoom), round(a.x * zoom) + 1));` `3367 var dirtyattrs = ["x", "y", "text", "font", "font-family", "font-weight", "font-style", "font-size"];` `3368 for (var d = 0, dd = dirtyattrs.length; d < dd; d++) if (dirtyattrs[d] in params) {` `3369 res._.dirty = 1;` `3370 break;` `3371 }` `3372` `3373 // text-anchor emulation` `3374 switch (a["text-anchor"]) {` `3375 case "start":` `3376 res.textpath.style["v-text-align"] = "left";` `3377 res.bbx = res.W / 2;` `3378 break;` `3379 case "end":` `3380 res.textpath.style["v-text-align"] = "right";` `3381 res.bbx = -res.W / 2;` `3382 break;` `3383 default:` `3384 res.textpath.style["v-text-align"] = "center";` `3385 res.bbx = 0;` `3386 break;` `3387 }` `3388 res.textpath.style["v-text-kern"] = true;` `3389 }` `3390 res.paper.canvas.style.display = E;` `3391 };` `3392 addGradientFill = function (o, gradient, fill) {` `3393 o.attrs = o.attrs || {};` `3394 var attrs = o.attrs,` `3395 type = "linear",` `3396 fxfy = ".5 .5";` `3397 o.attrs.gradient = gradient;` `3398 gradient = Str(gradient).replace(radial_gradient, function (all, fx, fy) {` `3399 type = "radial";` `3400 if (fx && fy) {` `3401 fx = toFloat(fx);` `3402 fy = toFloat(fy);` `3403 pow(fx - .5, 2) + pow(fy - .5, 2) > .25 && (fy = math.sqrt(.25 - pow(fx - .5, 2)) * ((fy > .5) * 2 - 1) + .5);` `3404 fxfy = fx + S + fy;` `3405 }` `3406 return E;` `3407 });` `3408 gradient = gradient.split(/\s*\-\s*/);` `3409 if (type == "linear") {` `3410 var angle = gradient.shift();` `3411 angle = -toFloat(angle);` `3412 if (isNaN(angle)) {` `3413 return null;` `3414 }` `3415 }` `3416 var dots = parseDots(gradient);` `3417 if (!dots) {` `3418 return null;` `3419 }` `3420 o = o.shape || o.node;` `3421 if (dots.length) {` `3422 o.removeChild(fill);` `3423 fill.on = true;` `3424 fill.method = "none";` `3425 fill.color = dots[0].color;` `3426 fill.color2 = dots[dots.length - 1].color;` `3427 var clrs = [];` `3428 for (var i = 0, ii = dots.length; i < ii; i++) {` `3429 dots[i].offset && clrs.push(dots[i].offset + S + dots[i].color);` `3430 }` `3431 fill.colors && (fill.colors.value = clrs.length ? clrs.join() : "0% " + fill.color);` `3432 if (type == "radial") {` `3433 fill.type = "gradientTitle";` `3434 fill.focus = "100%";` `3435 fill.focussize = "0 0";` `3436 fill.focusposition = fxfy;` `3437 fill.angle = 0;` `3438 } else {` `3439 // fill.rotate= true;` `3440 fill.type = "gradient";` `3441 fill.angle = (270 - angle) % 360;` `3442 }` `3443 o.appendChild(fill);` `3444 // alert(fill.outerHTML);` `3445 }` `3446 return 1;` `3447 };` `3448 Element = function (node, vml) {` `3449 this[0] = this.node = node;` `3450 node.raphael = true;` `3451 this.id = R._oid++;` `3452 node.raphaelid = this.id;` `3453 this.X = 0;` `3454 this.Y = 0;` `3455 this.attrs = {};` `3456 this.paper = vml;` `3457 this.matrix = new Matrix;` `3458 this._ = {` `3459 transform: [],` `3460 sx: 1,` `3461 sy: 1,` `3462 dx: 0,` `3463 dy: 0,` `3464 deg: 0,` `3465 dirty: 1,` `3466 dirtyT: 1` `3467 };` `3468 !vml.bottom && (vml.bottom = this);` `3469 this.prev = vml.top;` `3470 vml.top && (vml.top.next = this);` `3471 vml.top = this;` `3472 this.next = null;` `3473 };` `3474 elproto = Element.prototype;` `3475 elproto.transform = function (tstr) {` `3476 if (tstr == null) {` `3477 return this._.transform;` `3478 }` `3479 extractTransform(this, tstr);` `3480 var matrix = this.matrix.clone(),` `3481 skew = this.skew;` `3482 matrix.translate(-.5, -.5);` `3483 if (this.type == "image") {` `3484 if (Str(tstr).indexOf("m") + 1) {` `3485 this.node.style.filter = matrix.toFilter();` `3486 var bb = this.getBBox(),` `3487 bbt = this.getBBox(1),` `3488 im = matrix.invert(),` `3489 dx = im.x(bb.x, bb.y) - im.x(bbt.x, bbt.y),` `3490 dy = im.y(bb.x, bb.y) - im.y(bbt.x, bbt.y);` `3491 // skew.offset = dx + S + dy;` `3492 // this.node.getElementsByTagName(fillString)[0].position = skew.offset;` `3493 } else {` `3494 this.node.style.filter = E;` `3495 setCoords(this);` `3496 }` `3497 } else {` `3498 // o = this.node,` `3499 // _ = this._,` `3500 // fillpos = _.fillpos,` `3501 // deg,` `3502 // matrix = this.matrix;` `3503 // fill = o.getElementsByTagName(fillString)[0],` `3504 // angle = fill.angle;` `3505` `3506 this.node.style.filter = E;` `3507 skew.matrix = matrix;` `3508 skew.offset = matrix.offset();` `3509` `3510 // if (0&&angle) {` `3511 // angle = R.rad(270 - angle);` `3512 // var dx = 100 * math.cos(angle),` `3513 // dy = 100 * math.sin(angle),` `3514 // zx = matrix.x(0, 0),` `3515 // zy = matrix.y(0, 0),` `3516 // mx = matrix.x(dx, dy),` `3517 // my = matrix.y(dx, dy);` `3518 // angle = R.angle(zx, zy, mx, my);` `3519 // fill.angle = (270 - angle) % 360;` `3520 // }` `3521 }` `3522 return this;` `3523 };` `3524 elproto.rotate = function (deg, cx, cy) {` `3525 if (this.removed) {` `3526 return this;` `3527 }` `3528 if (deg == null) {` `3529 return;` `3530 }` `3531 deg = Str(deg).split(separator);` `3532 if (deg.length - 1) {` `3533 cx = toFloat(deg[1]);` `3534 cy = toFloat(deg[2]);` `3535 }` `3536 deg = toFloat(deg[0]);` `3537 (cy == null) && (cx = cy);` `3538 if (cx == null || cy == null) {` `3539 var bbox = this.getBBox(1);` `3540 cx = bbox.x + bbox.width / 2;` `3541 cy = bbox.y + bbox.height / 2;` `3542 }` `3543 this._.dirtyT = 1;` `3544 this.transform(this._.transform.concat([["r", deg, cx, cy]]));` `3545 return this;` `3546 };` `3547 elproto.translate = function (dx, dy) {` `3548 if (this.removed) {` `3549 return this;` `3550 }` `3551 dx = Str(dx).split(separator);` `3552 if (dx.length - 1) {` `3553 dy = toFloat(dx[1]);` `3554 }` `3555 dx = toFloat(dx[0]) || 0;` `3556 dy = +dy || 0;` `3557 if (this._.bbox) {` `3558 this._.bbox.x += dx;` `3559 this._.bbox.y += dy;` `3560 }` `3561 this.transform(this._.transform.concat([["t", dx, dy]]));` `3562 return this;` `3563 };` `3564 elproto.scale = function (sx, sy, cx, cy) {` `3565 if (this.removed) {` `3566 return this;` `3567 }` `3568 sx = Str(sx).split(separator);` `3569 if (sx.length - 1) {` `3570 sy = toFloat(sx[1]);` `3571 cx = toFloat(sx[2]);` `3572 cy = toFloat(sx[3]);` `3573 isNaN(cx) && (cx = null);` `3574 isNaN(cy) && (cy = null);` `3575 }` `3576 sx = toFloat(sx[0]);` `3577 (sy == null) && (sy = sx);` `3578 (cy == null) && (cx = cy);` `3579 if (cx == null || cy == null) {` `3580 var bbox = this.getBBox(1);` `3581 }` `3582 cx = cx == null ? bbox.x + bbox.width / 2 : cx;` `3583 cy = cy == null ? bbox.y + bbox.height / 2 : cy;` `3584` `3585 this.transform(this._.transform.concat([["s", sx, sy, cx, cy]]));` `3586 this._.dirtyT = 1;` `3587 return this;` `3588 };` `3589 elproto.hide = function () {` `3590 !this.removed && (this.node.style.display = "none");` `3591 return this;` `3592 };` `3593 elproto.show = function () {` `3594 !this.removed && (this.node.style.display = E);` `3595 return this;` `3596 };` `3597 elproto._getBBox = function () {` `3598 if (this.removed) {` `3599 return {};` `3600 }` `3601 if (this.type == "text") {` `3602 return {` `3603 x: this.X + (this.bbx || 0) - this.W / 2,` `3604 y: this.Y - this.H,` `3605 width: this.W,` `3606 height: this.H` `3607 };` `3608 } else {` `3609 return pathDimensions(this.attrs.path);` `3610 }` `3611 };` `3612 elproto.remove = function () {` `3613 if (this.removed) {` `3614 return;` `3615 }` `3616 eve.unbind("*.*." + this.id);` `3617 tear(this, this.paper);` `3618 this.node.parentNode.removeChild(this.node);` `3619 this.shape && this.shape.parentNode.removeChild(this.shape);` `3620 for (var i in this) {` `3621 delete this[i];` `3622 }` `3623 this.removed = true;` `3624 };` `3625 elproto.attr = function (name, value) {` `3626 if (this.removed) {` `3627 return this;` `3628 }` `3629 if (name == null) {` `3630 var res = {};` `3631 for (var i in this.attrs) if (this.attrs[has](i)) {` `3632 res[i] = this.attrs[i];` `3633 }` `3634 res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient;` `3635 return res;` `3636 }` `3637 if (value == null && R.is(name, "string")) {` `3638 if (name == fillString && this.attrs.fill == "none" && this.attrs.gradient) {` `3639 return this.attrs.gradient;` `3640 }` `3641 if (name in this.attrs) {` `3642 return this.attrs[name];` `3643 } else if (R.is(this.paper.customAttributes[name], "function")) {` `3644 return this.paper.customAttributes[name].def;` `3645 } else {` `3646 return availableAttrs[name];` `3647 }` `3648 }` `3649 if (this.attrs && value == null && R.is(name, array)) {` `3650 var ii, values = {};` `3651 for (i = 0, ii = name.length; i < ii; i++) {` `3652 values[name[i]] = this.attr(name[i]);` `3653 }` `3654 return values;` `3655 }` `3656 var params;` `3657 if (value != null) {` `3658 params = {};` `3659 params[name] = value;` `3660 }` `3661 value == null && R.is(name, "object") && (params = name);` `3662 for (var key in params) {` `3663 eve("attr." + key + "." + this.id, this, params[key]);` `3664 }` `3665 if (params) {` `3666 for (key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], "function")) {` `3667 var par = this.paper.customAttributes[key].apply(this, [][concat](params[key]));` `3668 this.attrs[key] = params[key];` `3669 for (var subkey in par) if (par[has](subkey)) {` `3670 params[subkey] = par[subkey];` `3671 }` `3672 }` `3673 // this.paper.canvas.style.display = "none";` `3674 if (params.text && this.type == "text") {` `3675 this.textpath.string = params.text;` `3676 }` `3677 setFillAndStroke(this, params);` `3678 // this.paper.canvas.style.display = E;` `3679 }` `3680 return this;` `3681 };` `3682 elproto.toFront = function () {` `3683 !this.removed && this.node.parentNode.appendChild(this.node);` `3684 this.paper.top != this && tofront(this, this.paper);` `3685 return this;` `3686 };` `3687 elproto.toBack = function () {` `3688 if (this.removed) {` `3689 return this;` `3690 }` `3691 if (this.node.parentNode.firstChild != this.node) {` `3692 this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild);` `3693 toback(this, this.paper);` `3694 }` `3695 return this;` `3696 };` `3697 elproto.insertAfter = function (element) {` `3698 if (this.removed) {` `3699 return this;` `3700 }` `3701 if (element.constructor == Set) {` `3702 element = element[element.length - 1];` `3703 }` `3704 if (element.node.nextSibling) {` `3705 element.node.parentNode.insertBefore(this.node, element.node.nextSibling);` `3706 } else {` `3707 element.node.parentNode.appendChild(this.node);` `3708 }` `3709 insertafter(this, element, this.paper);` `3710 return this;` `3711 };` `3712 elproto.insertBefore = function (element) {` `3713 if (this.removed) {` `3714 return this;` `3715 }` `3716 if (element.constructor == Set) {` `3717 element = element[0];` `3718 }` `3719 element.node.parentNode.insertBefore(this.node, element.node);` `3720 insertbefore(this, element, this.paper);` `3721 return this;` `3722 };` `3723 elproto.blur = function (size) {` `3724 var s = this.node.runtimeStyle,` `3725 f = s.filter;` `3726 f = f.replace(blurregexp, E);` `3727 if (+size !== 0) {` `3728 this.attrs.blur = size;` `3729 s.filter = f + S + ms + ".Blur(pixelradius=" + (+size || 1.5) + ")";` `3730 s.margin = R.format("-{0}px 0 0 -{0}px", round(+size || 1.5));` `3731 } else {` `3732 s.filter = f;` `3733 s.margin = 0;` `3734 delete this.attrs.blur;` `3735 }` `3736 };` `3737` `3738 thePath = function (pathString, vml) {` `3739 var el = createNode("shape");` `3740 el.style.cssText = cssDot;` `3741 el.coordsize = zoom + S + zoom;` `3742 el.coordorigin = vml.coordorigin;` `3743 var p = new Element(el, vml),` `3744 attr = {fill: "none", stroke: "#000"};` `3745 pathString && (attr.path = pathString);` `3746 p.type = "path";` `3747 p.path = [];` `3748 p.Path = E;` `3749 setFillAndStroke(p, attr);` `3750 vml.canvas.appendChild(el);` `3751 var skew = createNode("skew");` `3752 skew.on = true;` `3753 el.appendChild(skew);` `3754 p.skew = skew;` `3755 p.transform(E);` `3756 return p;` `3757 };` `3758 theRect = function (vml, x, y, w, h, r) {` `3759 var path = rectPath(x, y, w, h, r),` `3760 res = vml.path(path),` `3761 a = res.attrs;` `3762 res.X = a.x = x;` `3763 res.Y = a.y = y;` `3764 res.W = a.width = w;` `3765 res.H = a.height = h;` `3766 a.r = r;` `3767 a.path = path;` `3768 res.type = "rect";` `3769 return res;` `3770 };` `3771 theEllipse = function (vml, x, y, rx, ry) {` `3772 var res = vml.path(),` `3773 a = res.attrs;` `3774 res.X = x - rx;` `3775 res.Y = y - ry;` `3776 res.W = rx * 2;` `3777 res.H = ry * 2;` `3778 res.type = "ellipse";` `3779 setFillAndStroke(res, {` `3780 cx: x,` `3781 cy: y,` `3782 rx: rx,` `3783 ry: ry` `3784 });` `3785 return res;` `3786 };` `3787 theCircle = function (vml, x, y, r) {` `3788 var res = vml.path(),` `3789 a = res.attrs;` `3790 res.X = x - r;` `3791 res.Y = y - r;` `3792 res.W = res.H = r * 2;` `3793 res.type = "circle";` `3794 setFillAndStroke(res, {` `3795 cx: x,` `3796 cy: y,` `3797 r: r` `3798 });` `3799 return res;` `3800 };` `3801 theImage = function (vml, src, x, y, w, h) {` `3802 var path = rectPath(x, y, w, h),` `3803 res = vml.path(path).attr({stroke: "none"}),` `3804 a = res.attrs,` `3805 node = res.node,` `3806 fill = node.getElementsByTagName(fillString)[0];` `3807 a.src = src;` `3808 res.X = a.x = x;` `3809 res.Y = a.y = y;` `3810 res.W = a.width = w;` `3811 res.H = a.height = h;` `3812 a.path = path;` `3813 res.type = "image";` `3814 fill.parentNode == node && node.removeChild(fill);` `3815 fill.rotate = true;` `3816 fill.src = src;` `3817 fill.type = "tile";` `3818 res._.fillpos = [x, y];` `3819 res._.fillsize = [w, h];` `3820 node.appendChild(fill);` `3821 setCoords(res);` `3822 return res;` `3823 };` `3824 theText = function (vml, x, y, text) {` `3825 var el = createNode("shape"),` `3826 path = createNode("path"),` `3827 o = createNode("textpath");` `3828 x = x || 0;` `3829 y = y || 0;` `3830 text = text || "";` `3831 path.v = R.format("m{0},{1}l{2},{1}", round(x * zoom), round(y * zoom), round(x * zoom) + 1);` `3832 path.textpathok = true;` `3833 o.string = Str(text);` `3834 o.on = true;` `3835 el.style.cssText = "position:absolute;left:0;top:0;width:1;height:1";` `3836 el.coordsize = zoom + S + zoom;` `3837 el.coordorigin = "0 0";` `3838 var p = new Element(el, vml),` `3839 attr = {fill: "#000", stroke: "none", font: availableAttrs.font, text: text};` `3840 p.shape = el;` `3841 p.path = path;` `3842 p.textpath = o;` `3843 p.type = "text";` `3844 p.attrs.text = Str(text);` `3845 p.attrs.x = x;` `3846 p.attrs.y = y;` `3847 p.attrs.w = 1;` `3848 p.attrs.h = 1;` `3849 setFillAndStroke(p, attr);` `3850 el.appendChild(o);` `3851 el.appendChild(path);` `3852 vml.canvas.appendChild(el);` `3853 var skew = createNode("skew");` `3854 skew.on = true;` `3855 el.appendChild(skew);` `3856 p.skew = skew;` `3857 p.transform(E);` `3858 return p;` `3859 };` `3860 setSize = function (width, height) {` `3861 var cs = this.canvas.style;` `3862 this.width = width;` `3863 this.height = height;` `3864 width == +width && (width += "px");` `3865 height == +height && (height += "px");` `3866 cs.width = width;` `3867 cs.height = height;` `3868 cs.clip = "rect(0 " + width + " " + height + " 0)";` `3869 if (this._viewBox) {` `3870 setViewBox.apply(this, this._viewBox);` `3871 }` `3872 return this;` `3873 };` `3874 setViewBox = function (x, y, w, h, fit) {` `3875 eve("setViewBox", this, this._viewBox, [x, y, w, h, fit]);` `3876 var width = this.width,` `3877 height = this.height,` `3878 size = 1e3 * mmax(w / width, h / height),` `3879 H, W;` `3880 if (fit) {` `3881 H = height / h;` `3882 W = width / w;` `3883 if (w * H < width) {` `3884 x -= (width - w * H) / 2 / H;` `3885 }` `3886 if (h * W < height) {` `3887 y -= (height - h * W) / 2 / W;` `3888 }` `3889 }` `3890 this._viewBox = [x, y, w, h, !!fit];` `3891 this.forEach(function (el) {` `3892 el.transform("...");` `3893 });` `3894 return this;` `3895 };` `3896 var createNode,` `3897 initWin = function (win) {` `3898 var doc = win.document;` `3899 doc.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)");` `3900 try {` `3901 !doc.namespaces.rvml && doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml");` `3902 createNode = function (tagName) {` `3903 return doc.createElement('<rvml:' + tagName + ' class="rvml">');` `3904 };` `3905 } catch (e) {` `3906 createNode = function (tagName) {` `3907 return doc.createElement('<' + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');` `3908 };` `3909 }` `3910 };` `3911 initWin(g.win);` `3912 create = function () {` `3913 var con = getContainer[apply](0, arguments),` `3914 container = con.container,` `3915 height = con.height,` `3916 s,` `3917 width = con.width,` `3918 x = con.x,` `3919 y = con.y;` `3920 if (!container) {` `3921 throw new Error("VML container not found.");` `3922 }` `3923 var res = new Paper,` `3924 c = res.canvas = g.doc.createElement("div"),` `3925 cs = c.style;` `3926 x = x || 0;` `3927 y = y || 0;` `3928 width = width || 512;` `3929 height = height || 342;` `3930 res.width = width;` `3931 res.height = height;` `3932 width == +width && (width += "px");` `3933 height == +height && (height += "px");` `3934 res.coordsize = zoom * 1e3 + S + zoom * 1e3;` `3935 res.coordorigin = "0 0";` `3936 res.span = g.doc.createElement("span");` `3937 res.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;";` `3938 c.appendChild(res.span);` `3939 cs.cssText = R.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden", width, height);` `3940 if (container == 1) {` `3941 g.doc.body.appendChild(c);` `3942 cs.left = x + "px";` `3943 cs.top = y + "px";` `3944 cs.position = "absolute";` `3945 } else {` `3946 if (container.firstChild) {` `3947 container.insertBefore(c, container.firstChild);` `3948 } else {` `3949 container.appendChild(c);` `3950 }` `3951 }` `3952 plugins.call(res, res, R.fn);` `3953 res.renderfix = fun;` `3954 return res;` `3955 };` `3956 paperproto.clear = function () {` `3957 eve("clear", this);` `3958 this.canvas.innerHTML = E;` `3959 this.span = g.doc.createElement("span");` `3960 this.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";` `3961 this.canvas.appendChild(this.span);` `3962 this.bottom = this.top = null;` `3963 };` `3964 paperproto.remove = function () {` `3965 eve("remove", this);` `3966 this.canvas.parentNode.removeChild(this.canvas);` `3967 for (var i in this) {` `3968 this[i] = removed(i);` `3969 }` `3970 return true;` `3971 };` `3972 }` `3973` `3974 // WebKit rendering bug workaround method` `3975 var version = navigator.userAgent.match(/Version\/(.*?)\s/) || navigator.userAgent.match(/Chrome\/(\d+)/);` `3976 if ((navigator.vendor == "Apple Computer, Inc.") && (version && version[1] < 4 || navigator.platform.slice(0, 2) == "iP") ||` `3977 (navigator.vendor == "Google Inc." && version && version[1] < 8)) {` `3978 /*\` `3979 * Paper.safari` `3980 [ method ]` `3981 **` `3982 * There is an inconvenient rendering bug in Safari (WebKit):` `3983 * sometimes the rendering should be forced.` `3984 * This method should help with dealing with this bug.` `3985 \*/` `3986 paperproto.safari = function () {` `3987 var rect = this.rect(-99, -99, this.width + 99, this.height + 99).attr({stroke: "none"});` `3988 setTimeout(function () {rect.remove();});` `3989 };` `3990 } else {` `3991 paperproto.safari = fun;` `3992 }` `3993` `3994 // Events` `3995 var preventDefault = function () {` `3996 this.returnValue = false;` `3997 },` `3998 preventTouch = function () {` `3999 return this.originalEvent.preventDefault();` `4000 },` `4001 stopPropagation = function () {` `4002 this.cancelBubble = true;` `4003 },` `4004 stopTouch = function () {` `4005 return this.originalEvent.stopPropagation();` `4006 },` `4007 addEvent = (function () {` `4008 if (g.doc.addEventListener) {` `4009 return function (obj, type, fn, element) {` `4010 var realName = supportsTouch && touchMap[type] ? touchMap[type] : type;` `4011 var f = function (e) {` `4012 if (supportsTouch && touchMap[has](type)) {` `4013 for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) {` `4014 if (e.targetTouches[i].target == obj) {` `4015 var olde = e;` `4016 e = e.targetTouches[i];` `4017 e.originalEvent = olde;` `4018 e.preventDefault = preventTouch;` `4019 e.stopPropagation = stopTouch;` `4020 break;` `4021 }` `4022 }` `4023 }` `4024 return fn.call(element, e);` `4025 };` `4026 obj.addEventListener(realName, f, false);` `4027 return function () {` `4028 obj.removeEventListener(realName, f, false);` `4029 return true;` `4030 };` `4031 };` `4032 } else if (g.doc.attachEvent) {` `4033 return function (obj, type, fn, element) {` `4034 var f = function (e) {` `4035 e = e || g.win.event;` `4036 e.preventDefault = e.preventDefault || preventDefault;` `4037 e.stopPropagation = e.stopPropagation || stopPropagation;` `4038 return fn.call(element, e);` `4039 };` `4040 obj.attachEvent("on" + type, f);` `4041 var detacher = function () {` `4042 obj.detachEvent("on" + type, f);` `4043 return true;` `4044 };` `4045 return detacher;` `4046 };` `4047 }` `4048 })(),` `4049 drag = [],` `4050 dragMove = function (e) {` `4051 var x = e.clientX,` `4052 y = e.clientY,` `4053 scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,` `4054 scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft,` `4055 dragi,` `4056 j = drag.length;` `4057 while (j--) {` `4058 dragi = drag[j];` `4059 if (supportsTouch) {` `4060 var i = e.touches.length,` `4061 touch;` `4062 while (i--) {` `4063 touch = e.touches[i];` `4064 if (touch.identifier == dragi.el._drag.id) {` `4065 x = touch.clientX;` `4066 y = touch.clientY;` `4067 (e.originalEvent ? e.originalEvent : e).preventDefault();` `4068 break;` `4069 }` `4070 }` `4071 } else {` `4072 e.preventDefault();` `4073 }` `4074 var node = dragi.el.node,` `4075 o,` `4076 next = node.nextSibling,` `4077 parent = node.parentNode,` `4078 display = node.style.display;` `4079 g.win.opera && parent.removeChild(node);` `4080 node.style.display = "none";` `4081 o = dragi.el.paper.getElementByPoint(x, y);` `4082 node.style.display = display;` `4083 g.win.opera && (next ? parent.insertBefore(node, next) : parent.appendChild(node));` `4084 o && eve("drag.over." + dragi.el.id, dragi.el, o);` `4085 x += scrollX;` `4086 y += scrollY;` `4087 eve("drag.move." + dragi.el.id, dragi.move_scope || dragi.el, x - dragi.el._drag.x, y - dragi.el._drag.y, x, y, e);` `4088 }` `4089 },` `4090 dragUp = function (e) {` `4091 R.unmousemove(dragMove).unmouseup(dragUp);` `4092 var i = drag.length,` `4093 dragi;` `4094 while (i--) {` `4095 dragi = drag[i];` `4096 dragi.el._drag = {};` `4097 eve("drag.end." + dragi.el.id, dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e);` `4098 }` `4099 drag = [];` `4100 };` `4101 for (var i = events.length; i--;) {` `4102 (function (eventName) {` `4103 R[eventName] = Element.prototype[eventName] = function (fn, scope) {` `4104 if (R.is(fn, "function")) {` `4105 this.events = this.events || [];` `4106 this.events.push({name: eventName, f: fn, unbind: addEvent(this.shape || this.node || g.doc, eventName, fn, scope || this)});` `4107 }` `4108 return this;` `4109 };` `4110 R["un" + eventName] = Element.prototype["un" + eventName] = function (fn) {` `4111 var events = this.events,` `4112 l = events.length;` `4113 while (l--) if (events[l].name == eventName && events[l].f == fn) {` `4114 events[l].unbind();` `4115 events.splice(l, 1);` `4116 !events.length && delete this.events;` `4117 return this;` `4118 }` `4119 return this;` `4120 };` `4121 })(events[i]);` `4122 }` `4123 /*\` `4124 * Element.hover` `4125 [ method ]` `4126 **` `4127 * Adds event handlers for hover for the element.` `4128 > Parameters` `4129 - f_in (function) handler for hover in` `4130 - f_out (function) handler for hover out` `4131 - icontext (object) #optional context for hover in handler` `4132 - ocontext (object) #optional context for hover out handler` `4133 = (object) @Element` `4134 \*/` `4135 elproto.hover = function (f_in, f_out, scope_in, scope_out) {` `4136 return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in);` `4137 };` `4138 /*\` `4139 * Element.unhover` `4140 [ method ]` `4141 **` `4142 * Removes event handlers for hover for the element.` `4143 > Parameters` `4144 - f_in (function) handler for hover in` `4145 - f_out (function) handler for hover out` `4146 = (object) @Element` `4147 \*/` `4148 elproto.unhover = function (f_in, f_out) {` `4149 return this.unmouseover(f_in).unmouseout(f_out);` `4150 };` `4151 /*\` `4152 * Element.drag` `4153 [ method ]` `4154 **` `4155 * Adds event handlers for drag of the element.` `4156 > Parameters` `4157 - onmove (function) handler for moving` `4158 - onstart (function) handler for drag start` `4159 - onend (function) handler for drag end` `4160 - mcontext (object) #optional context for moving handler` `4161 - scontext (object) #optional context for drag start handler` `4162 - econtext (object) #optional context for drag end handler` `4163 * Additionaly following `drag` events will be triggered: `drag.start.<id>` on start,` `4164 * `drag.end.<id>` on end and `drag.move.<id>` on every move. When element will be dragged over another element` `4165 * `drag.over.<id>` will be fired as well.` `4166 *` `4167 * Start event and start handler will be called in specified context or in context of the element with following parameters:` `4168 o x (number) x position of the mouse` `4169 o y (number) y position of the mouse` `4170 o event (object) DOM event object` `4171 * Move event and move handler will be called in specified context or in context of the element with following parameters:` `4172 o dx (number) shift by x from the start point` `4173 o dy (number) shift by y from the start point` `4174 o x (number) x position of the mouse` `4175 o y (number) y position of the mouse` `4176 o event (object) DOM event object` `4177 * End event and end handler will be called in specified context or in context of the element with following parameters:` `4178 o event (object) DOM event object` `4179 = (object) @Element` `4180 \*/` `4181 elproto.drag = function (onmove, onstart, onend, move_scope, start_scope, end_scope) {` `4182 function start(e) {` `4183 (e.originalEvent || e).preventDefault();` `4184 var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,` `4185 scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft;` `4186 this._drag.x = e.clientX + scrollX;` `4187 this._drag.y = e.clientY + scrollY;` `4188 this._drag.id = e.identifier;` `4189 !drag.length && R.mousemove(dragMove).mouseup(dragUp);` `4190 drag.push({el: this, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope});` `4191 onstart && eve.on("drag.start." + this.id, onstart);` `4192 onmove && eve.on("drag.move." + this.id, onmove);` `4193 onend && eve.on("drag.end." + this.id, onend);` `4194 eve("drag.start." + this.id, start_scope || move_scope || this, e.clientX + scrollX, e.clientY + scrollY, e);` `4195 }` `4196 this._drag = {};` `4197 this.mousedown(start);` `4198 return this;` `4199 };` `4200 /*\` `4201 * Element.onDragOver` `4202 [ method ]` `4203 **` `4204 * Shortcut for assigning event handler for `drag.over.<id>` event, where id is id of the element (see @Element.id).` `4205 > Parameters` `4206 - f (function) handler for event` `4207 \*/` `4208 elproto.onDragOver = function (f) {` `4209 f ? eve.on("drag.over." + this.id, f) : eve.unbind("drag.over." + this.id);` `4210 };` `4211 /*\` `4212 * Element.undrag` `4213 [ method ]` `4214 **` `4215 * Removes all drag event handlers from given element.` `4216 \*/` `4217 elproto.undrag = function () {` `4218 var i = drag.length;` `4219 while (i--) if (drag[i].el == this) {` `4220 R.unmousedown(drag[i].start);` `4221 drag.splice(i++, 1);` `4222 eve.unbind("drag.*." + this.id);` `4223 }` `4224 !drag.length && R.unmousemove(dragMove).unmouseup(dragUp);` `4225 };` `4226 /*\` `4227 * Paper.circle` `4228 [ method ]` `4229 **` `4230 * Draws a circle.` `4231 **` `4232 > Parameters` `4233 **` `4234 - x (number) x coordinate of the centre` `4235 - y (number) y coordinate of the centre` `4236 - r (number) radius` `4237 = (object) Raphaël element object with type “circle”` `4238 **` `4239 > Usage` `4240 | var c = paper.circle(50, 50, 40);` `4241 \*/` `4242 paperproto.circle = function (x, y, r) {` `4243 return theCircle(this, x || 0, y || 0, r || 0);` `4244 };` `4245 /*\` `4246 * Paper.rect` `4247 [ method ]` `4248 *` `4249 * Draws a rectangle.` `4250 **` `4251 > Parameters` `4252 **` `4253 - x (number) x coordinate of the top left corner` `4254 - y (number) y coordinate of the top left corner` `4255 - width (number) width` `4256 - height (number) height` `4257 - r (number) #optional radius for rounded corners, default is 0` `4258 = (object) Raphaël element object with type “rect”` `4259 **` `4260 > Usage` `4261 | // regular rectangle` `4262 | var c = paper.rect(10, 10, 50, 50);` `4263 | // rectangle with rounded corners` `4264 | var c = paper.rect(40, 40, 50, 50, 10);` `4265 \*/` `4266 paperproto.rect = function (x, y, w, h, r) {` `4267 return theRect(this, x || 0, y || 0, w || 0, h || 0, r || 0);` `4268 };` `4269 /*\` `4270 * Paper.ellipse` `4271 [ method ]` `4272 **` `4273 * Draws an ellipse.` `4274 **` `4275 > Parameters` `4276 **` `4277 - x (number) x coordinate of the centre` `4278 - y (number) y coordinate of the centre` `4279 - rx (number) horizontal radius` `4280 - ry (number) vertical radius` `4281 = (object) Raphaël element object with type “ellipse”` `4282 **` `4283 > Usage` `4284 | var c = paper.ellipse(50, 50, 40, 20);` `4285 \*/` `4286 paperproto.ellipse = function (x, y, rx, ry) {` `4287 return theEllipse(this, x || 0, y || 0, rx || 0, ry || 0);` `4288 };` `4289 /*\` `4290 * Paper.path` `4291 [ method ]` `4292 **` `4293 * Creates a path element by given path data string.` `4294 **` `4295 > Parameters` `4296 **` `4297 - pathString (string) path data in SVG path string format.` `4298 = (object) Raphaël element object with type “ellipse”` `4299 # Details of a path's data attribute's format are described in the <a href="http://www.w3.org/TR/SVG/paths.html#PathData">SVG specification</a>.` `4300 **` `4301 > Usage` `4302 | var c = paper.path("M10 10L90 90");` `4303 | // draw a diagonal line:` `4304 | // move to 10,10, line to 90,90` `4305 \*/` `4306 paperproto.path = function (pathString) {` `4307 pathString && !R.is(pathString, string) && !R.is(pathString[0], array) && (pathString += E);` `4308 return thePath(R.format[apply](R, arguments), this);` `4309 };` `4310 /*\` `4311 * Paper.image` `4312 [ method ]` `4313 **` `4314 * Embeds an image into the surface.` `4315 **` `4316 > Parameters` `4317 **` `4318 - src (string) URI of the source image` `4319 - x (number) x coordinate position` `4320 - y (number) y coordinate position` `4321 - width (number) width of the image` `4322 - height (number) height of the image` `4323 = (object) Raphaël element object with type “image”` `4324 **` `4325 > Usage` `4326 | var c = paper.image("apple.png", 10, 10, 80, 80);` `4327 \*/` `4328 paperproto.image = function (src, x, y, w, h) {` `4329 return theImage(this, src || "about:blank", x || 0, y || 0, w || 0, h || 0);` `4330 };` `4331 /*\` `4332 * Paper.text` `4333 [ method ]` `4334 **` `4335 * Draws a text string. If you need line breaks, put “\n” in the string.` `4336 **` `4337 > Parameters` `4338 **` `4339 - x (number) x coordinate position` `4340 - y (number) y coordinate position` `4341 - text (string) The text string to draw` `4342 = (object) Raphaël element object with type “text”` `4343 **` `4344 > Usage` `4345 | var t = paper.text(50, 50, "Raphaël\nkicks\nbutt!");` `4346 \*/` `4347 paperproto.text = function (x, y, text) {` `4348 return theText(this, x || 0, y || 0, Str(text));` `4349 };` `4350 /*\` `4351 * Paper.set` `4352 [ method ]` `4353 **` `4354 * Creates array-like object to keep and operate several elements at once.` `4355 * Warning: it doesn’t create any elements for itself in the page, it just groups existing elements.` `4356 * Sets act as pseudo elements — all methods available to an element can be used on a set.` `4357 = (object) array-like object that represents set of elements` `4358 **` `4359 > Usage` `4360 | var st = paper.set();` `4361 | st.push(` `4362 | paper.circle(10, 10, 5),` `4363 | paper.circle(30, 10, 5)` `4364 | );` `4365 | st.attr({fill: "red"});` `4366 \*/` `4367 paperproto.set = function (itemsArray) {` `4368 arguments.length > 1 && (itemsArray = Array.prototype.splice.call(arguments, 0, arguments.length));` `4369 return new Set(itemsArray);` `4370 };` `4371 /*\` `4372 * Paper.setSize` `4373 [ method ]` `4374 **` `4375 * If you need to change dimensions of the canvas call this method` `4376 **` `4377 > Parameters` `4378 **` `4379 - width (number) new width of the canvas` `4380 - height (number) new height of the canvas` `4381 > Usage` `4382 | var st = paper.set();` `4383 | st.push(` `4384 | paper.circle(10, 10, 5),` `4385 | paper.circle(30, 10, 5)` `4386 | );` `4387 | st.attr({fill: "red"});` `4388 \*/` `4389 paperproto.setSize = setSize;` `4390 /*\` `4391 * Paper.setViewBox` `4392 [ method ]` `4393 **` `4394 * Sets the view box of the paper. Practically it gives you ability to zoom and pan whole paper surface by` `4395 * specifying new boundaries.` `4396 **` `4397 > Parameters` `4398 **` `4399 x, y, w, h, fit` `4400 - x (number) new x position, default is `0`` `4401 - y (number) new y position, default is `0`` `4402 - w (number) new width of the canvas` `4403 - h (number) new height of the canvas` `4404 - fit (boolean) `true` if you want graphics to fit into new boundary box` `4405 \*/` `4406 paperproto.setViewBox = setViewBox;` `4407 /*\` `4408 * Paper.top` `4409 [ property ]` `4410 **` `4411 * Points to the topmost element on the paper` `4412 \*/` `4413 /*\` `4414 * Paper.bottom` `4415 [ property ]` `4416 **` `4417 * Points to the bottom element on the paper` `4418 \*/` `4419 paperproto.top = paperproto.bottom = null;` `4420 /*\` `4421 * Paper.raphael` `4422 [ property ]` `4423 **` `4424 * Points to the @Raphael object/function` `4425 \*/` `4426 paperproto.raphael = R;` `4427 var getOffset = function (elem) {` `4428 var box = elem.getBoundingClientRect(),` `4429 doc = elem.ownerDocument,` `4430 body = doc.body,` `4431 docElem = doc.documentElement,` `4432 clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,` `4433 top = box.top + (g.win.pageYOffset || docElem.scrollTop || body.scrollTop ) - clientTop,` `4434 left = box.left + (g.win.pageXOffset || docElem.scrollLeft || body.scrollLeft) - clientLeft;` `4435 return {` `4436 y: top,` `4437 x: left` `4438 };` `4439 };` `4440 /*\` `4441 * Paper.getElementByPoint` `4442 [ method ]` `4443 **` `4444 * Returns you topmost element under given point.` `4445 **` `4446 = (object) Raphaël element object` `4447 > Parameters` `4448 **` `4449 - x (number) x coordinate from the top left corner of the window` `4450 - y (number) y coordinate from the top left corner of the window` `4451 > Usage` `4452 | paper.getElementByPoint(mouseX, mouseY).attr({stroke: "#f00"});` `4453 \*/` `4454 paperproto.getElementByPoint = function (x, y) {` `4455 var paper = this,` `4456 svg = paper.canvas,` `4457 target = g.doc.elementFromPoint(x, y);` `4458 if (g.win.opera && target.tagName == "svg") {` `4459 var so = getOffset(svg),` `4460 sr = svg.createSVGRect();` `4461 sr.x = x - so.x;` `4462 sr.y = y - so.y;` `4463 sr.width = sr.height = 1;` `4464 var hits = svg.getIntersectionList(sr, null);` `4465 if (hits.length) {` `4466 target = hits[hits.length - 1];` `4467 }` `4468 }` `4469 if (!target) {` `4470 return null;` `4471 }` `4472 while (target.parentNode && target != svg.parentNode && !target.raphael) {` `4473 target = target.parentNode;` `4474 }` `4475 target == paper.canvas.parentNode && (target = svg);` `4476 target = target && target.raphael ? paper.getById(target.raphaelid) : null;` `4477 return target;` `4478 };` `4479 /*\` `4480 * Paper.getById` `4481 [ method ]` `4482 **` `4483 * Returns you element by its internal ID.` `4484 **` `4485 > Parameters` `4486 **` `4487 - id (number) id` `4488 = (object) Raphaël element object` `4489 \*/` `4490 paperproto.getById = function (id) {` `4491 var bot = this.bottom;` `4492 while (bot) {` `4493 if (bot.id == id) {` `4494 return bot;` `4495 }` `4496 bot = bot.next;` `4497 }` `4498 return null;` `4499 };` `4500 /*\` `4501 * Paper.forEach` `4502 [ method ]` `4503 **` `4504 * Executes given function for each element on the paper` `4505 *` `4506 * If callback function returns `false` it will stop loop running.` `4507 **` `4508 > Parameters` `4509 **` `4510 - callback (function) function to run` `4511 - thisArg (object) context object for the callback` `4512 = (object) Paper object` `4513 \*/` `4514 paperproto.forEach = function (callback, thisArg) {` `4515 var bot = this.bottom;` `4516 while (bot) {` `4517 if (callback.call(thisArg, bot) === false) {` `4518 return this;` `4519 }` `4520 bot = bot.next;` `4521 }` `4522 return this;` `4523 };` `4524 function x_y() {` `4525 return this.x + S + this.y;` `4526 }` `4527 function x_y_w_h() {` `4528 return this.x + S + this.y + S + this.width + "\xd7" + this.height;` `4529 }` `4530 /*\` `4531 * Element.getBBox` `4532 [ method ]` `4533 **` `4534 * Return bounding box for a given element` `4535 **` `4536 > Parameters` `4537 **` `4538 - isWithoutTransform (boolean) flag, `true` if you want to have bounding box before transformations. Default is `false`.` `4539 = (object) Bounding box object:` `4540 o {` `4541 o x: (number) top left corner x` `4542 o y: (number) top left corner y` `4543 o width: (number) width` `4544 o height: (number) height` `4545 o }` `4546 \*/` `4547 elproto.getBBox = function (isWithoutTransform) {` `4548 if (this.removed) {` `4549 return {};` `4550 }` `4551 var _ = this._;` `4552 if (isWithoutTransform) {` `4553 if (_.dirty || !_.bboxwt) {` `4554 this.realPath = getPath[this.type](this);` `4555 _.bboxwt = pathDimensions(this.realPath);` `4556 _.bboxwt.toString = x_y_w_h;` `4557 _.dirty = 0;` `4558 }` `4559 return _.bboxwt;` `4560 }` `4561 if (_.dirty || _.dirtyT || !_.bbox) {` `4562 if (_.dirty || !this.realPath) {` `4563 _.bboxwt = 0;` `4564 this.realPath = getPath[this.type](this);` `4565 }` `4566 _.bbox = pathDimensions(mapPath(this.realPath, this.matrix));` `4567 _.bbox.toString = x_y_w_h;` `4568 _.dirty = _.dirtyT = 0;` `4569 }` `4570 return _.bbox;` `4571 };` `4572 /*\` `4573 * Element.clone` `4574 [ method ]` `4575 **` `4576 = (object) clone of a given element` `4577 **` `4578 \*/` `4579 elproto.clone = function () {` `4580 if (this.removed) {` `4581 return null;` `4582 }` `4583 var attr = this.attr();` `4584 delete attr.scale;` `4585 delete attr.translation;` `4586 return this.paper[this.type]().attr(attr);` `4587 };` `4588 /*\` `4589 * Element.glow` `4590 [ method ]` `4591 **` `4592 * Return set of elements that create glow-like effect around given element. See @Paper.set.` `4593 *` `4594 * Note: Glow is not connected to the element. If you change element attributes it won’t adjust itself.` `4595 **` `4596 > Parameters` `4597 **` `4598 - glow (object) #optional parameters object with all properties optional:` `4599 o {` `4600 o width (number) size of the glow, default is `10`` `4601 o fill (boolean) will it be filled, default is `false`` `4602 o opacity: opacity, default is `0.5`` `4603 o offsetx: horizontal offset, default is `0`` `4604 o offsety: vertical offset, default is `0`` `4605 o color: glow colour, default is `black`` `4606 o }` `4607 = (object) @Paper.set of elements that represents glow` `4608 \*/` `4609 elproto.glow = function (glow) {` `4610 if (this.type == "text") {` `4611 return null;` `4612 }` `4613 glow = glow || {};` `4614 var s = {` `4615 width: (glow.width || 10) + (+this.attr("stroke-width") || 1),` `4616 fill: glow.fill || false,` `4617 opacity: glow.opacity || .5,` `4618 offsetx: glow.offsetx || 0,` `4619 offsety: glow.offsety || 0,` `4620 color: glow.color || "#000"` `4621 },` `4622 c = s.width / 2,` `4623 r = this.paper,` `4624 out = r.set(),` `4625 path = this.realPath || getPath[this.type](this);` `4626 path = this.matrix ? mapPath(path, this.matrix) : path;` `4627 for (var i = 1; i < c + 1; i++) {` `4628 out.push(r.path(path).attr({` `4629 stroke: s.color,` `4630 fill: s.fill ? s.color : "none",` `4631 "stroke-linejoin": "round",` `4632 "stroke-linecap": "round",` `4633 "stroke-width": +(s.width / c * i).toFixed(3),` `4634 opacity: +(s.opacity / c).toFixed(3)` `4635 }));` `4636 }` `4637 return out.insertBefore(this).translate(s.offsetx, s.offsety);` `4638 };` `4639 var curveslengths = {},` `4640 getPointAtSegmentLength = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) {` `4641 var len = 0,` `4642 precision = 100,` `4643 name = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y].join(),` `4644 cache = curveslengths[name],` `4645 old, dot;` `4646 !cache && (curveslengths[name] = cache = {data: []});` `4647 cache.timer && clearTimeout(cache.timer);` `4648 cache.timer = setTimeout(function () {delete curveslengths[name];}, 2e3);` `4649 if (length != null && !cache.precision) {` `4650 var total = getPointAtSegmentLength(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y);` `4651 cache.precision = ~~total * 10;` `4652 cache.data = [];` `4653 }` `4654 precision = cache.precision || precision;` `4655 for (var i = 0; i < precision + 1; i++) {` `4656 if (cache.data[i * precision]) {` `4657 dot = cache.data[i * precision];` `4658 } else {` `4659 dot = R.findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, i / precision);` `4660 cache.data[i * precision] = dot;` `4661 }` `4662 i && (len += pow(pow(old.x - dot.x, 2) + pow(old.y - dot.y, 2), .5));` `4663 if (length != null && len >= length) {` `4664 return dot;` `4665 }` `4666 old = dot;` `4667 }` `4668 if (length == null) {` `4669 return len;` `4670 }` `4671 },` `4672 getLengthFactory = function (istotal, subpath) {` `4673 return function (path, length, onlystart) {` `4674 path = path2curve(path);` `4675 var x, y, p, l, sp = "", subpaths = {}, point,` `4676 len = 0;` `4677 for (var i = 0, ii = path.length; i < ii; i++) {` `4678 p = path[i];` `4679 if (p[0] == "M") {` `4680 x = +p[1];` `4681 y = +p[2];` `4682 } else {` `4683 l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);` `4684 if (len + l > length) {` `4685 if (subpath && !subpaths.start) {` `4686 point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);` `4687 sp += ["C" + point.start.x, point.start.y, point.m.x, point.m.y, point.x, point.y];` `4688 if (onlystart) {return sp;}` `4689 subpaths.start = sp;` `4690 sp = ["M" + point.x, point.y + "C" + point.n.x, point.n.y, point.end.x, point.end.y, p[5], p[6]].join();` `4691 len += l;` `4692 x = +p[5];` `4693 y = +p[6];` `4694 continue;` `4695 }` `4696 if (!istotal && !subpath) {` `4697 point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);` `4698 return {x: point.x, y: point.y, alpha: point.alpha};` `4699 }` `4700 }` `4701 len += l;` `4702 x = +p[5];` `4703 y = +p[6];` `4704 }` `4705 sp += p.shift() + p;` `4706 }` `4707 subpaths.end = sp;` `4708 point = istotal ? len : subpath ? subpaths : R.findDotsAtSegment(x, y, p[1], p[2], p[3], p[4], p[5], p[6], 1);` `4709 point.alpha && (point = {x: point.x, y: point.y, alpha: point.alpha});` `4710 return point;` `4711 };` `4712 };` `4713 var getTotalLength = getLengthFactory(1),` `4714 getPointAtLength = getLengthFactory(),` `4715 getSubpathsAtLength = getLengthFactory(0, 1);` `4716 /*\` `4717 * Raphael.getTotalLength` `4718 [ method ]` `4719 **` `4720 * Returns length of the given path in pixels.` `4721 **` `4722 > Parameters` `4723 **` `4724 - path (string) SVG path string.` `4725 **` `4726 = (number) length.` `4727 \*/` `4728 R.getTotalLength = getTotalLength;` `4729 /*\` `4730 * Raphael.getPointAtLength` `4731 [ method ]` `4732 **` `4733 * Return coordinates of the point located at the given length on the given path.` `4734 **` `4735 > Parameters` `4736 **` `4737 - path (string) SVG path string` `4738 - length (number)` `4739 **` `4740 = (object) representation of the point:` `4741 o {` `4742 o x: (number) x coordinate` `4743 o y: (number) y coordinate` `4744 o alpha: (number) angle of derivative` `4745 o }` `4746 \*/` `4747 R.getPointAtLength = getPointAtLength;` `4748 /*\` `4749 * Raphael.getSubpath` `4750 [ method ]` `4751 **` `4752 * Return subpath of a given path from given length to given length.` `4753 **` `4754 > Parameters` `4755 **` `4756 - path (string) SVG path string` `4757 - from (number) position of the start of the segment` `4758 - to (number) position of the end of the segment` `4759 **` `4760 = (string) pathstring for the segment` `4761 \*/` `4762 R.getSubpath = function (path, from, to) {` `4763 if (abs(this.getTotalLength(path) - to) < 1e-6) {` `4764 return getSubpathsAtLength(path, from).end;` `4765 }` `4766 var a = getSubpathsAtLength(path, to, 1);` `4767 return from ? getSubpathsAtLength(a, from).end : a;` `4768 };` `4769 /*\` `4770 * Element.getTotalLength` `4771 [ method ]` `4772 **` `4773 * Returns length of the path in pixels. Only works for element of “path” type.` `4774 = (number) length.` `4775 \*/` `4776 elproto.getTotalLength = function () {` `4777 if (this.type != "path") {return;}` `4778 if (this.node.getTotalLength) {` `4779 return this.node.getTotalLength();` `4780 }` `4781 return getTotalLength(this.attrs.path);` `4782 };` `4783 /*\` `4784 * Element.getPointAtLength` `4785 [ method ]` `4786 **` `4787 * Return coordinates of the point located at the given length on the given path. Only works for element of “path” type.` `4788 **` `4789 > Parameters` `4790 **` `4791 - length (number)` `4792 **` `4793 = (object) representation of the point:` `4794 o {` `4795 o x: (number) x coordinate` `4796 o y: (number) y coordinate` `4797 o alpha: (number) angle of derivative` `4798 o }` `4799 \*/` `4800 elproto.getPointAtLength = function (length) {` `4801 if (this.type != "path") {return;}` `4802 return getPointAtLength(this.attrs.path, length);` `4803 };` `4804 /*\` `4805 * Element.getSubpath` `4806 [ method ]` `4807 **` `4808 * Return subpath of a given element from given length to given length. Only works for element of “path” type.` `4809 **` `4810 > Parameters` `4811 **` `4812 - from (number) position of the start of the segment` `4813 - to (number) position of the end of the segment` `4814 **` `4815 = (string) pathstring for the segment` `4816 \*/` `4817 elproto.getSubpath = function (from, to) {` `4818 if (this.type != "path") {return;}` `4819 return R.getSubpath(this.attrs.path, from, to);` `4820 };` `4821 /*\` `4822 * Raphael.easing_formulas` `4823 [ property ]` `4824 **` `4825 * Object that contains easing formulas for animation. You could extend it with your own. By default it has following list of easing:` `4826 # <ul>` `4827 # <li>“linear”</li>` `4828 # <li>“<” or “easeIn” or “ease-in”</li>` `4829 # <li>“>” or “easeOut” or “ease-out”</li>` `4830 # <li>“<>” or “easeInOut” or “ease-in-out”</li>` `4831 # <li>“backIn” or “back-in”</li>` `4832 # <li>“backOut” or “back-out”</li>` `4833 # <li>“elastic”</li>` `4834 # <li>“bounce”</li>` `4835 # </ul>` `4836 # <p>See also <a href="http://raphaeljs.com/easing.html">Easing demo</a>.</p>` `4837 \*/` `4838 var ef = R.easing_formulas = {` `4839 linear: function (n) {` `4840 return n;` `4841 },` `4842 "<": function (n) {` `4843 return pow(n, 1.7);` `4844 },` `4845 ">": function (n) {` `4846 return pow(n, .48);` `4847 },` `4848 "<>": function (n) {` `4849 var q = .48 - n / 1.04,` `4850 Q = math.sqrt(.1734 + q * q),` `4851 x = Q - q,` `4852 X = pow(abs(x), 1 / 3) * (x < 0 ? -1 : 1),` `4853 y = -Q - q,` `4854 Y = pow(abs(y), 1 / 3) * (y < 0 ? -1 : 1),` `4855 t = X + Y + .5;` `4856 return (1 - t) * 3 * t * t + t * t * t;` `4857 },` `4858 backIn: function (n) {` `4859 var s = 1.70158;` `4860 return n * n * ((s + 1) * n - s);` `4861 },` `4862 backOut: function (n) {` `4863 n = n - 1;` `4864 var s = 1.70158;` `4865 return n * n * ((s + 1) * n + s) + 1;` `4866 },` `4867 elastic: function (n) {` `4868 if (n == !!n) {` `4869 return n;` `4870 }` `4871 return pow(2, -10 * n) * math.sin((n - .075) * (2 * PI) / .3) + 1;` `4872 },` `4873 bounce: function (n) {` `4874 var s = 7.5625,` `4875 p = 2.75,` `4876 l;` `4877 if (n < (1 / p)) {` `4878 l = s * n * n;` `4879 } else {` `4880 if (n < (2 / p)) {` `4881 n -= (1.5 / p);` `4882 l = s * n * n + .75;` `4883 } else {` `4884 if (n < (2.5 / p)) {` `4885 n -= (2.25 / p);` `4886 l = s * n * n + .9375;` `4887 } else {` `4888 n -= (2.625 / p);` `4889 l = s * n * n + .984375;` `4890 }` `4891 }` `4892 }` `4893 return l;` `4894 }` `4895 };` `4896 ef.easeIn = ef["ease-in"] = ef["<"];` `4897 ef.easeOut = ef["ease-out"] = ef[">"];` `4898 ef.easeInOut = ef["ease-in-out"] = ef["<>"];` `4899 ef["back-in"] = ef.backIn;` `4900 ef["back-out"] = ef.backOut;` `4901` `4902 var animationElements = [],` `4903 requestAnimFrame = window.requestAnimationFrame ||` `4904 window.webkitRequestAnimationFrame ||` `4905 window.mozRequestAnimationFrame ||` `4906 window.oRequestAnimationFrame ||` `4907 window.msRequestAnimationFrame ||` `4908 function (callback) {` `4909 setTimeout(callback, 16);` `4910 },` `4911 animation = function () {` `4912 var Now = +new Date,` `4913 l = 0;` `4914 for (; l < animationElements.length; l++) {` `4915 var e = animationElements[l];` `4916 if (e.el.removed || e.paused) {` `4917 continue;` `4918 }` `4919 var time = Now - e.start,` `4920 ms = e.ms,` `4921 easing = e.easing,` `4922 from = e.from,` `4923 diff = e.diff,` `4924 to = e.to,` `4925 t = e.t,` `4926 that = e.el,` `4927 set = {},` `4928 now;` `4929 if (e.initstatus) {` `4930 time = (e.initstatus * e.anim.top - e.prev) / (e.percent - e.prev) * ms;` `4931 e.status = e.initstatus;` `4932 delete e.initstatus;` `4933 e.stop && animationElements.splice(l--, 1);` `4934 } else {` `4935 e.status = (e.prev + (e.percent - e.prev) * (time / ms)) / e.anim.top;` `4936 }` `4937 if (time < 0) {` `4938 continue;` `4939 }` `4940 if (time < ms) {` `4941 var pos = easing(time / ms);` `4942 for (var attr in from) if (from[has](attr)) {` `4943 switch (availableAnimAttrs[attr]) {` `4944 case nu:` `4945 now = +from[attr] + pos * ms * diff[attr];` `4946 break;` `4947 case "colour":` `4948 now = "rgb(" + [` `4949 upto255(round(from[attr].r + pos * ms * diff[attr].r)),` `4950 upto255(round(from[attr].g + pos * ms * diff[attr].g)),` `4951 upto255(round(from[attr].b + pos * ms * diff[attr].b))` `4952 ].join(",") + ")";` `4953 break;` `4954 case "path":` `4955 now = [];` `4956 for (var i = 0, ii = from[attr].length; i < ii; i++) {` `4957 now[i] = [from[attr][i][0]];` `4958 for (var j = 1, jj = from[attr][i].length; j < jj; j++) {` `4959 now[i][j] = +from[attr][i][j] + pos * ms * diff[attr][i][j];` `4960 }` `4961 now[i] = now[i].join(S);` `4962 }` `4963 now = now.join(S);` `4964 break;` `4965 case "transform":` `4966 if (diff[attr].real) {` `4967 now = [];` `4968 for (i = 0, ii = from[attr].length; i < ii; i++) {` `4969 now[i] = [from[attr][i][0]];` `4970 for (j = 1, jj = from[attr][i].length; j < jj; j++) {` `4971 now[i][j] = from[attr][i][j] + pos * ms * diff[attr][i][j];` `4972 }` `4973 }` `4974 } else {` `4975 var get = function (i) {` `4976 return +from[attr][i] + pos * ms * diff[attr][i];` `4977 };` `4978 // now = [["r", get(2), 0, 0], ["t", get(3), get(4)], ["s", get(0), get(1), 0, 0]];` `4979 now = [["m", get(0), get(1), get(2), get(3), get(4), get(5)]];` `4980 }` `4981 break;` `4982 case "csv":` `4983 if (attr == "clip-rect") {` `4984 now = [];` `4985 i = 4;` `4986 while (i--) {` `4987 now[i] = +from[attr][i] + pos * ms * diff[attr][i];` `4988 }` `4989 }` `4990 break;` `4991 default:` `4992 var from2 = [].concat(from[attr]);` `4993 now = [];` `4994 i = that.paper.customAttributes[attr].length;` `4995 while (i--) {` `4996 now[i] = +from2[i] + pos * ms * diff[attr][i];` `4997 }` `4998 break;` `4999 }` `5000 set[attr] = now;` `5001 }` `5002 that.attr(set);` `5003 (function (id, that, anim) {` `5004 setTimeout(function () {` `5005 eve("anim.frame." + id, that, anim);` `5006 });` `5007 })(that.id, that, e.anim);` `5008 } else {` `5009 (function(f, el, a) {` `5010 setTimeout(function() {` `5011 eve("anim.finish." + el.id, el, a);` `5012 R.is(f, "function") && f.call(el);` `5013 });` `5014 })(e.callback, that, e.anim);` `5015 console.log(e.repeat);` `5016 if (--e.repeat) {` `5017 that.attr(e.origin);` `5018 e.start = Now;` `5019 } else {` `5020 that.attr(to);` `5021 animationElements.splice(l--, 1);` `5022 }` `5023 if (e.next && !e.stop) {` `5024 runAnimation(e.anim, e.el, e.next, null, e.totalOrigin);` `5025 }` `5026 }` `5027 }` `5028 R.svg && that && that.paper && that.paper.safari();` `5029 animationElements.length && requestAnimFrame(animation);` `5030 },` `5031 upto255 = function (color) {` `5032 return mmax(mmin(color, 255), 0);` `5033 };` `5034 /*\` `5035 * Element.animateWith` `5036 [ method ]` `5037 **` `5038 * Acts similar to @Element.animate, but ensure that given animation runs in sync with another given element.` `5039 **` `5040 > Parameters` `5041 **` `5042 - params (object) final attributes for the element, see also @Element.attr` `5043 - ms (number) number of milliseconds for animation to run` `5044 - easing (string) #optional easing type. Accept on of @Raphael.easing_formulas or CSS format: `cubic‐bezier(XX,&#160;XX,&#160;XX,&#160;XX)`` `5045 - callback (function) #optional callback function. Will be called at the end of animation.` `5046 * or` `5047 - animation (object) animation object, see @Raphael.animation` `5048 **` `5049 = (object) original element` `5050 \*/` `5051 elproto.animateWith = function (element, params, ms, easing, callback) {` `5052 this.animate(params, ms, easing, callback);` `5053 var start, el;` `5054 for (var i = 0, ii = animationElements.length; i < ii; i++) {` `5055 el = animationElements[i];` `5056 if (el.el.id == element.id) {` `5057 start = el.timestamp;` `5058 } else if (el.el.id == this.id) {` `5059 el.start = start;` `5060 }` `5061 }` `5062 return this.animate(params, ms, easing, callback);` `5063 };` `5064 function CubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration) {` `5065 var cx = 3 * p1x,` `5066 bx = 3 * (p2x - p1x) - cx,` `5067 ax = 1 - cx - bx,` `5068 cy = 3 * p1y,` `5069 by = 3 * (p2y - p1y) - cy,` `5070 ay = 1 - cy - by;` `5071 function sampleCurveX(t) {` `5072 return ((ax * t + bx) * t + cx) * t;` `5073 }` `5074 function solve(x, epsilon) {` `5075 var t = solveCurveX(x, epsilon);` `5076 return ((ay * t + by) * t + cy) * t;` `5077 }` `5078 function solveCurveX(x, epsilon) {` `5079 var t0, t1, t2, x2, d2, i;` `5080 for(t2 = x, i = 0; i < 8; i++) {` `5081 x2 = sampleCurveX(t2) - x;` `5082 if (abs(x2) < epsilon) {` `5083 return t2;` `5084 }` `5085 d2 = (3 * ax * t2 + 2 * bx) * t2 + cx;` `5086 if (abs(d2) < 1e-6) {` `5087 break;` `5088 }` `5089 t2 = t2 - x2 / d2;` `5090 }` `5091 t0 = 0;` `5092 t1 = 1;` `5093 t2 = x;` `5094 if (t2 < t0) {` `5095 return t0;` `5096 }` `5097 if (t2 > t1) {` `5098 return t1;` `5099 }` `5100 while (t0 < t1) {` `5101 x2 = sampleCurveX(t2);` `5102 if (abs(x2 - x) < epsilon) {` `5103 return t2;` `5104 }` `5105 if (x > x2) {` `5106 t0 = t2;` `5107 } else {` `5108 t1 = t2;` `5109 }` `5110 t2 = (t1 - t0) / 2 + t0;` `5111 }` `5112 return t2;` `5113 }` `5114 return solve(t, 1 / (200 * duration));` `5115 }` `5116 elproto.onAnimation = function (f) {` `5117 f ? eve.on("anim.frame." + this.id, f) : eve.unbind("anim.frame." + this.id);` `5118 return this;` `5119 };` `5120 function Animation(anim, ms) {` `5121 var percents = [];` `5122 this.anim = anim;` `5123 this.ms = ms;` `5124 this.times = 1;` `5125 if (this.anim) {` `5126 for (var attr in this.anim) if (this.anim[has](attr)) {` `5127 percents.push(+attr);` `5128 }` `5129 percents.sort(sortByNumber);` `5130 }` `5131 this.top = percents[percents.length - 1];` `5132 this.percents = percents;` `5133 }` `5134 /*\` `5135 * Animation.delay` `5136 [ method ]` `5137 **` `5138 * Creates a copy of existing animation object with given delay.` `5139 **` `5140 > Parameters` `5141 **` `5142 - delay (number) number of ms to pass between animation start and actual animation` `5143 **` `5144 = (object) new altered Animation object` `5145 \*/` `5146 Animation.prototype.delay = function (delay) {` `5147 var a = new Animation(this.anim, this.ms);` `5148 a.times = this.times;` `5149 a.del = +delay || 0;` `5150 return a;` `5151 };` `5152 /*\` `5153 * Animation.repeat` `5154 [ method ]` `5155 **` `5156 * Creates a copy of existing animation object with given repetition.` `5157 **` `5158 > Parameters` `5159 **` `5160 - repeat (number) number iterations of animation. For infinite animation pass `Infinity`` `5161 **` `5162 = (object) new altered Animation object` `5163 \*/` `5164 Animation.prototype.repeat = function (times) {` `5165 var a = new Animation(this.anim, this.ms);` `5166 a.del = this.del;` `5167 a.times = math.floor(mmax(times, 0)) || 1;` `5168 return a;` `5169 };` `5170 function runAnimation(anim, element, percent, status, totalOrigin) {` `5171 percent = toFloat(percent);` `5172 var params,` `5173 isInAnim,` `5174 isInAnimSet,` `5175 percents = [],` `5176 next,` `5177 prev,` `5178 timestamp,` `5179 ms = anim.ms,` `5180 from = {},` `5181 to = {},` `5182 diff = {};` `5183 if (status) {` `5184 for (i = 0, ii = animationElements.length; i < ii; i++) {` `5185 var e = animationElements[i];` `5186 if (e.el.id == element.id && e.anim == anim) {` `5187 if (e.percent != percent) {` `5188 animationElements.splice(i, 1);` `5189 isInAnimSet = 1;` `5190 } else {` `5191 isInAnim = e;` `5192 }` `5193 element.attr(e.totalOrigin);` `5194 break;` `5195 }` `5196 }` `5197 } else {` `5198 status = +to; // NaN` `5199 }` `5200 for (var i = 0, ii = anim.percents.length; i < ii; i++) {` `5201 if (anim.percents[i] == percent || anim.percents[i] > status * anim.top) {` `5202 percent = anim.percents[i];` `5203 prev = anim.percents[i - 1] || 0;` `5204 ms = ms / anim.top * (percent - prev);` `5205 next = anim.percents[i + 1];` `5206 params = anim.anim[percent];` `5207 break;` `5208 } else if (status) {` `5209 element.attr(anim.anim[anim.percents[i]]);` `5210 }` `5211 }` `5212 if (!params) {` `5213 return;` `5214 }` `5215 if (!isInAnim) {` `5216 for (attr in params) if (params[has](attr)) {` `5217 if (availableAnimAttrs[has](attr) || element.paper.customAttributes[has](attr)) {` `5218 from[attr] = element.attr(attr);` `5219 (from[attr] == null) && (from[attr] = availableAttrs[attr]);` `5220 to[attr] = params[attr];` `5221 switch (availableAnimAttrs[attr]) {` `5222 case nu:` `5223 diff[attr] = (to[attr] - from[attr]) / ms;` `5224 break;` `5225 case "colour":` `5226 from[attr] = R.getRGB(from[attr]);` `5227 var toColour = R.getRGB(to[attr]);` `5228 diff[attr] = {` `5229 r: (toColour.r - from[attr].r) / ms,` `5230 g: (toColour.g - from[attr].g) / ms,` `5231 b: (toColour.b - from[attr].b) / ms` `5232 };` `5233 break;` `5234 case "path":` `5235 var pathes = path2curve(from[attr], to[attr]),` `5236 toPath = pathes[1];` `5237 from[attr] = pathes[0];` `5238 diff[attr] = [];` `5239 for (i = 0, ii = from[attr].length; i < ii; i++) {` `5240 diff[attr][i] = [0];` `5241 for (var j = 1, jj = from[attr][i].length; j < jj; j++) {` `5242 diff[attr][i][j] = (toPath[i][j] - from[attr][i][j]) / ms;` `5243 }` `5244 }` `5245 break;` `5246 case "transform":` `5247 var _ = element._,` `5248 eq = equaliseTransform(_[attr], to[attr]);` `5249 if (eq) {` `5250 from[attr] = eq.from;` `5251 to[attr] = eq.to;` `5252 diff[attr] = [];` `5253 diff[attr].real = true;` `5254 for (i = 0, ii = from[attr].length; i < ii; i++) {` `5255 diff[attr][i] = [from[attr][i][0]];` `5256 for (j = 1, jj = from[attr][i].length; j < jj; j++) {` `5257 diff[attr][i][j] = (to[attr][i][j] - from[attr][i][j]) / ms;` `5258 }` `5259 }` `5260 } else {` `5261 var m = (element.matrix || new Matrix).m,` `5262 to2 = {_:{transform: _.transform}, getBBox: function () { return element.getBBox(); }};` `5263 from[attr] = [` `5264 m[0][0],` `5265 m[1][0],` `5266 m[0][1],` `5267 m[1][1],` `5268 m[0][2],` `5269 m[1][2]` `5270 ];` `5271 extractTransform(to2, to[attr]);` `5272 to[attr] = to2._.transform;` `5273 diff[attr] = [` `5274 (to2.matrix.m[0][0] - m[0][0]) / ms,` `5275 (to2.matrix.m[1][0] - m[1][0]) / ms,` `5276 (to2.matrix.m[0][1] - m[0][1]) / ms,` `5277 (to2.matrix.m[1][1] - m[1][1]) / ms,` `5278 (to2.matrix.m[0][2] - m[0][2]) / ms,` `5279 (to2.matrix.m[1][2] - m[1][2]) / ms` `5280 ];` `5281 // from[attr] = [_.sx, _.sy, _.deg, _.dx, _.dy];` `5282 // var to2 = {_:{}, getBBox: function () { return element.getBBox(); }};` `5283 // extractTransform(to2, to[attr]);` `5284 // diff[attr] = [` `5285 // (to2._.sx - _.sx) / ms,` `5286 // (to2._.sy - _.sy) / ms,` `5287 // (to2._.deg - _.deg) / ms,` `5288 // (to2._.dx - _.dx) / ms,` `5289 // (to2._.dy - _.dy) / ms` `5290 // ];` `5291 }` `5292 break;` `5293 case "csv":` `5294 var values = Str(params[attr]).split(separator),` `5295 from2 = Str(from[attr]).split(separator);` `5296 if (attr == "clip-rect") {` `5297 from[attr] = from2;` `5298 diff[attr] = [];` `5299 i = from2.length;` `5300 while (i--) {` `5301 diff[attr][i] = (values[i] - from[attr][i]) / ms;` `5302 }` `5303 }` `5304 to[attr] = values;` `5305 break;` `5306 default:` `5307 values = [].concat(params[attr]);` `5308 from2 = [].concat(from[attr]);` `5309 diff[attr] = [];` `5310 i = element.paper.customAttributes[attr].length;` `5311 while (i--) {` `5312 diff[attr][i] = ((values[i] || 0) - (from2[i] || 0)) / ms;` `5313 }` `5314 break;` `5315 }` `5316 }` `5317 }` `5318 var easing = params.easing,` `5319 easyeasy = R.easing_formulas[easing];` `5320 if (!easyeasy) {` `5321 easyeasy = Str(easing).match(bezierrg);` `5322 if (easyeasy && easyeasy.length == 5) {` `5323 var curve = easyeasy;` `5324 easyeasy = function (t) {` `5325 return CubicBezierAtTime(t, +curve[1], +curve[2], +curve[3], +curve[4], ms);` `5326 };` `5327 } else {` `5328 easyeasy = pipe;` `5329 }` `5330 }` `5331 timestamp = params.start || anim.start || +new Date;` `5332 e = {` `5333 anim: anim,` `5334 percent: percent,` `5335 timestamp: timestamp,` `5336 start: timestamp + (anim.del || 0),` `5337 status: 0,` `5338 initstatus: status || 0,` `5339 stop: false,` `5340 ms: ms,` `5341 easing: easyeasy,` `5342 from: from,` `5343 diff: diff,` `5344 to: to,` `5345 el: element,` `5346 callback: params.callback,` `5347 prev: prev,` `5348 next: next,` `5349 repeat: anim.times,` `5350 origin: element.attr(),` `5351 totalOrigin: totalOrigin` `5352 };` `5353 animationElements.push(e);` `5354 if (status && !isInAnim) {` `5355 e.stop = true;` `5356 e.start = new Date - ms * status;` `5357 if (animationElements.length == 1) {` `5358 return animation();` `5359 }` `5360 }` `5361 animationElements.length == 1 && requestAnimFrame(animation);` `5362 } else {` `5363 isInAnim.initstatus = status;` `5364 isInAnim.start = new Date - isInAnim.ms * status;` `5365 }` `5366 eve("anim.start." + element.id, element, anim);` `5367 }` `5368 /*\` `5369 * Raphael.animation` `5370 [ method ]` `5371 **` `5372 * Creates an animation object that can be passed to the @Element.animate or @Element.animateWith methods.` `5373 * See also @Animation.delay and @Animation.repeat methods.` `5374 **` `5375 > Parameters` `5376 **` `5377 - params (object) final attributes for the element, see also @Element.attr` `5378 - ms (number) number of milliseconds for animation to run` `5379 - easing (string) #optional easing type. Accept one of @Raphael.easing_formulas or CSS format: `cubic‐bezier(XX,&#160;XX,&#160;XX,&#160;XX)`` `5380 - callback (function) #optional callback function. Will be called at the end of animation.` `5381 **` `5382 = (object) @Animation` `5383 \*/` `5384 R.animation = function (params, ms, easing, callback) {` `5385 if (R.is(easing, "function") || !easing) {` `5386 callback = callback || easing || null;` `5387 easing = null;` `5388 }` `5389 params = Object(params);` `5390 ms = +ms || 0;` `5391 var p = {},` `5392 json,` `5393 attr;` `5394 for (attr in params) if (params[has](attr) && toFloat(attr) != attr) {` `5395 json = true;` `5396 p[attr] = params[attr];` `5397 }` `5398 if (!json) {` `5399 return new Animation(params, ms);` `5400 } else {` `5401 easing && (p.easing = easing);` `5402 callback && (p.callback = callback);` `5403 return new Animation({100: p}, ms);` `5404 }` `5405 };` `5406 /*\` `5407 * Element.animate` `5408 [ method ]` `5409 **` `5410 * Creates and starts animation for given element.` `5411 **` `5412 > Parameters` `5413 **` `5414 - params (object) final attributes for the element, see also @Element.attr` `5415 - ms (number) number of milliseconds for animation to run` `5416 - easing (string) #optional easing type. Accept one of @Raphael.easing_formulas or CSS format: `cubic‐bezier(XX,&#160;XX,&#160;XX,&#160;XX)`` `5417 - callback (function) #optional callback function. Will be called at the end of animation.` `5418 * or` `5419 - animation (object) animation object, see @Raphael.animation` `5420 **` `5421 = (object) original element` `5422 \*/` `5423 elproto.animate = function (params, ms, easing, callback) {` `5424 var element = this;` `5425 if (element.removed) {` `5426 callback && callback.call(element);` `5427 return element;` `5428 }` `5429 var anim = params instanceof Animation ? params : R.animation(params, ms, easing, callback);` `5430 runAnimation(anim, element, anim.percents[0], null, element.attr());` `5431 return element;` `5432 };` `5433 /*\` `5434 * Element.setTime` `5435 [ method ]` `5436 **` `5437 * Sets the status of animation of the element in milliseconds. Similar to @Element.status method.` `5438 **` `5439 > Parameters` `5440 **` `5441 - anim (object) animation object` `5442 - value (number) number of milliseconds from the beginning of the animation` `5443 **` `5444 = (object) original element if `value` is specified` `5445 * Note, that during animation following events are triggered:` `5446 *` `5447 * On each animation frame event `anim.frame.<id>`, on start `anim.start.<id>` and on end `anim.finish.<id>`.` `5448 \*/` `5449 elproto.setTime = function (anim, value) {` `5450 if (anim && value != null) {` `5451 this.status(anim, mmin(value, anim.ms) / anim.ms);` `5452 }` `5453 return this;` `5454 };` `5455 /*\` `5456 * Element.status` `5457 [ method ]` `5458 **` `5459 * Gets or sets the status of animation of the element.` `5460 **` `5461 > Parameters` `5462 **` `5463 - anim (object) #optional animation object` `5464 - value (number) #optional 0 – 1. If specified, method works like a setter and sets the status of a given animation to the value. This will cause animation to jump to the given position.` `5465 **` `5466 = (number) status` `5467 * or` `5468 = (array) status if `anim` is not specified. Array of objects in format:` `5469 o {` `5470 o anim: (object) animation object` `5471 o status: (number) status` `5472 o }` `5473 * or` `5474 = (object) original element if `value` is specified` `5475 \*/` `5476 elproto.status = function (anim, value) {` `5477 var out = [],` `5478 i = 0,` `5479 len,` `5480 e;` `5481 if (value != null) {` `5482 runAnimation(anim, this, -1, mmin(value, 1));` `5483 return this;` `5484 } else {` `5485 len = animationElements.length;` `5486 for (; i < len; i++) {` `5487 e = animationElements[i];` `5488 if (e.el.id == this.id && (!anim || e.anim == anim)) {` `5489 if (anim) {` `5490 return e.status;` `5491 }` `5492 out.push({anim: e.anim, status: e.status});` `5493 }` `5494 }` `5495 if (anim) {` `5496 return 0;` `5497 }` `5498 return out;` `5499 }` `5500 };` `5501 /*\` `5502 * Element.pause` `5503 [ method ]` `5504 **` `5505 * Stops animation of the element with ability to resume it later on.` `5506 **` `5507 > Parameters` `5508 **` `5509 - anim (object) #optional animation object` `5510 **` `5511 = (object) original element` `5512 \*/` `5513 elproto.pause = function (anim) {` `5514 for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {` `5515 if (eve("anim.pause." + this.id, this, animationElements[i].anim) !== false) {` `5516 animationElements[i].paused = true;` `5517 }` `5518 }` `5519 return this;` `5520 };` `5521 /*\` `5522 * Element.resume` `5523 [ method ]` `5524 **` `5525 * Resumes animation if it was paused with @Element.pause method.` `5526 **` `5527 > Parameters` `5528 **` `5529 - anim (object) #optional animation object` `5530 **` `5531 = (object) original element` `5532 \*/` `5533 elproto.resume = function (anim) {` `5534 for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {` `5535 var e = animationElements[i];` `5536 if (eve("anim.resume." + this.id, this, e.anim) !== false) {` `5537 delete e.paused;` `5538 this.status(e.anim, e.status);` `5539 }` `5540 }` `5541 return this;` `5542 };` `5543 /*\` `5544 * Element.stop` `5545 [ method ]` `5546 **` `5547 * Stops animation of the element.` `5548 **` `5549 > Parameters` `5550 **` `5551 - anim (object) #optional animation object` `5552 **` `5553 = (object) original element` `5554 \*/` `5555 elproto.stop = function (anim) {` `5556 for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {` `5557 if (eve("anim.stop." + this.id, this, animationElements[i].anim) !== false) {` `5558 animationElements.splice(i--, 1);` `5559 }` `5560 }` `5561 return this;` `5562 };` `5563 elproto.toString = function () {` `5564 return "Rapha\xebl\u2019s object";` `5565 };` `5566` `5567 // Set` `5568 var Set = function (items) {` `5569 this.items = [];` `5570 this.length = 0;` `5571 this.type = "set";` `5572 if (items) {` `5573 for (var i = 0, ii = items.length; i < ii; i++) {` `5574 if (items[i] && (items[i].constructor == Element || items[i].constructor == Set)) {` `5575 this[this.items.length] = this.items[this.items.length] = items[i];` `5576 this.length++;` `5577 }` `5578 }` `5579 }` `5580 },` `5581 setproto = Set.prototype;` `5582 /*\` `5583 * Set.push` `5584 [ method ]` `5585 **` `5586 * Adds each argument to the current set.` `5587 = (object) original element` `5588 \*/` `5589 setproto.push = function () {` `5590 var item,` `5591 len;` `5592 for (var i = 0, ii = arguments.length; i < ii; i++) {` `5593 item = arguments[i];` `5594 if (item && (item.constructor == Element || item.constructor == Set)) {` `5595 len = this.items.length;` `5596 this[len] = this.items[len] = item;` `5597 this.length++;` `5598 }` `5599 }` `5600 return this;` `5601 };` `5602 /*\` `5603 * Set.pop` `5604 [ method ]` `5605 **` `5606 * Removes last element and returns it.` `5607 = (object) element` `5608 \*/` `5609 setproto.pop = function () {` `5610 this.length && delete this[this.length--];` `5611 return this.items.pop();` `5612 };` `5613 /*\` `5614 * Set.forEach` `5615 [ method ]` `5616 **` `5617 * Executes given function for each element in the set.` `5618 *` `5619 * If function returns `false` it will stop loop running.` `5620 **` `5621 > Parameters` `5622 **` `5623 - callback (function) function to run` `5624 - thisArg (object) context object for the callback` `5625 = (object) Set object` `5626 \*/` `5627 setproto.forEach = function (callback, thisArg) {` `5628 for (var i = 0, ii = this.items.length; i < ii; i++) {` `5629 if (callback.call(thisArg, this.items[i]) === false) {` `5630 return this;` `5631 }` `5632 }` `5633 return this;` `5634 };` `5635 for (var method in elproto) if (elproto[has](method)) {` `5636 setproto[method] = (function (methodname) {` `5637 return function () {` `5638 var arg = arguments;` `5639 return this.forEach(function (el) {` `5640 el[methodname][apply](el, arg);` `5641 });` `5642 };` `5643 })(method);` `5644 }` `5645 setproto.attr = function (name, value) {` `5646 if (name && R.is(name, array) && R.is(name[0], "object")) {` `5647 for (var j = 0, jj = name.length; j < jj; j++) {` `5648 this.items[j].attr(name[j]);` `5649 }` `5650 } else {` `5651 for (var i = 0, ii = this.items.length; i < ii; i++) {` `5652 this.items[i].attr(name, value);` `5653 }` `5654 }` `5655 return this;` `5656 };` `5657 setproto.animate = function (params, ms, easing, callback) {` `5658 (R.is(easing, "function") || !easing) && (callback = easing || null);` `5659 var len = this.items.length,` `5660 i = len,` `5661 item,` `5662 set = this,` `5663 collector;` `5664 callback && (collector = function () {` `5665 !--len && callback.call(set);` `5666 });` `5667 easing = R.is(easing, string) ? easing : collector;` `5668 var anim = params instanceof Animation ? params : R.animation(params, ms, easing, collector);` `5669 item = this.items[--i].animate(anim);` `5670 while (i--) {` `5671 this.items[i] && !this.items[i].removed && this.items[i].animateWith(item, anim);` `5672 }` `5673 return this;` `5674 };` `5675 setproto.insertAfter = function (el) {` `5676 var i = this.items.length;` `5677 while (i--) {` `5678 this.items[i].insertAfter(el);` `5679 }` `5680 return this;` `5681 };` `5682 setproto.getBBox = function () {` `5683 var x = [],` `5684 y = [],` `5685 w = [],` `5686 h = [];` `5687 for (var i = this.items.length; i--;) if (!this.items[i].removed) {` `5688 var box = this.items[i].getBBox();` `5689 x.push(box.x);` `5690 y.push(box.y);` `5691 w.push(box.x + box.width);` `5692 h.push(box.y + box.height);` `5693 }` `5694 x = mmin[apply](0, x);` `5695 y = mmin[apply](0, y);` `5696 return {` `5697 x: x,` `5698 y: y,` `5699 width: mmax[apply](0, w) - x,` `5700 height: mmax[apply](0, h) - y` `5701 };` `5702 };` `5703 setproto.clone = function (s) {` `5704 s = new Set;` `5705 for (var i = 0, ii = this.items.length; i < ii; i++) {` `5706 s.push(this.items[i].clone());` `5707 }` `5708 return s;` `5709 };` `5710 setproto.toString = function () {` `5711 return "Rapha\xebl\u2018s set";` `5712 };` `5713` `5714 R.registerFont = function (font) {` `5715 if (!font.face) {` `5716 return font;` `5717 }` `5718 this.fonts = this.fonts || {};` `5719 var fontcopy = {` `5720 w: font.w,` `5721 face: {},` `5722 glyphs: {}` `5723 },` `5724 family = font.face["font-family"];` `5725 for (var prop in font.face) if (font.face[has](prop)) {` `5726 fontcopy.face[prop] = font.face[prop];` `5727 }` `5728 if (this.fonts[family]) {` `5729 this.fonts[family].push(fontcopy);` `5730 } else {` `5731 this.fonts[family] = [fontcopy];` `5732 }` `5733 if (!font.svg) {` `5734 fontcopy.face["units-per-em"] = toInt(font.face["units-per-em"], 10);` `5735 for (var glyph in font.glyphs) if (font.glyphs[has](glyph)) {` `5736 var path = font.glyphs[glyph];` `5737 fontcopy.glyphs[glyph] = {` `5738 w: path.w,` `5739 k: {},` `5740 d: path.d && "M" + path.d.replace(/[mlcxtrv]/g, function (command) {` `5741 return {l: "L", c: "C", x: "z", t: "m", r: "l", v: "c"}[command] || "M";` `5742 }) + "z"` `5743 };` `5744 if (path.k) {` `5745 for (var k in path.k) if (path[has](k)) {` `5746 fontcopy.glyphs[glyph].k[k] = path.k[k];` `5747 }` `5748 }` `5749 }` `5750 }` `5751 return font;` `5752 };` `5753 paperproto.getFont = function (family, weight, style, stretch) {` `5754 stretch = stretch || "normal";` `5755 style = style || "normal";` `5756 weight = +weight || {normal: 400, bold: 700, lighter: 300, bolder: 800}[weight] || 400;` `5757 if (!R.fonts) {` `5758 return;` `5759 }` `5760 var font = R.fonts[family];` `5761 if (!font) {` `5762 var name = new RegExp("(^|\\s)" + family.replace(/[^\w\d\s+!~.:_-]/g, E) + "(\\s|$)", "i");` `5763 for (var fontName in R.fonts) if (R.fonts[has](fontName)) {` `5764 if (name.test(fontName)) {` `5765 font = R.fonts[fontName];` `5766 break;` `5767 }` `5768 }` `5769 }` `5770 var thefont;` `5771 if (font) {` `5772 for (var i = 0, ii = font.length; i < ii; i++) {` `5773 thefont = font[i];` `5774 if (thefont.face["font-weight"] == weight && (thefont.face["font-style"] == style || !thefont.face["font-style"]) && thefont.face["font-stretch"] == stretch) {` `5775 break;` `5776 }` `5777 }` `5778 }` `5779 return thefont;` `5780 };` `5781 paperproto.print = function (x, y, string, font, size, origin, letter_spacing) {` `5782 origin = origin || "middle"; // baseline|middle` `5783 letter_spacing = mmax(mmin(letter_spacing || 0, 1), -1);` `5784 var out = this.set(),` `5785 letters = Str(string).split(E),` `5786 shift = 0,` `5787 path = E,` `5788 scale;` `5789 R.is(font, string) && (font = this.getFont(font));` `5790 if (font) {` `5791 scale = (size || 16) / font.face["units-per-em"];` `5792 var bb = font.face.bbox.split(separator),` `5793 top = +bb[0],` `5794 height = +bb[1] + (origin == "baseline" ? bb[3] - bb[1] + (+font.face.descent) : (bb[3] - bb[1]) / 2);` `5795 for (var i = 0, ii = letters.length; i < ii; i++) {` `5796 var prev = i && font.glyphs[letters[i - 1]] || {},` `5797 curr = font.glyphs[letters[i]];` `5798 shift += i ? (prev.w || font.w) + (prev.k && prev.k[letters[i]] || 0) + (font.w * letter_spacing) : 0;` `5799 curr && curr.d && out.push(this.path(curr.d).attr({fill: "#000", stroke: "none", transform: [["t", shift, 0]]}));` `5800 }` `5801 out.scale(scale, scale, top, height).translate(x - top, y - height);` `5802 }` `5803 return out;` `5804 };` `5805` `5806 R.format = function (token, params) {` `5807 var args = R.is(params, array) ? [0][concat](params) : arguments;` `5808 token && R.is(token, string) && args.length - 1 && (token = token.replace(formatrg, function (str, i) {` `5809 return args[++i] == null ? E : args[i];` `5810 }));` `5811 return token || E;` `5812 };` `5813 R.ninja = function () {` `5814 oldRaphael.was ? (g.win.Raphael = oldRaphael.is) : delete Raphael;` `5815 return R;` `5816 };` `5817 /*\` `5818 * Raphael.el` `5819 [ property (object) ]` `5820 **` `5821 * You can add your own method to elements. This is usefull when you want to hack default functionality or` `5822 * want to wrap some common transformation or attributes in one method. In difference to canvas methods,` `5823 * you can redefine element method at any time. Expending element methods wouldn’t affect set.` `5824 > Usage` `5825 | Raphael.el.red = function () {` `5826 | this.attr({fill: "#f00"});` `5827 | };` `5828 | // then use it` `5829 | paper.circle(100, 100, 20).red();` `5830 \*/` `5831 R.el = elproto;` `5832 R.st = setproto;` `5833 // Firefox <3.6 fix: http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html` `5834 (function (doc, loaded, f) {` `5835 if (doc.readyState == null && doc.addEventListener){` `5836 doc.addEventListener(loaded, f = function () {` `5837 doc.removeEventListener(loaded, f, false);` `5838 doc.readyState = "complete";` `5839 }, false);` `5840 doc.readyState = "loading";` `5841 }` `5842 function isLoaded() {` `5843 (/in/).test(doc.readyState) ? setTimeout(isLoaded, 9) : eve("DOMload");` `5844 }` `5845 isLoaded();` `5846 })(document, "DOMContentLoaded");` `5847` `5848 oldRaphael.was ? (g.win.Raphael = R) : (Raphael = R);` `5849` `5850 /*` `5851 * Eve 0.2.1 - JavaScript Events Library` `5852 *` `5853 * Copyright (c) 2010 Dmitry Baranovskiy (http://dmitry.baranovskiy.com/)` `5854 * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.` `5855 */` `5856` `5857 var eve = R.eve = (function () {` `5858 var version = "0.2.1",` `5859 has = "hasOwnProperty",` `5860 separator = /[\.\/]/,` `5861 wildcard = "*",` `5862 events = {n: {}},` `5863 eve = function (name, scope) {` `5864 var e = events,` `5865 args = Array.prototype.slice.call(arguments, 2),` `5866 listeners = eve.listeners(name),` `5867 errors = [];` `5868 for (var i = 0, ii = listeners.length; i < ii; i++) {` `5869 try {` `5870 listeners[i].apply(scope, args);` `5871 } catch (ex) {` `5872 errors.push({error: ex && ex.message || ex, func: listeners[i]});` `5873 }` `5874 }` `5875 if (errors.length) {` `5876 return errors;` `5877 }` `5878 };` `5879 eve.listeners = function (name) {` `5880 var names = name.split(separator),` `5881 e = events,` `5882 item,` `5883 items,` `5884 k,` `5885 i,` `5886 ii,` `5887 j,` `5888 jj,` `5889 nes,` `5890 es = [e],` `5891 out = [];` `5892 for (i = 0, ii = names.length; i < ii; i++) {` `5893 nes = [];` `5894 for (j = 0, jj = es.length; j < jj; j++) {` `5895 e = es[j].n;` `5896 items = [e[names[i]], e[wildcard]];` `5897 k = 2;` `5898 while (k--) {` `5899 item = items[k];` `5900 if (item) {` `5901 nes.push(item);` `5902 out = out.concat(item.f || []);` `5903 }` `5904 }` `5905 }` `5906 es = nes;` `5907 }` `5908 return out;` `5909 };` `5910 eve.on = function (name, f) {` `5911 var names = name.split(separator),` `5912 e = events;` `5913 for (var i = 0, ii = names.length; i < ii; i++) {` `5914 e = e.n;` `5915 !e[names[i]] && (e[names[i]] = {n: {}});` `5916 e = e[names[i]];` `5917 }` `5918 e.f = e.f || [];` `5919 for (i = 0, ii = e.f.length; i < ii; i++) if (e.f[i] == f) {` `5920 return false;` `5921 }` `5922 e.f.push(f);` `5923 };` `5924 eve.unbind = function (name, f) {` `5925 var names = name.split(separator),` `5926 e,` `5927 key,` `5928 splice,` `5929 cur = [events];` `5930 for (var i = 0, ii = names.length; i < ii; i++) {` `5931 for (var j = 0; j < cur.length; j += splice.length - 2) {` `5932 splice = [j, 1];` `5933 e = cur[j].n;` `5934 if (names[i] != wildcard) {` `5935 if (e[names[i]]) {` `5936 splice.push(e[names[i]]);` `5937 }` `5938 } else {` `5939 for (key in e) if (e[has](key)) {` `5940 splice.push(e[key]);` `5941 }` `5942 }` `5943 cur.splice.apply(cur, splice);` `5944 }` `5945 }` `5946 for (i = 0, ii = cur.length; i < ii; i++) {` `5947 e = cur[i];` `5948 while (e.n) {` `5949 if (f) {` `5950 if (e.f) {` `5951 for (i = 0, ii = e.f.length; i < ii; i++) if (e.f[i] == f) {` `5952 e.f.splice(i, 1);` `5953 break;` `5954 }` `5955 !e.f.length && delete e.f;` `5956 }` `5957 for (key in e.n) if (e.n[has](key) && e.n[key].f) {` `5958 var funcs = e.n[key].f;` `5959 for (i = 0, ii = funcs.length; i < ii; i++) if (funcs[i] == f) {` `5960 funcs.splice(i, 1);` `5961 break;` `5962 }` `5963 !funcs.length && delete e.n[key].f;` `5964 }` `5965 } else {` `5966 delete e.f;` `5967 for (key in e.n) if (e.n[has](key) && e.n[key].f) {` `5968 delete e.n[key].f;` `5969 }` `5970 }` `5971 e = e.n;` `5972 }` `5973 }` `5974 return true;` `5975 };` `5976 eve.version = version;` `5977 eve.toString = function () {` `5978 return "You are running Eve " + version;` `5979 };` `5980 return eve;` `5981 })();` `5982})();`