raphael-rails 2.1.1 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,21 +1,32 @@
1
1
  // ┌────────────────────────────────────────────────────────────────────┐ \\
2
- // │ Raphaël 2.1.0 - JavaScript Vector Library │ \\
2
+ // │ Raphaël 2.1.2 - JavaScript Vector Library │ \\
3
3
  // ├────────────────────────────────────────────────────────────────────┤ \\
4
4
  // │ Copyright © 2008-2012 Dmitry Baranovskiy (http://raphaeljs.com) │ \\
5
5
  // │ Copyright © 2008-2012 Sencha Labs (http://sencha.com) │ \\
6
6
  // ├────────────────────────────────────────────────────────────────────┤ \\
7
7
  // │ Licensed under the MIT (http://raphaeljs.com/license.html) license.│ \\
8
8
  // └────────────────────────────────────────────────────────────────────┘ \\
9
-
10
- // ┌──────────────────────────────────────────────────────────────────────────────────────┐ \\
11
- // Eve 0.3.4 - JavaScript Events Library │ \\
12
- // ├──────────────────────────────────────────────────────────────────────────────────────┤ \\
13
- // Copyright (c) 2008-2011 Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) │ \\
14
- // │ Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. │ \\
15
- // └──────────────────────────────────────────────────────────────────────────────────────┘ \\
9
+ // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
10
+ //
11
+ // Licensed under the Apache License, Version 2.0 (the "License");
12
+ // you may not use this file except in compliance with the License.
13
+ // You may obtain a copy of the License at
14
+ //
15
+ // http://www.apache.org/licenses/LICENSE-2.0
16
+ //
17
+ // Unless required by applicable law or agreed to in writing, software
18
+ // distributed under the License is distributed on an "AS IS" BASIS,
19
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
+ // See the License for the specific language governing permissions and
21
+ // limitations under the License.
22
+ // ┌────────────────────────────────────────────────────────────┐ \\
23
+ // │ Eve 0.4.2 - JavaScript Events Library │ \\
24
+ // ├────────────────────────────────────────────────────────────┤ \\
25
+ // │ Author Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) │ \\
26
+ // └────────────────────────────────────────────────────────────┘ \\
16
27
 
17
28
  (function (glob) {
18
- var version = "0.3.4",
29
+ var version = "0.4.2",
19
30
  has = "hasOwnProperty",
20
31
  separator = /[\.\/]/,
21
32
  wildcard = "*",
@@ -26,8 +37,22 @@
26
37
  current_event,
27
38
  stop,
28
39
  events = {n: {}},
29
-
40
+ /*\
41
+ * eve
42
+ [ method ]
43
+
44
+ * Fires event with given `name`, given scope and other parameters.
45
+
46
+ > Arguments
47
+
48
+ - name (string) name of the *event*, dot (`.`) or slash (`/`) separated
49
+ - scope (object) context for the event handlers
50
+ - varargs (...) the rest of arguments will be sent to event handlers
51
+
52
+ = (object) array of returned values from the listeners
53
+ \*/
30
54
  eve = function (name, scope) {
55
+ name = String(name);
31
56
  var e = events,
32
57
  oldstop = stop,
33
58
  args = Array.prototype.slice.call(arguments, 2),
@@ -87,7 +112,20 @@
87
112
  current_event = ce;
88
113
  return out.length ? out : null;
89
114
  };
90
-
115
+ // Undocumented. Debug only.
116
+ eve._events = events;
117
+ /*\
118
+ * eve.listeners
119
+ [ method ]
120
+
121
+ * Internal method which gives you array of all event handlers that will be triggered by the given `name`.
122
+
123
+ > Arguments
124
+
125
+ - name (string) name of the event, dot (`.`) or slash (`/`) separated
126
+
127
+ = (array) array of event handlers
128
+ \*/
91
129
  eve.listeners = function (name) {
92
130
  var names = name.split(separator),
93
131
  e = events,
@@ -120,14 +158,40 @@
120
158
  return out;
121
159
  };
122
160
 
123
-
161
+ /*\
162
+ * eve.on
163
+ [ method ]
164
+ **
165
+ * Binds given event handler with a given name. You can use wildcards “`*`” for the names:
166
+ | eve.on("*.under.*", f);
167
+ | eve("mouse.under.floor"); // triggers f
168
+ * Use @eve to trigger the listener.
169
+ **
170
+ > Arguments
171
+ **
172
+ - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
173
+ - f (function) event handler function
174
+ **
175
+ = (function) returned function accepts a single numeric parameter that represents z-index of the handler. It is an optional feature and only used when you need to ensure that some subset of handlers will be invoked in a given order, despite of the order of assignment.
176
+ > Example:
177
+ | eve.on("mouse", eatIt)(2);
178
+ | eve.on("mouse", scream);
179
+ | eve.on("mouse", catchIt)(1);
180
+ * This will ensure that `catchIt()` function will be called before `eatIt()`.
181
+ *
182
+ * If you want to put your handler before non-indexed handlers, specify a negative value.
183
+ * Note: I assume most of the time you don’t need to worry about z-index, but it’s nice to have this feature “just in case”.
184
+ \*/
124
185
  eve.on = function (name, f) {
186
+ name = String(name);
187
+ if (typeof f != "function") {
188
+ return function () {};
189
+ }
125
190
  var names = name.split(separator),
126
191
  e = events;
127
192
  for (var i = 0, ii = names.length; i < ii; i++) {
128
193
  e = e.n;
129
- !e[names[i]] && (e[names[i]] = {n: {}});
130
- e = e[names[i]];
194
+ e = e.hasOwnProperty(names[i]) && e[names[i]] || (e[names[i]] = {n: {}});
131
195
  }
132
196
  e.f = e.f || [];
133
197
  for (i = 0, ii = e.f.length; i < ii; i++) if (e.f[i] == f) {
@@ -140,20 +204,92 @@
140
204
  }
141
205
  };
142
206
  };
143
-
207
+ /*\
208
+ * eve.f
209
+ [ method ]
210
+ **
211
+ * Returns function that will fire given event with optional arguments.
212
+ * Arguments that will be passed to the result function will be also
213
+ * concated to the list of final arguments.
214
+ | el.onclick = eve.f("click", 1, 2);
215
+ | eve.on("click", function (a, b, c) {
216
+ | console.log(a, b, c); // 1, 2, [event object]
217
+ | });
218
+ > Arguments
219
+ - event (string) event name
220
+ - varargs (…) and any other arguments
221
+ = (function) possible event handler function
222
+ \*/
223
+ eve.f = function (event) {
224
+ var attrs = [].slice.call(arguments, 1);
225
+ return function () {
226
+ eve.apply(null, [event, null].concat(attrs).concat([].slice.call(arguments, 0)));
227
+ };
228
+ };
229
+ /*\
230
+ * eve.stop
231
+ [ method ]
232
+ **
233
+ * Is used inside an event handler to stop the event, preventing any subsequent listeners from firing.
234
+ \*/
144
235
  eve.stop = function () {
145
236
  stop = 1;
146
237
  };
147
-
238
+ /*\
239
+ * eve.nt
240
+ [ method ]
241
+ **
242
+ * Could be used inside event handler to figure out actual name of the event.
243
+ **
244
+ > Arguments
245
+ **
246
+ - subname (string) #optional subname of the event
247
+ **
248
+ = (string) name of the event, if `subname` is not specified
249
+ * or
250
+ = (boolean) `true`, if current event’s name contains `subname`
251
+ \*/
148
252
  eve.nt = function (subname) {
149
253
  if (subname) {
150
254
  return new RegExp("(?:\\.|\\/|^)" + subname + "(?:\\.|\\/|$)").test(current_event);
151
255
  }
152
256
  return current_event;
153
257
  };
154
-
155
-
258
+ /*\
259
+ * eve.nts
260
+ [ method ]
261
+ **
262
+ * Could be used inside event handler to figure out actual name of the event.
263
+ **
264
+ **
265
+ = (array) names of the event
266
+ \*/
267
+ eve.nts = function () {
268
+ return current_event.split(separator);
269
+ };
270
+ /*\
271
+ * eve.off
272
+ [ method ]
273
+ **
274
+ * Removes given function from the list of event listeners assigned to given name.
275
+ * If no arguments specified all the events will be cleared.
276
+ **
277
+ > Arguments
278
+ **
279
+ - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
280
+ - f (function) event handler function
281
+ \*/
282
+ /*\
283
+ * eve.unbind
284
+ [ method ]
285
+ **
286
+ * See @eve.off
287
+ \*/
156
288
  eve.off = eve.unbind = function (name, f) {
289
+ if (!name) {
290
+ eve._events = events = {n: {}};
291
+ return;
292
+ }
157
293
  var names = name.split(separator),
158
294
  e,
159
295
  key,
@@ -205,33 +341,113 @@
205
341
  }
206
342
  }
207
343
  };
208
-
344
+ /*\
345
+ * eve.once
346
+ [ method ]
347
+ **
348
+ * Binds given event handler with a given name to only run once then unbind itself.
349
+ | eve.once("login", f);
350
+ | eve("login"); // triggers f
351
+ | eve("login"); // no listeners
352
+ * Use @eve to trigger the listener.
353
+ **
354
+ > Arguments
355
+ **
356
+ - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
357
+ - f (function) event handler function
358
+ **
359
+ = (function) same return function as @eve.on
360
+ \*/
209
361
  eve.once = function (name, f) {
210
362
  var f2 = function () {
211
- var res = f.apply(this, arguments);
212
363
  eve.unbind(name, f2);
213
- return res;
364
+ return f.apply(this, arguments);
214
365
  };
215
366
  return eve.on(name, f2);
216
367
  };
217
-
368
+ /*\
369
+ * eve.version
370
+ [ property (string) ]
371
+ **
372
+ * Current version of the library.
373
+ \*/
218
374
  eve.version = version;
219
375
  eve.toString = function () {
220
376
  return "You are running Eve " + version;
221
377
  };
222
378
  (typeof module != "undefined" && module.exports) ? (module.exports = eve) : (typeof define != "undefined" ? (define("eve", [], function() { return eve; })) : (glob.eve = eve));
223
379
  })(this);
224
-
225
-
226
380
  // ┌─────────────────────────────────────────────────────────────────────┐ \\
227
- // │ "Raphaël 2.1.0" - JavaScript Vector Library │ \\
381
+ // │ "Raphaël 2.1.2" - JavaScript Vector Library │ \\
228
382
  // ├─────────────────────────────────────────────────────────────────────┤ \\
229
383
  // │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com) │ \\
230
384
  // │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\
231
385
  // │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\
232
386
  // └─────────────────────────────────────────────────────────────────────┘ \\
233
- (function () {
234
-
387
+
388
+ (function (glob, factory) {
389
+ // AMD support
390
+ if (typeof define === "function" && define.amd) {
391
+ // Define as an anonymous module
392
+ define(["eve"], function( eve ) {
393
+ return factory(glob, eve);
394
+ });
395
+ } else {
396
+ // Browser globals (glob is window)
397
+ // Raphael adds itself to window
398
+ factory(glob, glob.eve);
399
+ }
400
+ }(this, function (window, eve) {
401
+ /*\
402
+ * Raphael
403
+ [ method ]
404
+ **
405
+ * Creates a canvas object on which to draw.
406
+ * You must do this first, as all future calls to drawing methods
407
+ * from this instance will be bound to this canvas.
408
+ > Parameters
409
+ **
410
+ - container (HTMLElement|string) DOM element or its ID which is going to be a parent for drawing surface
411
+ - width (number)
412
+ - height (number)
413
+ - callback (function) #optional callback function which is going to be executed in the context of newly created paper
414
+ * or
415
+ - x (number)
416
+ - y (number)
417
+ - width (number)
418
+ - height (number)
419
+ - callback (function) #optional callback function which is going to be executed in the context of newly created paper
420
+ * or
421
+ - 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>}). See @Paper.add.
422
+ - callback (function) #optional callback function which is going to be executed in the context of newly created paper
423
+ * or
424
+ - 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`.
425
+ = (object) @Paper
426
+ > Usage
427
+ | // Each of the following examples create a canvas
428
+ | // that is 320px wide by 200px high.
429
+ | // Canvas is created at the viewport’s 10,50 coordinate.
430
+ | var paper = Raphael(10, 50, 320, 200);
431
+ | // Canvas is created at the top left corner of the #notepad element
432
+ | // (or its top right corner in dir="rtl" elements)
433
+ | var paper = Raphael(document.getElementById("notepad"), 320, 200);
434
+ | // Same as above
435
+ | var paper = Raphael("notepad", 320, 200);
436
+ | // Image dump
437
+ | var set = Raphael(["notepad", 320, 200, {
438
+ | type: "rect",
439
+ | x: 10,
440
+ | y: 10,
441
+ | width: 25,
442
+ | height: 25,
443
+ | stroke: "#f00"
444
+ | }, {
445
+ | type: "text",
446
+ | x: 30,
447
+ | y: 40,
448
+ | text: "Dump"
449
+ | }]);
450
+ \*/
235
451
  function R(first) {
236
452
  if (R.is(first, "function")) {
237
453
  return loaded ? first() : eve.on("raphael.DOMload", first);
@@ -249,7 +465,7 @@
249
465
  }
250
466
  }
251
467
  }
252
- R.version = "2.1.0";
468
+ R.version = "2.1.2";
253
469
  R.eve = eve;
254
470
  var loaded,
255
471
  separator = /[, ]+/,
@@ -266,15 +482,45 @@
266
482
  is: g.win.Raphael
267
483
  },
268
484
  Paper = function () {
269
-
270
-
485
+ /*\
486
+ * Paper.ca
487
+ [ property (object) ]
488
+ **
489
+ * Shortcut for @Paper.customAttributes
490
+ \*/
491
+ /*\
492
+ * Paper.customAttributes
493
+ [ property (object) ]
494
+ **
495
+ * If you have a set of attributes that you would like to represent
496
+ * as a function of some number you can do it easily with custom attributes:
497
+ > Usage
498
+ | paper.customAttributes.hue = function (num) {
499
+ | num = num % 1;
500
+ | return {fill: "hsb(" + num + ", 0.75, 1)"};
501
+ | };
502
+ | // Custom attribute “hue” will change fill
503
+ | // to be given hue with fixed saturation and brightness.
504
+ | // Now you can use it like this:
505
+ | var c = paper.circle(10, 10, 10).attr({hue: .45});
506
+ | // or even like this:
507
+ | c.animate({hue: 1}, 1e3);
508
+ |
509
+ | // You could also create custom attribute
510
+ | // with multiple parameters:
511
+ | paper.customAttributes.hsb = function (h, s, b) {
512
+ | return {fill: "hsb(" + [h, s, b].join(",") + ")"};
513
+ | };
514
+ | c.attr({hsb: "0.5 .8 1"});
515
+ | c.animate({hsb: [1, 0, 0.5]}, 1e3);
516
+ \*/
271
517
  this.ca = this.customAttributes = {};
272
518
  },
273
519
  paperproto,
274
520
  appendChild = "appendChild",
275
521
  apply = "apply",
276
522
  concat = "concat",
277
- supportsTouch = "createTouch" in g.doc,
523
+ supportsTouch = ('ontouchstart' in g.win) || g.win.DocumentTouch && g.doc instanceof DocumentTouch, //taken from Modernizr touch test
278
524
  E = "",
279
525
  S = " ",
280
526
  Str = String,
@@ -425,9 +671,22 @@
425
671
  text: function (el) {
426
672
  var bbox = el._getBBox();
427
673
  return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);
674
+ },
675
+ set : function(el) {
676
+ var bbox = el._getBBox();
677
+ return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);
428
678
  }
429
679
  },
430
-
680
+ /*\
681
+ * Raphael.mapPath
682
+ [ method ]
683
+ **
684
+ * Transform the path string with given matrix.
685
+ > Parameters
686
+ - path (string) path string
687
+ - matrix (object) see @Matrix
688
+ = (string) transformed path string
689
+ \*/
431
690
  mapPath = R.mapPath = function (path, matrix) {
432
691
  if (!matrix) {
433
692
  return path;
@@ -447,7 +706,12 @@
447
706
  };
448
707
 
449
708
  R._g = g;
450
-
709
+ /*\
710
+ * Raphael.type
711
+ [ property (string) ]
712
+ **
713
+ * Can be “SVG”, “VML” or empty, depending on browser support.
714
+ \*/
451
715
  R.type = (g.win.SVGAngle || g.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML");
452
716
  if (R.type == "VML") {
453
717
  var d = g.doc.createElement("div"),
@@ -460,15 +724,59 @@
460
724
  }
461
725
  d = null;
462
726
  }
463
-
464
-
727
+ /*\
728
+ * Raphael.svg
729
+ [ property (boolean) ]
730
+ **
731
+ * `true` if browser supports SVG.
732
+ \*/
733
+ /*\
734
+ * Raphael.vml
735
+ [ property (boolean) ]
736
+ **
737
+ * `true` if browser supports VML.
738
+ \*/
465
739
  R.svg = !(R.vml = R.type == "VML");
466
740
  R._Paper = Paper;
467
-
741
+ /*\
742
+ * Raphael.fn
743
+ [ property (object) ]
744
+ **
745
+ * You can add your own method to the canvas. For example if you want to draw a pie chart,
746
+ * you can create your own pie chart function and ship it as a Raphaël plugin. To do this
747
+ * you need to extend the `Raphael.fn` object. You should modify the `fn` object before a
748
+ * Raphaël instance is created, otherwise it will take no effect. Please note that the
749
+ * ability for namespaced plugins was removed in Raphael 2.0. It is up to the plugin to
750
+ * ensure any namespacing ensures proper context.
751
+ > Usage
752
+ | Raphael.fn.arrow = function (x1, y1, x2, y2, size) {
753
+ | return this.path( ... );
754
+ | };
755
+ | // or create namespace
756
+ | Raphael.fn.mystuff = {
757
+ | arrow: function () {…},
758
+ | star: function () {…},
759
+ | // etc…
760
+ | };
761
+ | var paper = Raphael(10, 10, 630, 480);
762
+ | // then use it
763
+ | paper.arrow(10, 10, 30, 30, 5).attr({fill: "#f00"});
764
+ | paper.mystuff.arrow();
765
+ | paper.mystuff.star();
766
+ \*/
468
767
  R.fn = paperproto = Paper.prototype = R.prototype;
469
768
  R._id = 0;
470
769
  R._oid = 0;
471
-
770
+ /*\
771
+ * Raphael.is
772
+ [ method ]
773
+ **
774
+ * Handfull replacement for `typeof` operator.
775
+ > Parameters
776
+ - o (…) any object or primitive
777
+ - type (string) name of the type, i.e. “string”, “function”, “number”, etc.
778
+ = (boolean) is given value is of given type
779
+ \*/
472
780
  R.is = function (o, type) {
473
781
  type = lowerCase.call(type);
474
782
  if (type == "finite") {
@@ -485,7 +793,7 @@
485
793
  };
486
794
 
487
795
  function clone(obj) {
488
- if (Object(obj) !== obj) {
796
+ if (typeof obj == "function" || Object(obj) !== obj) {
489
797
  return obj;
490
798
  }
491
799
  var res = new obj.constructor;
@@ -495,7 +803,20 @@
495
803
  return res;
496
804
  }
497
805
 
498
-
806
+ /*\
807
+ * Raphael.angle
808
+ [ method ]
809
+ **
810
+ * Returns angle between two or three points
811
+ > Parameters
812
+ - x1 (number) x coord of first point
813
+ - y1 (number) y coord of first point
814
+ - x2 (number) x coord of second point
815
+ - y2 (number) y coord of second point
816
+ - x3 (number) #optional x coord of third point
817
+ - y3 (number) #optional y coord of third point
818
+ = (number) angle in degrees.
819
+ \*/
499
820
  R.angle = function (x1, y1, x2, y2, x3, y3) {
500
821
  if (x3 == null) {
501
822
  var x = x1 - x2,
@@ -508,15 +829,41 @@
508
829
  return R.angle(x1, y1, x3, y3) - R.angle(x2, y2, x3, y3);
509
830
  }
510
831
  };
511
-
832
+ /*\
833
+ * Raphael.rad
834
+ [ method ]
835
+ **
836
+ * Transform angle to radians
837
+ > Parameters
838
+ - deg (number) angle in degrees
839
+ = (number) angle in radians.
840
+ \*/
512
841
  R.rad = function (deg) {
513
842
  return deg % 360 * PI / 180;
514
843
  };
515
-
844
+ /*\
845
+ * Raphael.deg
846
+ [ method ]
847
+ **
848
+ * Transform angle to degrees
849
+ > Parameters
850
+ - deg (number) angle in radians
851
+ = (number) angle in degrees.
852
+ \*/
516
853
  R.deg = function (rad) {
517
854
  return rad * 180 / PI % 360;
518
855
  };
519
-
856
+ /*\
857
+ * Raphael.snapTo
858
+ [ method ]
859
+ **
860
+ * Snaps given value to given grid.
861
+ > Parameters
862
+ - values (array|number) given array of values or step of the grid
863
+ - value (number) value to adjust
864
+ - tolerance (number) #optional tolerance for snapping. Default is `10`.
865
+ = (number) adjusted value.
866
+ \*/
520
867
  R.snapTo = function (values, value, tolerance) {
521
868
  tolerance = R.is(tolerance, "finite") ? tolerance : 10;
522
869
  if (R.is(values, array)) {
@@ -536,8 +883,13 @@
536
883
  }
537
884
  return value;
538
885
  };
539
-
540
-
886
+
887
+ /*\
888
+ * Raphael.createUUID
889
+ [ method ]
890
+ **
891
+ * Returns RFC4122, version 4 ID
892
+ \*/
541
893
  var createUUID = R.createUUID = (function (uuidRegEx, uuidReplacer) {
542
894
  return function () {
543
895
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(uuidRegEx, uuidReplacer).toUpperCase();
@@ -548,7 +900,14 @@
548
900
  return v.toString(16);
549
901
  });
550
902
 
551
-
903
+ /*\
904
+ * Raphael.setWindow
905
+ [ method ]
906
+ **
907
+ * Used when you need to draw in `&lt;iframe>`. Switched window to the iframe one.
908
+ > Parameters
909
+ - newwin (window) new window object
910
+ \*/
552
911
  R.setWindow = function (newwin) {
553
912
  eve("raphael.setWindow", R, g.win, newwin);
554
913
  g.win = newwin;
@@ -619,7 +978,7 @@
619
978
  g /= 255;
620
979
  b /= 255;
621
980
  }
622
-
981
+
623
982
  return [r, g, b];
624
983
  },
625
984
  packageRGB = function (r, g, b, o) {
@@ -636,8 +995,27 @@
636
995
  R.is(o, "finite") && (rgb.opacity = o);
637
996
  return rgb;
638
997
  };
639
-
640
-
998
+
999
+ /*\
1000
+ * Raphael.color
1001
+ [ method ]
1002
+ **
1003
+ * Parses the color string and returns object with all values for the given color.
1004
+ > Parameters
1005
+ - clr (string) color string in one of the supported formats (see @Raphael.getRGB)
1006
+ = (object) Combined RGB & HSB object in format:
1007
+ o {
1008
+ o r (number) red,
1009
+ o g (number) green,
1010
+ o b (number) blue,
1011
+ o hex (string) color in HTML/CSS format: #••••••,
1012
+ o error (boolean) `true` if string can’t be parsed,
1013
+ o h (number) hue,
1014
+ o s (number) saturation,
1015
+ o v (number) value (brightness),
1016
+ o l (number) lightness
1017
+ o }
1018
+ \*/
641
1019
  R.color = function (clr) {
642
1020
  var rgb;
643
1021
  if (R.is(clr, "object") && "h" in clr && "s" in clr && "b" in clr) {
@@ -671,7 +1049,23 @@
671
1049
  clr.toString = rgbtoString;
672
1050
  return clr;
673
1051
  };
674
-
1052
+ /*\
1053
+ * Raphael.hsb2rgb
1054
+ [ method ]
1055
+ **
1056
+ * Converts HSB values to RGB object.
1057
+ > Parameters
1058
+ - h (number) hue
1059
+ - s (number) saturation
1060
+ - v (number) value or brightness
1061
+ = (object) RGB object in format:
1062
+ o {
1063
+ o r (number) red,
1064
+ o g (number) green,
1065
+ o b (number) blue,
1066
+ o hex (string) color in HTML/CSS format: #••••••
1067
+ o }
1068
+ \*/
675
1069
  R.hsb2rgb = function (h, s, v, o) {
676
1070
  if (this.is(h, "object") && "h" in h && "s" in h && "b" in h) {
677
1071
  v = h.b;
@@ -692,7 +1086,23 @@
692
1086
  B += [0, 0, X, C, C, X][h];
693
1087
  return packageRGB(R, G, B, o);
694
1088
  };
695
-
1089
+ /*\
1090
+ * Raphael.hsl2rgb
1091
+ [ method ]
1092
+ **
1093
+ * Converts HSL values to RGB object.
1094
+ > Parameters
1095
+ - h (number) hue
1096
+ - s (number) saturation
1097
+ - l (number) luminosity
1098
+ = (object) RGB object in format:
1099
+ o {
1100
+ o r (number) red,
1101
+ o g (number) green,
1102
+ o b (number) blue,
1103
+ o hex (string) color in HTML/CSS format: #••••••
1104
+ o }
1105
+ \*/
696
1106
  R.hsl2rgb = function (h, s, l, o) {
697
1107
  if (this.is(h, "object") && "h" in h && "s" in h && "l" in h) {
698
1108
  l = h.l;
@@ -717,7 +1127,22 @@
717
1127
  B += [0, 0, X, C, C, X][h];
718
1128
  return packageRGB(R, G, B, o);
719
1129
  };
720
-
1130
+ /*\
1131
+ * Raphael.rgb2hsb
1132
+ [ method ]
1133
+ **
1134
+ * Converts RGB values to HSB object.
1135
+ > Parameters
1136
+ - r (number) red
1137
+ - g (number) green
1138
+ - b (number) blue
1139
+ = (object) HSB object in format:
1140
+ o {
1141
+ o h (number) hue
1142
+ o s (number) saturation
1143
+ o b (number) brightness
1144
+ o }
1145
+ \*/
721
1146
  R.rgb2hsb = function (r, g, b) {
722
1147
  b = prepareRGB(r, g, b);
723
1148
  r = b[0];
@@ -736,7 +1161,22 @@
736
1161
  S = C == 0 ? 0 : C / V;
737
1162
  return {h: H, s: S, b: V, toString: hsbtoString};
738
1163
  };
739
-
1164
+ /*\
1165
+ * Raphael.rgb2hsl
1166
+ [ method ]
1167
+ **
1168
+ * Converts RGB values to HSL object.
1169
+ > Parameters
1170
+ - r (number) red
1171
+ - g (number) green
1172
+ - b (number) blue
1173
+ = (object) HSL object in format:
1174
+ o {
1175
+ o h (number) hue
1176
+ o s (number) saturation
1177
+ o l (number) luminosity
1178
+ o }
1179
+ \*/
740
1180
  R.rgb2hsl = function (r, g, b) {
741
1181
  b = prepareRGB(r, g, b);
742
1182
  r = b[0];
@@ -798,12 +1238,38 @@
798
1238
  g.doc.body.appendChild(img);
799
1239
  img.src = src;
800
1240
  };
801
-
1241
+
802
1242
  function clrToString() {
803
1243
  return this.hex;
804
1244
  }
805
1245
 
806
-
1246
+ /*\
1247
+ * Raphael.getRGB
1248
+ [ method ]
1249
+ **
1250
+ * Parses colour string as RGB object
1251
+ > Parameters
1252
+ - colour (string) colour string in one of formats:
1253
+ # <ul>
1254
+ # <li>Colour name (“<code>red</code>”, “<code>green</code>”, “<code>cornflowerblue</code>”, etc)</li>
1255
+ # <li>#••• — shortened HTML colour: (“<code>#000</code>”, “<code>#fc0</code>”, etc)</li>
1256
+ # <li>#•••••• — full length HTML colour: (“<code>#000000</code>”, “<code>#bd2300</code>”)</li>
1257
+ # <li>rgb(•••, •••, •••) — red, green and blue channels’ values: (“<code>rgb(200,&nbsp;100,&nbsp;0)</code>”)</li>
1258
+ # <li>rgb(•••%, •••%, •••%) — same as above, but in %: (“<code>rgb(100%,&nbsp;175%,&nbsp;0%)</code>”)</li>
1259
+ # <li>hsb(•••, •••, •••) — hue, saturation and brightness values: (“<code>hsb(0.5,&nbsp;0.25,&nbsp;1)</code>”)</li>
1260
+ # <li>hsb(•••%, •••%, •••%) — same as above, but in %</li>
1261
+ # <li>hsl(•••, •••, •••) — same as hsb</li>
1262
+ # <li>hsl(•••%, •••%, •••%) — same as hsb</li>
1263
+ # </ul>
1264
+ = (object) RGB object in format:
1265
+ o {
1266
+ o r (number) red,
1267
+ o g (number) green,
1268
+ o b (number) blue
1269
+ o hex (string) color in HTML/CSS format: #••••••,
1270
+ o error (boolean) true if string can’t be parsed
1271
+ o }
1272
+ \*/
807
1273
  R.getRGB = cacher(function (colour) {
808
1274
  if (!colour || !!((colour = Str(colour)).indexOf("-") + 1)) {
809
1275
  return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: clrToString};
@@ -875,19 +1341,57 @@
875
1341
  }
876
1342
  return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: clrToString};
877
1343
  }, R);
878
-
1344
+ /*\
1345
+ * Raphael.hsb
1346
+ [ method ]
1347
+ **
1348
+ * Converts HSB values to hex representation of the colour.
1349
+ > Parameters
1350
+ - h (number) hue
1351
+ - s (number) saturation
1352
+ - b (number) value or brightness
1353
+ = (string) hex representation of the colour.
1354
+ \*/
879
1355
  R.hsb = cacher(function (h, s, b) {
880
1356
  return R.hsb2rgb(h, s, b).hex;
881
1357
  });
882
-
1358
+ /*\
1359
+ * Raphael.hsl
1360
+ [ method ]
1361
+ **
1362
+ * Converts HSL values to hex representation of the colour.
1363
+ > Parameters
1364
+ - h (number) hue
1365
+ - s (number) saturation
1366
+ - l (number) luminosity
1367
+ = (string) hex representation of the colour.
1368
+ \*/
883
1369
  R.hsl = cacher(function (h, s, l) {
884
1370
  return R.hsl2rgb(h, s, l).hex;
885
1371
  });
886
-
1372
+ /*\
1373
+ * Raphael.rgb
1374
+ [ method ]
1375
+ **
1376
+ * Converts RGB values to hex representation of the colour.
1377
+ > Parameters
1378
+ - r (number) red
1379
+ - g (number) green
1380
+ - b (number) blue
1381
+ = (string) hex representation of the colour.
1382
+ \*/
887
1383
  R.rgb = cacher(function (r, g, b) {
888
1384
  return "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1);
889
1385
  });
890
-
1386
+ /*\
1387
+ * Raphael.getColor
1388
+ [ method ]
1389
+ **
1390
+ * On each call returns next colour in the spectrum. To reset it back to red call @Raphael.getColor.reset
1391
+ > Parameters
1392
+ - value (number) #optional brightness, default is `0.75`
1393
+ = (string) hex representation of the colour.
1394
+ \*/
891
1395
  R.getColor = function (value) {
892
1396
  var start = this.getColor.start = this.getColor.start || {h: 0, s: 1, b: value || .75},
893
1397
  rgb = this.hsb2rgb(start.h, start.s, start.b);
@@ -899,7 +1403,12 @@
899
1403
  }
900
1404
  return rgb.hex;
901
1405
  };
902
-
1406
+ /*\
1407
+ * Raphael.getColor.reset
1408
+ [ method ]
1409
+ **
1410
+ * Resets spectrum position for @Raphael.getColor back to red.
1411
+ \*/
903
1412
  R.getColor.reset = function () {
904
1413
  delete this.start;
905
1414
  };
@@ -942,7 +1451,17 @@
942
1451
 
943
1452
  return d;
944
1453
  }
945
-
1454
+ /*\
1455
+ * Raphael.parsePathString
1456
+ [ method ]
1457
+ **
1458
+ * Utility method
1459
+ **
1460
+ * Parses given path string into an array of arrays of path segments.
1461
+ > Parameters
1462
+ - pathString (string|array) path string or array of segments (in the last case it will be returned straight away)
1463
+ = (array) array of segments.
1464
+ \*/
946
1465
  R.parsePathString = function (pathString) {
947
1466
  if (!pathString) {
948
1467
  return null;
@@ -951,7 +1470,7 @@
951
1470
  if (pth.arr) {
952
1471
  return pathClone(pth.arr);
953
1472
  }
954
-
1473
+
955
1474
  var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0},
956
1475
  data = [];
957
1476
  if (R.is(pathString, array) && R.is(pathString[0], array)) { // rough assumption
@@ -983,7 +1502,17 @@
983
1502
  pth.arr = pathClone(data);
984
1503
  return data;
985
1504
  };
986
-
1505
+ /*\
1506
+ * Raphael.parseTransformString
1507
+ [ method ]
1508
+ **
1509
+ * Utility method
1510
+ **
1511
+ * Parses given path string into an array of transformations.
1512
+ > Parameters
1513
+ - TString (string|array) transform string or array of transformations (in the last case it will be returned straight away)
1514
+ = (array) array of transformations.
1515
+ \*/
987
1516
  R.parseTransformString = cacher(function (TString) {
988
1517
  if (!TString) {
989
1518
  return null;
@@ -1024,7 +1553,46 @@
1024
1553
  });
1025
1554
  return p[ps];
1026
1555
  };
1027
-
1556
+ /*\
1557
+ * Raphael.findDotsAtSegment
1558
+ [ method ]
1559
+ **
1560
+ * Utility method
1561
+ **
1562
+ * Find dot coordinates on the given cubic bezier curve at the given t.
1563
+ > Parameters
1564
+ - p1x (number) x of the first point of the curve
1565
+ - p1y (number) y of the first point of the curve
1566
+ - c1x (number) x of the first anchor of the curve
1567
+ - c1y (number) y of the first anchor of the curve
1568
+ - c2x (number) x of the second anchor of the curve
1569
+ - c2y (number) y of the second anchor of the curve
1570
+ - p2x (number) x of the second point of the curve
1571
+ - p2y (number) y of the second point of the curve
1572
+ - t (number) position on the curve (0..1)
1573
+ = (object) point information in format:
1574
+ o {
1575
+ o x: (number) x coordinate of the point
1576
+ o y: (number) y coordinate of the point
1577
+ o m: {
1578
+ o x: (number) x coordinate of the left anchor
1579
+ o y: (number) y coordinate of the left anchor
1580
+ o }
1581
+ o n: {
1582
+ o x: (number) x coordinate of the right anchor
1583
+ o y: (number) y coordinate of the right anchor
1584
+ o }
1585
+ o start: {
1586
+ o x: (number) x coordinate of the start of the curve
1587
+ o y: (number) y coordinate of the start of the curve
1588
+ o }
1589
+ o end: {
1590
+ o x: (number) x coordinate of the end of the curve
1591
+ o y: (number) y coordinate of the end of the curve
1592
+ o }
1593
+ o alpha: (number) angle of the curve derivative at the point
1594
+ o }
1595
+ \*/
1028
1596
  R.findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
1029
1597
  var t1 = 1 - t,
1030
1598
  t13 = pow(t1, 3),
@@ -1053,7 +1621,36 @@
1053
1621
  alpha: alpha
1054
1622
  };
1055
1623
  };
1056
-
1624
+ /*\
1625
+ * Raphael.bezierBBox
1626
+ [ method ]
1627
+ **
1628
+ * Utility method
1629
+ **
1630
+ * Return bounding box of a given cubic bezier curve
1631
+ > Parameters
1632
+ - p1x (number) x of the first point of the curve
1633
+ - p1y (number) y of the first point of the curve
1634
+ - c1x (number) x of the first anchor of the curve
1635
+ - c1y (number) y of the first anchor of the curve
1636
+ - c2x (number) x of the second anchor of the curve
1637
+ - c2y (number) y of the second anchor of the curve
1638
+ - p2x (number) x of the second point of the curve
1639
+ - p2y (number) y of the second point of the curve
1640
+ * or
1641
+ - bez (array) array of six points for bezier curve
1642
+ = (object) point information in format:
1643
+ o {
1644
+ o min: {
1645
+ o x: (number) x coordinate of the left point
1646
+ o y: (number) y coordinate of the top point
1647
+ o }
1648
+ o max: {
1649
+ o x: (number) x coordinate of the right point
1650
+ o y: (number) y coordinate of the bottom point
1651
+ o }
1652
+ o }
1653
+ \*/
1057
1654
  R.bezierBBox = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
1058
1655
  if (!R.is(p1x, "array")) {
1059
1656
  p1x = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y];
@@ -1068,11 +1665,34 @@
1068
1665
  height: bbox.max.y - bbox.min.y
1069
1666
  };
1070
1667
  };
1071
-
1668
+ /*\
1669
+ * Raphael.isPointInsideBBox
1670
+ [ method ]
1671
+ **
1672
+ * Utility method
1673
+ **
1674
+ * Returns `true` if given point is inside bounding boxes.
1675
+ > Parameters
1676
+ - bbox (string) bounding box
1677
+ - x (string) x coordinate of the point
1678
+ - y (string) y coordinate of the point
1679
+ = (boolean) `true` if point inside
1680
+ \*/
1072
1681
  R.isPointInsideBBox = function (bbox, x, y) {
1073
1682
  return x >= bbox.x && x <= bbox.x2 && y >= bbox.y && y <= bbox.y2;
1074
1683
  };
1075
-
1684
+ /*\
1685
+ * Raphael.isBBoxIntersect
1686
+ [ method ]
1687
+ **
1688
+ * Utility method
1689
+ **
1690
+ * Returns `true` if two bounding boxes intersect
1691
+ > Parameters
1692
+ - bbox1 (string) first bounding box
1693
+ - bbox2 (string) second bounding box
1694
+ = (boolean) `true` if they intersect
1695
+ \*/
1076
1696
  R.isBBoxIntersect = function (bbox1, bbox2) {
1077
1697
  var i = R.isPointInsideBBox;
1078
1698
  return i(bbox2, bbox1.x, bbox1.y)
@@ -1175,8 +1795,8 @@
1175
1795
  }
1176
1796
  var l1 = bezlen.apply(0, bez1),
1177
1797
  l2 = bezlen.apply(0, bez2),
1178
- n1 = ~~(l1 / 5),
1179
- n2 = ~~(l2 / 5),
1798
+ n1 = mmax(~~(l1 / 5), 1),
1799
+ n2 = mmax(~~(l2 / 5), 1),
1180
1800
  dots1 = [],
1181
1801
  dots2 = [],
1182
1802
  xy = {},
@@ -1205,15 +1825,15 @@
1205
1825
  xy[is.x.toFixed(4)] = is.y.toFixed(4);
1206
1826
  var t1 = di.t + abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t),
1207
1827
  t2 = dj.t + abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t);
1208
- if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) {
1828
+ if (t1 >= 0 && t1 <= 1.001 && t2 >= 0 && t2 <= 1.001) {
1209
1829
  if (justCount) {
1210
1830
  res++;
1211
1831
  } else {
1212
1832
  res.push({
1213
1833
  x: is.x,
1214
1834
  y: is.y,
1215
- t1: t1,
1216
- t2: t2
1835
+ t1: mmin(t1, 1),
1836
+ t2: mmin(t2, 1)
1217
1837
  });
1218
1838
  }
1219
1839
  }
@@ -1222,7 +1842,30 @@
1222
1842
  }
1223
1843
  return res;
1224
1844
  }
1225
-
1845
+ /*\
1846
+ * Raphael.pathIntersection
1847
+ [ method ]
1848
+ **
1849
+ * Utility method
1850
+ **
1851
+ * Finds intersections of two paths
1852
+ > Parameters
1853
+ - path1 (string) path string
1854
+ - path2 (string) path string
1855
+ = (array) dots of intersection
1856
+ o [
1857
+ o {
1858
+ o x: (number) x coordinate of the point
1859
+ o y: (number) y coordinate of the point
1860
+ o t1: (number) t value for segment of path1
1861
+ o t2: (number) t value for segment of path2
1862
+ o segment1: (number) order number for segment of path1
1863
+ o segment2: (number) order number for segment of path2
1864
+ o bez1: (array) eight coordinates representing beziér curve for the segment of path1
1865
+ o bez2: (array) eight coordinates representing beziér curve for the segment of path2
1866
+ o }
1867
+ o ]
1868
+ \*/
1226
1869
  R.pathIntersection = function (path1, path2) {
1227
1870
  return interPathHelper(path1, path2);
1228
1871
  };
@@ -1282,7 +1925,19 @@
1282
1925
  }
1283
1926
  return res;
1284
1927
  }
1285
-
1928
+ /*\
1929
+ * Raphael.isPointInsidePath
1930
+ [ method ]
1931
+ **
1932
+ * Utility method
1933
+ **
1934
+ * Returns `true` if given point is inside a given closed path.
1935
+ > Parameters
1936
+ - path (string) path string
1937
+ - x (number) x of the point
1938
+ - y (number) y of the point
1939
+ = (boolean) true, if point is inside the path
1940
+ \*/
1286
1941
  R.isPointInsidePath = function (path, x, y) {
1287
1942
  var bbox = R.pathBBox(path);
1288
1943
  return R.isPointInsideBBox(bbox, x, y) &&
@@ -1293,17 +1948,37 @@
1293
1948
  eve("raphael.log", null, "Rapha\xebl: you are calling to method \u201c" + methodname + "\u201d of removed object", methodname);
1294
1949
  };
1295
1950
  };
1296
-
1951
+ /*\
1952
+ * Raphael.pathBBox
1953
+ [ method ]
1954
+ **
1955
+ * Utility method
1956
+ **
1957
+ * Return bounding box of a given path
1958
+ > Parameters
1959
+ - path (string) path string
1960
+ = (object) bounding box
1961
+ o {
1962
+ o x: (number) x coordinate of the left top point of the box
1963
+ o y: (number) y coordinate of the left top point of the box
1964
+ o x2: (number) x coordinate of the right bottom point of the box
1965
+ o y2: (number) y coordinate of the right bottom point of the box
1966
+ o width: (number) width of the box
1967
+ o height: (number) height of the box
1968
+ o cx: (number) x coordinate of the center of the box
1969
+ o cy: (number) y coordinate of the center of the box
1970
+ o }
1971
+ \*/
1297
1972
  var pathDimensions = R.pathBBox = function (path) {
1298
1973
  var pth = paths(path);
1299
1974
  if (pth.bbox) {
1300
- return pth.bbox;
1975
+ return clone(pth.bbox);
1301
1976
  }
1302
1977
  if (!path) {
1303
1978
  return {x: 0, y: 0, width: 0, height: 0, x2: 0, y2: 0};
1304
1979
  }
1305
1980
  path = path2curve(path);
1306
- var x = 0,
1981
+ var x = 0,
1307
1982
  y = 0,
1308
1983
  X = [],
1309
1984
  Y = [],
@@ -1327,13 +2002,17 @@
1327
2002
  ymin = mmin[apply](0, Y),
1328
2003
  xmax = mmax[apply](0, X),
1329
2004
  ymax = mmax[apply](0, Y),
1330
- bb = {
2005
+ width = xmax - xmin,
2006
+ height = ymax - ymin,
2007
+ bb = {
1331
2008
  x: xmin,
1332
2009
  y: ymin,
1333
2010
  x2: xmax,
1334
2011
  y2: ymax,
1335
- width: xmax - xmin,
1336
- height: ymax - ymin
2012
+ width: width,
2013
+ height: height,
2014
+ cx: xmin + width / 2,
2015
+ cy: ymin + height / 2
1337
2016
  };
1338
2017
  pth.bbox = clone(bb);
1339
2018
  return bb;
@@ -1682,7 +2361,7 @@
1682
2361
  p2 = path2 && pathToAbsolute(path2),
1683
2362
  attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},
1684
2363
  attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},
1685
- processPath = function (path, d) {
2364
+ processPath = function (path, d, pcom) {
1686
2365
  var nx, ny;
1687
2366
  if (!path) {
1688
2367
  return ["C", d.x, d.y, d.x, d.y, d.x, d.y];
@@ -1697,13 +2376,25 @@
1697
2376
  path = ["C"][concat](a2c[apply](0, [d.x, d.y][concat](path.slice(1))));
1698
2377
  break;
1699
2378
  case "S":
1700
- nx = d.x + (d.x - (d.bx || d.x));
1701
- ny = d.y + (d.y - (d.by || d.y));
2379
+ if (pcom == "C" || pcom == "S") { // In "S" case we have to take into account, if the previous command is C/S.
2380
+ nx = d.x * 2 - d.bx; // And reflect the previous
2381
+ ny = d.y * 2 - d.by; // command's control point relative to the current point.
2382
+ }
2383
+ else { // or some else or nothing
2384
+ nx = d.x;
2385
+ ny = d.y;
2386
+ }
1702
2387
  path = ["C", nx, ny][concat](path.slice(1));
1703
2388
  break;
1704
2389
  case "T":
1705
- d.qx = d.x + (d.x - (d.qx || d.x));
1706
- d.qy = d.y + (d.y - (d.qy || d.y));
2390
+ if (pcom == "Q" || pcom == "T") { // In "T" case we have to take into account, if the previous command is Q/T.
2391
+ d.qx = d.x * 2 - d.qx; // And make a reflection similar
2392
+ d.qy = d.y * 2 - d.qy; // to case "S".
2393
+ }
2394
+ else { // or something else or nothing
2395
+ d.qx = d.x;
2396
+ d.qy = d.y;
2397
+ }
1707
2398
  path = ["C"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));
1708
2399
  break;
1709
2400
  case "Q":
@@ -1851,7 +2542,18 @@
1851
2542
  el2.prev = el;
1852
2543
  el.next = el2;
1853
2544
  },
1854
-
2545
+ /*\
2546
+ * Raphael.toMatrix
2547
+ [ method ]
2548
+ **
2549
+ * Utility method
2550
+ **
2551
+ * Returns matrix of transformations applied to a given path
2552
+ > Parameters
2553
+ - path (string) path string
2554
+ - transform (string|array) transformation string
2555
+ = (object) @Matrix
2556
+ \*/
1855
2557
  toMatrix = R.toMatrix = function (path, transform) {
1856
2558
  var bb = pathDimensions(path),
1857
2559
  el = {
@@ -1865,7 +2567,18 @@
1865
2567
  extractTransform(el, transform);
1866
2568
  return el.matrix;
1867
2569
  },
1868
-
2570
+ /*\
2571
+ * Raphael.transformPath
2572
+ [ method ]
2573
+ **
2574
+ * Utility method
2575
+ **
2576
+ * Returns path transformed by a given transformation
2577
+ > Parameters
2578
+ - path (string) path string
2579
+ - transform (string|array) transformation string
2580
+ = (string) path
2581
+ \*/
1869
2582
  transformPath = R.transformPath = function (path, transform) {
1870
2583
  return mapPath(path, toMatrix(path, transform));
1871
2584
  },
@@ -1945,7 +2658,12 @@
1945
2658
  }
1946
2659
  }
1947
2660
 
1948
-
2661
+ /*\
2662
+ * Element.matrix
2663
+ [ property (object) ]
2664
+ **
2665
+ * Keeps @Matrix object, which represents element transformation
2666
+ \*/
1949
2667
  el.matrix = m;
1950
2668
 
1951
2669
  _.sx = sx;
@@ -2039,12 +2757,47 @@
2039
2757
  height: h
2040
2758
  };
2041
2759
  };
2042
-
2760
+ /*\
2761
+ * Raphael.pathToRelative
2762
+ [ method ]
2763
+ **
2764
+ * Utility method
2765
+ **
2766
+ * Converts path to relative form
2767
+ > Parameters
2768
+ - pathString (string|array) path string or array of segments
2769
+ = (array) array of segments.
2770
+ \*/
2043
2771
  R.pathToRelative = pathToRelative;
2044
2772
  R._engine = {};
2045
-
2773
+ /*\
2774
+ * Raphael.path2curve
2775
+ [ method ]
2776
+ **
2777
+ * Utility method
2778
+ **
2779
+ * Converts path to a new path where all segments are cubic bezier curves.
2780
+ > Parameters
2781
+ - pathString (string|array) path string or array of segments
2782
+ = (array) array of segments.
2783
+ \*/
2046
2784
  R.path2curve = path2curve;
2047
-
2785
+ /*\
2786
+ * Raphael.matrix
2787
+ [ method ]
2788
+ **
2789
+ * Utility method
2790
+ **
2791
+ * Returns matrix based on given parameters.
2792
+ > Parameters
2793
+ - a (number)
2794
+ - b (number)
2795
+ - c (number)
2796
+ - d (number)
2797
+ - e (number)
2798
+ - f (number)
2799
+ = (object) @Matrix
2800
+ \*/
2048
2801
  R.matrix = function (a, b, c, d, e, f) {
2049
2802
  return new Matrix(a, b, c, d, e, f);
2050
2803
  };
@@ -2066,7 +2819,21 @@
2066
2819
  }
2067
2820
  }
2068
2821
  (function (matrixproto) {
2069
-
2822
+ /*\
2823
+ * Matrix.add
2824
+ [ method ]
2825
+ **
2826
+ * Adds given matrix to existing one.
2827
+ > Parameters
2828
+ - a (number)
2829
+ - b (number)
2830
+ - c (number)
2831
+ - d (number)
2832
+ - e (number)
2833
+ - f (number)
2834
+ or
2835
+ - matrix (object) @Matrix
2836
+ \*/
2070
2837
  matrixproto.add = function (a, b, c, d, e, f) {
2071
2838
  var out = [[], [], []],
2072
2839
  m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]],
@@ -2093,28 +2860,67 @@
2093
2860
  this.e = out[0][2];
2094
2861
  this.f = out[1][2];
2095
2862
  };
2096
-
2863
+ /*\
2864
+ * Matrix.invert
2865
+ [ method ]
2866
+ **
2867
+ * Returns inverted version of the matrix
2868
+ = (object) @Matrix
2869
+ \*/
2097
2870
  matrixproto.invert = function () {
2098
2871
  var me = this,
2099
2872
  x = me.a * me.d - me.b * me.c;
2100
2873
  return new Matrix(me.d / x, -me.b / x, -me.c / x, me.a / x, (me.c * me.f - me.d * me.e) / x, (me.b * me.e - me.a * me.f) / x);
2101
2874
  };
2102
-
2875
+ /*\
2876
+ * Matrix.clone
2877
+ [ method ]
2878
+ **
2879
+ * Returns copy of the matrix
2880
+ = (object) @Matrix
2881
+ \*/
2103
2882
  matrixproto.clone = function () {
2104
2883
  return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f);
2105
2884
  };
2106
-
2885
+ /*\
2886
+ * Matrix.translate
2887
+ [ method ]
2888
+ **
2889
+ * Translate the matrix
2890
+ > Parameters
2891
+ - x (number)
2892
+ - y (number)
2893
+ \*/
2107
2894
  matrixproto.translate = function (x, y) {
2108
2895
  this.add(1, 0, 0, 1, x, y);
2109
2896
  };
2110
-
2897
+ /*\
2898
+ * Matrix.scale
2899
+ [ method ]
2900
+ **
2901
+ * Scales the matrix
2902
+ > Parameters
2903
+ - x (number)
2904
+ - y (number) #optional
2905
+ - cx (number) #optional
2906
+ - cy (number) #optional
2907
+ \*/
2111
2908
  matrixproto.scale = function (x, y, cx, cy) {
2112
2909
  y == null && (y = x);
2113
2910
  (cx || cy) && this.add(1, 0, 0, 1, cx, cy);
2114
2911
  this.add(x, 0, 0, y, 0, 0);
2115
2912
  (cx || cy) && this.add(1, 0, 0, 1, -cx, -cy);
2116
2913
  };
2117
-
2914
+ /*\
2915
+ * Matrix.rotate
2916
+ [ method ]
2917
+ **
2918
+ * Rotates the matrix
2919
+ > Parameters
2920
+ - a (number)
2921
+ - x (number)
2922
+ - y (number)
2923
+ \*/
2118
2924
  matrixproto.rotate = function (a, x, y) {
2119
2925
  a = R.rad(a);
2120
2926
  x = x || 0;
@@ -2124,11 +2930,29 @@
2124
2930
  this.add(cos, sin, -sin, cos, x, y);
2125
2931
  this.add(1, 0, 0, 1, -x, -y);
2126
2932
  };
2127
-
2933
+ /*\
2934
+ * Matrix.x
2935
+ [ method ]
2936
+ **
2937
+ * Return x coordinate for given point after transformation described by the matrix. See also @Matrix.y
2938
+ > Parameters
2939
+ - x (number)
2940
+ - y (number)
2941
+ = (number) x
2942
+ \*/
2128
2943
  matrixproto.x = function (x, y) {
2129
2944
  return x * this.a + y * this.c + this.e;
2130
2945
  };
2131
-
2946
+ /*\
2947
+ * Matrix.y
2948
+ [ method ]
2949
+ **
2950
+ * Return y coordinate for given point after transformation described by the matrix. See also @Matrix.x
2951
+ > Parameters
2952
+ - x (number)
2953
+ - y (number)
2954
+ = (number) y
2955
+ \*/
2132
2956
  matrixproto.y = function (x, y) {
2133
2957
  return x * this.b + y * this.d + this.f;
2134
2958
  };
@@ -2156,7 +2980,20 @@
2156
2980
  a[0] && (a[0] /= mag);
2157
2981
  a[1] && (a[1] /= mag);
2158
2982
  }
2159
-
2983
+ /*\
2984
+ * Matrix.split
2985
+ [ method ]
2986
+ **
2987
+ * Splits matrix into primitive transformations
2988
+ = (object) in format:
2989
+ o dx (number) translation by x
2990
+ o dy (number) translation by y
2991
+ o scalex (number) scale by x
2992
+ o scaley (number) scale by y
2993
+ o shear (number) shear
2994
+ o rotate (number) rotation in deg
2995
+ o isSimple (boolean) could it be represented via simple transformations
2996
+ \*/
2160
2997
  matrixproto.split = function () {
2161
2998
  var out = {};
2162
2999
  // translation
@@ -2192,14 +3029,20 @@
2192
3029
  out.noRotation = !+out.shear.toFixed(9) && !out.rotate;
2193
3030
  return out;
2194
3031
  };
2195
-
3032
+ /*\
3033
+ * Matrix.toTransformString
3034
+ [ method ]
3035
+ **
3036
+ * Return transform string that represents given matrix
3037
+ = (string) transform string
3038
+ \*/
2196
3039
  matrixproto.toTransformString = function (shorter) {
2197
3040
  var s = shorter || this[split]();
2198
3041
  if (s.isSimple) {
2199
3042
  s.scalex = +s.scalex.toFixed(4);
2200
3043
  s.scaley = +s.scaley.toFixed(4);
2201
3044
  s.rotate = +s.rotate.toFixed(4);
2202
- return (s.dx || s.dy ? "t" + [s.dx, s.dy] : E) +
3045
+ return (s.dx || s.dy ? "t" + [s.dx, s.dy] : E) +
2203
3046
  (s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E) +
2204
3047
  (s.rotate ? "r" + [s.rotate, 0, 0] : E);
2205
3048
  } else {
@@ -2212,7 +3055,14 @@
2212
3055
  var version = navigator.userAgent.match(/Version\/(.*?)\s/) || navigator.userAgent.match(/Chrome\/(\d+)/);
2213
3056
  if ((navigator.vendor == "Apple Computer, Inc.") && (version && version[1] < 4 || navigator.platform.slice(0, 2) == "iP") ||
2214
3057
  (navigator.vendor == "Google Inc." && version && version[1] < 8)) {
2215
-
3058
+ /*\
3059
+ * Paper.safari
3060
+ [ method ]
3061
+ **
3062
+ * There is an inconvenient rendering bug in Safari (WebKit):
3063
+ * sometimes the rendering should be forced.
3064
+ * This method should help with dealing with this bug.
3065
+ \*/
2216
3066
  paperproto.safari = function () {
2217
3067
  var rect = this.rect(-99, -99, this.width + 99, this.height + 99).attr({stroke: "none"});
2218
3068
  setTimeout(function () {rect.remove();});
@@ -2220,7 +3070,7 @@
2220
3070
  } else {
2221
3071
  paperproto.safari = fun;
2222
3072
  }
2223
-
3073
+
2224
3074
  var preventDefault = function () {
2225
3075
  this.returnValue = false;
2226
3076
  },
@@ -2233,19 +3083,31 @@
2233
3083
  stopTouch = function () {
2234
3084
  return this.originalEvent.stopPropagation();
2235
3085
  },
3086
+ getEventPosition = function (e) {
3087
+ var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,
3088
+ scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft;
3089
+
3090
+ return {
3091
+ x: e.clientX + scrollX,
3092
+ y: e.clientY + scrollY
3093
+ };
3094
+ },
2236
3095
  addEvent = (function () {
2237
3096
  if (g.doc.addEventListener) {
2238
3097
  return function (obj, type, fn, element) {
2239
- var realName = supportsTouch && touchMap[type] ? touchMap[type] : type,
2240
- f = function (e) {
2241
- var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,
2242
- scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft,
2243
- x = e.clientX + scrollX,
2244
- y = e.clientY + scrollY;
2245
- if (supportsTouch && touchMap[has](type)) {
3098
+ var f = function (e) {
3099
+ var pos = getEventPosition(e);
3100
+ return fn.call(element, e, pos.x, pos.y);
3101
+ };
3102
+ obj.addEventListener(type, f, false);
3103
+
3104
+ if (supportsTouch && touchMap[type]) {
3105
+ var _f = function (e) {
3106
+ var pos = getEventPosition(e),
3107
+ olde = e;
3108
+
2246
3109
  for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) {
2247
3110
  if (e.targetTouches[i].target == obj) {
2248
- var olde = e;
2249
3111
  e = e.targetTouches[i];
2250
3112
  e.originalEvent = olde;
2251
3113
  e.preventDefault = preventTouch;
@@ -2253,12 +3115,18 @@
2253
3115
  break;
2254
3116
  }
2255
3117
  }
2256
- }
2257
- return fn.call(element, e, x, y);
2258
- };
2259
- obj.addEventListener(realName, f, false);
3118
+
3119
+ return fn.call(element, e, pos.x, pos.y);
3120
+ };
3121
+ obj.addEventListener(touchMap[type], _f, false);
3122
+ }
3123
+
2260
3124
  return function () {
2261
- obj.removeEventListener(realName, f, false);
3125
+ obj.removeEventListener(type, f, false);
3126
+
3127
+ if (supportsTouch && touchMap[type])
3128
+ obj.removeEventListener(touchMap[type], f, false);
3129
+
2262
3130
  return true;
2263
3131
  };
2264
3132
  };
@@ -2293,7 +3161,7 @@
2293
3161
  j = drag.length;
2294
3162
  while (j--) {
2295
3163
  dragi = drag[j];
2296
- if (supportsTouch) {
3164
+ if (supportsTouch && e.touches) {
2297
3165
  var i = e.touches.length,
2298
3166
  touch;
2299
3167
  while (i--) {
@@ -2335,40 +3203,229 @@
2335
3203
  }
2336
3204
  drag = [];
2337
3205
  },
2338
-
3206
+ /*\
3207
+ * Raphael.el
3208
+ [ property (object) ]
3209
+ **
3210
+ * You can add your own method to elements. This is usefull when you want to hack default functionality or
3211
+ * want to wrap some common transformation or attributes in one method. In difference to canvas methods,
3212
+ * you can redefine element method at any time. Expending element methods wouldn’t affect set.
3213
+ > Usage
3214
+ | Raphael.el.red = function () {
3215
+ | this.attr({fill: "#f00"});
3216
+ | };
3217
+ | // then use it
3218
+ | paper.circle(100, 100, 20).red();
3219
+ \*/
2339
3220
  elproto = R.el = {};
2340
-
2341
-
2342
-
2343
-
2344
-
2345
-
2346
-
2347
-
2348
-
2349
-
2350
-
2351
-
2352
-
2353
-
2354
-
2355
-
2356
-
2357
-
2358
-
2359
-
2360
-
2361
-
2362
-
2363
-
2364
-
2365
-
2366
-
2367
-
2368
-
2369
-
2370
-
2371
-
3221
+ /*\
3222
+ * Element.click
3223
+ [ method ]
3224
+ **
3225
+ * Adds event handler for click for the element.
3226
+ > Parameters
3227
+ - handler (function) handler for the event
3228
+ = (object) @Element
3229
+ \*/
3230
+ /*\
3231
+ * Element.unclick
3232
+ [ method ]
3233
+ **
3234
+ * Removes event handler for click for the element.
3235
+ > Parameters
3236
+ - handler (function) #optional handler for the event
3237
+ = (object) @Element
3238
+ \*/
3239
+
3240
+ /*\
3241
+ * Element.dblclick
3242
+ [ method ]
3243
+ **
3244
+ * Adds event handler for double click for the element.
3245
+ > Parameters
3246
+ - handler (function) handler for the event
3247
+ = (object) @Element
3248
+ \*/
3249
+ /*\
3250
+ * Element.undblclick
3251
+ [ method ]
3252
+ **
3253
+ * Removes event handler for double click for the element.
3254
+ > Parameters
3255
+ - handler (function) #optional handler for the event
3256
+ = (object) @Element
3257
+ \*/
3258
+
3259
+ /*\
3260
+ * Element.mousedown
3261
+ [ method ]
3262
+ **
3263
+ * Adds event handler for mousedown for the element.
3264
+ > Parameters
3265
+ - handler (function) handler for the event
3266
+ = (object) @Element
3267
+ \*/
3268
+ /*\
3269
+ * Element.unmousedown
3270
+ [ method ]
3271
+ **
3272
+ * Removes event handler for mousedown for the element.
3273
+ > Parameters
3274
+ - handler (function) #optional handler for the event
3275
+ = (object) @Element
3276
+ \*/
3277
+
3278
+ /*\
3279
+ * Element.mousemove
3280
+ [ method ]
3281
+ **
3282
+ * Adds event handler for mousemove for the element.
3283
+ > Parameters
3284
+ - handler (function) handler for the event
3285
+ = (object) @Element
3286
+ \*/
3287
+ /*\
3288
+ * Element.unmousemove
3289
+ [ method ]
3290
+ **
3291
+ * Removes event handler for mousemove for the element.
3292
+ > Parameters
3293
+ - handler (function) #optional handler for the event
3294
+ = (object) @Element
3295
+ \*/
3296
+
3297
+ /*\
3298
+ * Element.mouseout
3299
+ [ method ]
3300
+ **
3301
+ * Adds event handler for mouseout for the element.
3302
+ > Parameters
3303
+ - handler (function) handler for the event
3304
+ = (object) @Element
3305
+ \*/
3306
+ /*\
3307
+ * Element.unmouseout
3308
+ [ method ]
3309
+ **
3310
+ * Removes event handler for mouseout for the element.
3311
+ > Parameters
3312
+ - handler (function) #optional handler for the event
3313
+ = (object) @Element
3314
+ \*/
3315
+
3316
+ /*\
3317
+ * Element.mouseover
3318
+ [ method ]
3319
+ **
3320
+ * Adds event handler for mouseover for the element.
3321
+ > Parameters
3322
+ - handler (function) handler for the event
3323
+ = (object) @Element
3324
+ \*/
3325
+ /*\
3326
+ * Element.unmouseover
3327
+ [ method ]
3328
+ **
3329
+ * Removes event handler for mouseover for the element.
3330
+ > Parameters
3331
+ - handler (function) #optional handler for the event
3332
+ = (object) @Element
3333
+ \*/
3334
+
3335
+ /*\
3336
+ * Element.mouseup
3337
+ [ method ]
3338
+ **
3339
+ * Adds event handler for mouseup for the element.
3340
+ > Parameters
3341
+ - handler (function) handler for the event
3342
+ = (object) @Element
3343
+ \*/
3344
+ /*\
3345
+ * Element.unmouseup
3346
+ [ method ]
3347
+ **
3348
+ * Removes event handler for mouseup for the element.
3349
+ > Parameters
3350
+ - handler (function) #optional handler for the event
3351
+ = (object) @Element
3352
+ \*/
3353
+
3354
+ /*\
3355
+ * Element.touchstart
3356
+ [ method ]
3357
+ **
3358
+ * Adds event handler for touchstart for the element.
3359
+ > Parameters
3360
+ - handler (function) handler for the event
3361
+ = (object) @Element
3362
+ \*/
3363
+ /*\
3364
+ * Element.untouchstart
3365
+ [ method ]
3366
+ **
3367
+ * Removes event handler for touchstart for the element.
3368
+ > Parameters
3369
+ - handler (function) #optional handler for the event
3370
+ = (object) @Element
3371
+ \*/
3372
+
3373
+ /*\
3374
+ * Element.touchmove
3375
+ [ method ]
3376
+ **
3377
+ * Adds event handler for touchmove for the element.
3378
+ > Parameters
3379
+ - handler (function) handler for the event
3380
+ = (object) @Element
3381
+ \*/
3382
+ /*\
3383
+ * Element.untouchmove
3384
+ [ method ]
3385
+ **
3386
+ * Removes event handler for touchmove for the element.
3387
+ > Parameters
3388
+ - handler (function) #optional handler for the event
3389
+ = (object) @Element
3390
+ \*/
3391
+
3392
+ /*\
3393
+ * Element.touchend
3394
+ [ method ]
3395
+ **
3396
+ * Adds event handler for touchend for the element.
3397
+ > Parameters
3398
+ - handler (function) handler for the event
3399
+ = (object) @Element
3400
+ \*/
3401
+ /*\
3402
+ * Element.untouchend
3403
+ [ method ]
3404
+ **
3405
+ * Removes event handler for touchend for the element.
3406
+ > Parameters
3407
+ - handler (function) #optional handler for the event
3408
+ = (object) @Element
3409
+ \*/
3410
+
3411
+ /*\
3412
+ * Element.touchcancel
3413
+ [ method ]
3414
+ **
3415
+ * Adds event handler for touchcancel for the element.
3416
+ > Parameters
3417
+ - handler (function) handler for the event
3418
+ = (object) @Element
3419
+ \*/
3420
+ /*\
3421
+ * Element.untouchcancel
3422
+ [ method ]
3423
+ **
3424
+ * Removes event handler for touchcancel for the element.
3425
+ > Parameters
3426
+ - handler (function) #optional handler for the event
3427
+ = (object) @Element
3428
+ \*/
2372
3429
  for (var i = events.length; i--;) {
2373
3430
  (function (eventName) {
2374
3431
  R[eventName] = elproto[eventName] = function (fn, scope) {
@@ -2381,20 +3438,48 @@
2381
3438
  R["un" + eventName] = elproto["un" + eventName] = function (fn) {
2382
3439
  var events = this.events || [],
2383
3440
  l = events.length;
2384
- while (l--) if (events[l].name == eventName && events[l].f == fn) {
2385
- events[l].unbind();
2386
- events.splice(l, 1);
2387
- !events.length && delete this.events;
2388
- return this;
3441
+ while (l--){
3442
+ if (events[l].name == eventName && (R.is(fn, "undefined") || events[l].f == fn)) {
3443
+ events[l].unbind();
3444
+ events.splice(l, 1);
3445
+ !events.length && delete this.events;
3446
+ }
2389
3447
  }
2390
3448
  return this;
2391
3449
  };
2392
3450
  })(events[i]);
2393
3451
  }
2394
-
2395
-
3452
+
3453
+ /*\
3454
+ * Element.data
3455
+ [ method ]
3456
+ **
3457
+ * Adds or retrieves given value asociated with given key.
3458
+ **
3459
+ * See also @Element.removeData
3460
+ > Parameters
3461
+ - key (string) key to store data
3462
+ - value (any) #optional value to store
3463
+ = (object) @Element
3464
+ * or, if value is not specified:
3465
+ = (any) value
3466
+ * or, if key and value are not specified:
3467
+ = (object) Key/value pairs for all the data associated with the element.
3468
+ > Usage
3469
+ | for (var i = 0, i < 5, i++) {
3470
+ | paper.circle(10 + 15 * i, 10, 10)
3471
+ | .attr({fill: "#000"})
3472
+ | .data("i", i)
3473
+ | .click(function () {
3474
+ | alert(this.data("i"));
3475
+ | });
3476
+ | }
3477
+ \*/
2396
3478
  elproto.data = function (key, value) {
2397
3479
  var data = eldata[this.id] = eldata[this.id] || {};
3480
+ if (arguments.length == 0) {
3481
+ return data;
3482
+ }
2398
3483
  if (arguments.length == 1) {
2399
3484
  if (R.is(key, "object")) {
2400
3485
  for (var i in key) if (key[has](i)) {
@@ -2409,7 +3494,16 @@
2409
3494
  eve("raphael.data.set." + this.id, this, value, key);
2410
3495
  return this;
2411
3496
  };
2412
-
3497
+ /*\
3498
+ * Element.removeData
3499
+ [ method ]
3500
+ **
3501
+ * Removes value associated with an element by given key.
3502
+ * If key is not provided, removes all the data of the element.
3503
+ > Parameters
3504
+ - key (string) #optional key
3505
+ = (object) @Element
3506
+ \*/
2413
3507
  elproto.removeData = function (key) {
2414
3508
  if (key == null) {
2415
3509
  eldata[this.id] = {};
@@ -2418,24 +3512,97 @@
2418
3512
  }
2419
3513
  return this;
2420
3514
  };
2421
-
3515
+ /*\
3516
+ * Element.getData
3517
+ [ method ]
3518
+ **
3519
+ * Retrieves the element data
3520
+ = (object) data
3521
+ \*/
3522
+ elproto.getData = function () {
3523
+ return clone(eldata[this.id] || {});
3524
+ };
3525
+ /*\
3526
+ * Element.hover
3527
+ [ method ]
3528
+ **
3529
+ * Adds event handlers for hover for the element.
3530
+ > Parameters
3531
+ - f_in (function) handler for hover in
3532
+ - f_out (function) handler for hover out
3533
+ - icontext (object) #optional context for hover in handler
3534
+ - ocontext (object) #optional context for hover out handler
3535
+ = (object) @Element
3536
+ \*/
2422
3537
  elproto.hover = function (f_in, f_out, scope_in, scope_out) {
2423
3538
  return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in);
2424
3539
  };
2425
-
3540
+ /*\
3541
+ * Element.unhover
3542
+ [ method ]
3543
+ **
3544
+ * Removes event handlers for hover for the element.
3545
+ > Parameters
3546
+ - f_in (function) handler for hover in
3547
+ - f_out (function) handler for hover out
3548
+ = (object) @Element
3549
+ \*/
2426
3550
  elproto.unhover = function (f_in, f_out) {
2427
3551
  return this.unmouseover(f_in).unmouseout(f_out);
2428
3552
  };
2429
3553
  var draggable = [];
2430
-
3554
+ /*\
3555
+ * Element.drag
3556
+ [ method ]
3557
+ **
3558
+ * Adds event handlers for drag of the element.
3559
+ > Parameters
3560
+ - onmove (function) handler for moving
3561
+ - onstart (function) handler for drag start
3562
+ - onend (function) handler for drag end
3563
+ - mcontext (object) #optional context for moving handler
3564
+ - scontext (object) #optional context for drag start handler
3565
+ - econtext (object) #optional context for drag end handler
3566
+ * Additionaly following `drag` events will be triggered: `drag.start.<id>` on start,
3567
+ * `drag.end.<id>` on end and `drag.move.<id>` on every move. When element will be dragged over another element
3568
+ * `drag.over.<id>` will be fired as well.
3569
+ *
3570
+ * Start event and start handler will be called in specified context or in context of the element with following parameters:
3571
+ o x (number) x position of the mouse
3572
+ o y (number) y position of the mouse
3573
+ o event (object) DOM event object
3574
+ * Move event and move handler will be called in specified context or in context of the element with following parameters:
3575
+ o dx (number) shift by x from the start point
3576
+ o dy (number) shift by y from the start point
3577
+ o x (number) x position of the mouse
3578
+ o y (number) y position of the mouse
3579
+ o event (object) DOM event object
3580
+ * End event and end handler will be called in specified context or in context of the element with following parameters:
3581
+ o event (object) DOM event object
3582
+ = (object) @Element
3583
+ \*/
2431
3584
  elproto.drag = function (onmove, onstart, onend, move_scope, start_scope, end_scope) {
2432
3585
  function start(e) {
2433
3586
  (e.originalEvent || e).preventDefault();
2434
- var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,
3587
+ var x = e.clientX,
3588
+ y = e.clientY,
3589
+ scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,
2435
3590
  scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft;
2436
- this._drag.x = e.clientX + scrollX;
2437
- this._drag.y = e.clientY + scrollY;
2438
3591
  this._drag.id = e.identifier;
3592
+ if (supportsTouch && e.touches) {
3593
+ var i = e.touches.length, touch;
3594
+ while (i--) {
3595
+ touch = e.touches[i];
3596
+ this._drag.id = touch.identifier;
3597
+ if (touch.identifier == this._drag.id) {
3598
+ x = touch.clientX;
3599
+ y = touch.clientY;
3600
+ break;
3601
+ }
3602
+ }
3603
+ }
3604
+ this._drag.x = x + scrollX;
3605
+ this._drag.y = y + scrollY;
2439
3606
  !drag.length && R.mousemove(dragMove).mouseup(dragUp);
2440
3607
  drag.push({el: this, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope});
2441
3608
  onstart && eve.on("raphael.drag.start." + this.id, onstart);
@@ -2448,11 +3615,23 @@
2448
3615
  this.mousedown(start);
2449
3616
  return this;
2450
3617
  };
2451
-
3618
+ /*\
3619
+ * Element.onDragOver
3620
+ [ method ]
3621
+ **
3622
+ * Shortcut for assigning event handler for `drag.over.<id>` event, where id is id of the element (see @Element.id).
3623
+ > Parameters
3624
+ - f (function) handler for event, first argument would be the element you are dragging over
3625
+ \*/
2452
3626
  elproto.onDragOver = function (f) {
2453
3627
  f ? eve.on("raphael.drag.over." + this.id, f) : eve.unbind("raphael.drag.over." + this.id);
2454
3628
  };
2455
-
3629
+ /*\
3630
+ * Element.undrag
3631
+ [ method ]
3632
+ **
3633
+ * Removes all drag event handlers from given element.
3634
+ \*/
2456
3635
  elproto.undrag = function () {
2457
3636
  var i = draggable.length;
2458
3637
  while (i--) if (draggable[i].el == this) {
@@ -2461,73 +3640,265 @@
2461
3640
  eve.unbind("raphael.drag.*." + this.id);
2462
3641
  }
2463
3642
  !draggable.length && R.unmousemove(dragMove).unmouseup(dragUp);
3643
+ drag = [];
2464
3644
  };
2465
-
3645
+ /*\
3646
+ * Paper.circle
3647
+ [ method ]
3648
+ **
3649
+ * Draws a circle.
3650
+ **
3651
+ > Parameters
3652
+ **
3653
+ - x (number) x coordinate of the centre
3654
+ - y (number) y coordinate of the centre
3655
+ - r (number) radius
3656
+ = (object) Raphaël element object with type “circle”
3657
+ **
3658
+ > Usage
3659
+ | var c = paper.circle(50, 50, 40);
3660
+ \*/
2466
3661
  paperproto.circle = function (x, y, r) {
2467
3662
  var out = R._engine.circle(this, x || 0, y || 0, r || 0);
2468
3663
  this.__set__ && this.__set__.push(out);
2469
3664
  return out;
2470
3665
  };
2471
-
3666
+ /*\
3667
+ * Paper.rect
3668
+ [ method ]
3669
+ *
3670
+ * Draws a rectangle.
3671
+ **
3672
+ > Parameters
3673
+ **
3674
+ - x (number) x coordinate of the top left corner
3675
+ - y (number) y coordinate of the top left corner
3676
+ - width (number) width
3677
+ - height (number) height
3678
+ - r (number) #optional radius for rounded corners, default is 0
3679
+ = (object) Raphaël element object with type “rect”
3680
+ **
3681
+ > Usage
3682
+ | // regular rectangle
3683
+ | var c = paper.rect(10, 10, 50, 50);
3684
+ | // rectangle with rounded corners
3685
+ | var c = paper.rect(40, 40, 50, 50, 10);
3686
+ \*/
2472
3687
  paperproto.rect = function (x, y, w, h, r) {
2473
3688
  var out = R._engine.rect(this, x || 0, y || 0, w || 0, h || 0, r || 0);
2474
3689
  this.__set__ && this.__set__.push(out);
2475
3690
  return out;
2476
3691
  };
2477
-
3692
+ /*\
3693
+ * Paper.ellipse
3694
+ [ method ]
3695
+ **
3696
+ * Draws an ellipse.
3697
+ **
3698
+ > Parameters
3699
+ **
3700
+ - x (number) x coordinate of the centre
3701
+ - y (number) y coordinate of the centre
3702
+ - rx (number) horizontal radius
3703
+ - ry (number) vertical radius
3704
+ = (object) Raphaël element object with type “ellipse”
3705
+ **
3706
+ > Usage
3707
+ | var c = paper.ellipse(50, 50, 40, 20);
3708
+ \*/
2478
3709
  paperproto.ellipse = function (x, y, rx, ry) {
2479
3710
  var out = R._engine.ellipse(this, x || 0, y || 0, rx || 0, ry || 0);
2480
3711
  this.__set__ && this.__set__.push(out);
2481
3712
  return out;
2482
3713
  };
2483
-
3714
+ /*\
3715
+ * Paper.path
3716
+ [ method ]
3717
+ **
3718
+ * Creates a path element by given path data string.
3719
+ > Parameters
3720
+ - pathString (string) #optional path string in SVG format.
3721
+ * Path string consists of one-letter commands, followed by comma seprarated arguments in numercal form. Example:
3722
+ | "M10,20L30,40"
3723
+ * Here we can see two commands: “M”, with arguments `(10, 20)` and “L” with arguments `(30, 40)`. Upper case letter mean command is absolute, lower case—relative.
3724
+ *
3725
+ # <p>Here is short list of commands available, for more details see <a href="http://www.w3.org/TR/SVG/paths.html#PathData" title="Details of a path's data attribute's format are described in the SVG specification.">SVG path string format</a>.</p>
3726
+ # <table><thead><tr><th>Command</th><th>Name</th><th>Parameters</th></tr></thead><tbody>
3727
+ # <tr><td>M</td><td>moveto</td><td>(x y)+</td></tr>
3728
+ # <tr><td>Z</td><td>closepath</td><td>(none)</td></tr>
3729
+ # <tr><td>L</td><td>lineto</td><td>(x y)+</td></tr>
3730
+ # <tr><td>H</td><td>horizontal lineto</td><td>x+</td></tr>
3731
+ # <tr><td>V</td><td>vertical lineto</td><td>y+</td></tr>
3732
+ # <tr><td>C</td><td>curveto</td><td>(x1 y1 x2 y2 x y)+</td></tr>
3733
+ # <tr><td>S</td><td>smooth curveto</td><td>(x2 y2 x y)+</td></tr>
3734
+ # <tr><td>Q</td><td>quadratic Bézier curveto</td><td>(x1 y1 x y)+</td></tr>
3735
+ # <tr><td>T</td><td>smooth quadratic Bézier curveto</td><td>(x y)+</td></tr>
3736
+ # <tr><td>A</td><td>elliptical arc</td><td>(rx ry x-axis-rotation large-arc-flag sweep-flag x y)+</td></tr>
3737
+ # <tr><td>R</td><td><a href="http://en.wikipedia.org/wiki/Catmull–Rom_spline#Catmull.E2.80.93Rom_spline">Catmull-Rom curveto</a>*</td><td>x1 y1 (x y)+</td></tr></tbody></table>
3738
+ * * “Catmull-Rom curveto” is a not standard SVG command and added in 2.0 to make life easier.
3739
+ * Note: there is a special case when path consist of just three commands: “M10,10R…z”. In this case path will smoothly connects to its beginning.
3740
+ > Usage
3741
+ | var c = paper.path("M10 10L90 90");
3742
+ | // draw a diagonal line:
3743
+ | // move to 10,10, line to 90,90
3744
+ * For example of path strings, check out these icons: http://raphaeljs.com/icons/
3745
+ \*/
2484
3746
  paperproto.path = function (pathString) {
2485
3747
  pathString && !R.is(pathString, string) && !R.is(pathString[0], array) && (pathString += E);
2486
3748
  var out = R._engine.path(R.format[apply](R, arguments), this);
2487
3749
  this.__set__ && this.__set__.push(out);
2488
3750
  return out;
2489
3751
  };
2490
-
3752
+ /*\
3753
+ * Paper.image
3754
+ [ method ]
3755
+ **
3756
+ * Embeds an image into the surface.
3757
+ **
3758
+ > Parameters
3759
+ **
3760
+ - src (string) URI of the source image
3761
+ - x (number) x coordinate position
3762
+ - y (number) y coordinate position
3763
+ - width (number) width of the image
3764
+ - height (number) height of the image
3765
+ = (object) Raphaël element object with type “image”
3766
+ **
3767
+ > Usage
3768
+ | var c = paper.image("apple.png", 10, 10, 80, 80);
3769
+ \*/
2491
3770
  paperproto.image = function (src, x, y, w, h) {
2492
3771
  var out = R._engine.image(this, src || "about:blank", x || 0, y || 0, w || 0, h || 0);
2493
3772
  this.__set__ && this.__set__.push(out);
2494
3773
  return out;
2495
3774
  };
2496
-
3775
+ /*\
3776
+ * Paper.text
3777
+ [ method ]
3778
+ **
3779
+ * Draws a text string. If you need line breaks, put “\n” in the string.
3780
+ **
3781
+ > Parameters
3782
+ **
3783
+ - x (number) x coordinate position
3784
+ - y (number) y coordinate position
3785
+ - text (string) The text string to draw
3786
+ = (object) Raphaël element object with type “text”
3787
+ **
3788
+ > Usage
3789
+ | var t = paper.text(50, 50, "Raphaël\nkicks\nbutt!");
3790
+ \*/
2497
3791
  paperproto.text = function (x, y, text) {
2498
3792
  var out = R._engine.text(this, x || 0, y || 0, Str(text));
2499
3793
  this.__set__ && this.__set__.push(out);
2500
3794
  return out;
2501
3795
  };
2502
-
3796
+ /*\
3797
+ * Paper.set
3798
+ [ method ]
3799
+ **
3800
+ * Creates array-like object to keep and operate several elements at once.
3801
+ * Warning: it doesn’t create any elements for itself in the page, it just groups existing elements.
3802
+ * Sets act as pseudo elements — all methods available to an element can be used on a set.
3803
+ = (object) array-like object that represents set of elements
3804
+ **
3805
+ > Usage
3806
+ | var st = paper.set();
3807
+ | st.push(
3808
+ | paper.circle(10, 10, 5),
3809
+ | paper.circle(30, 10, 5)
3810
+ | );
3811
+ | st.attr({fill: "red"}); // changes the fill of both circles
3812
+ \*/
2503
3813
  paperproto.set = function (itemsArray) {
2504
3814
  !R.is(itemsArray, "array") && (itemsArray = Array.prototype.splice.call(arguments, 0, arguments.length));
2505
3815
  var out = new Set(itemsArray);
2506
3816
  this.__set__ && this.__set__.push(out);
3817
+ out["paper"] = this;
3818
+ out["type"] = "set";
2507
3819
  return out;
2508
3820
  };
2509
-
3821
+ /*\
3822
+ * Paper.setStart
3823
+ [ method ]
3824
+ **
3825
+ * Creates @Paper.set. All elements that will be created after calling this method and before calling
3826
+ * @Paper.setFinish will be added to the set.
3827
+ **
3828
+ > Usage
3829
+ | paper.setStart();
3830
+ | paper.circle(10, 10, 5),
3831
+ | paper.circle(30, 10, 5)
3832
+ | var st = paper.setFinish();
3833
+ | st.attr({fill: "red"}); // changes the fill of both circles
3834
+ \*/
2510
3835
  paperproto.setStart = function (set) {
2511
3836
  this.__set__ = set || this.set();
2512
3837
  };
2513
-
3838
+ /*\
3839
+ * Paper.setFinish
3840
+ [ method ]
3841
+ **
3842
+ * See @Paper.setStart. This method finishes catching and returns resulting set.
3843
+ **
3844
+ = (object) set
3845
+ \*/
2514
3846
  paperproto.setFinish = function (set) {
2515
3847
  var out = this.__set__;
2516
3848
  delete this.__set__;
2517
3849
  return out;
2518
3850
  };
2519
-
3851
+ /*\
3852
+ * Paper.setSize
3853
+ [ method ]
3854
+ **
3855
+ * If you need to change dimensions of the canvas call this method
3856
+ **
3857
+ > Parameters
3858
+ **
3859
+ - width (number) new width of the canvas
3860
+ - height (number) new height of the canvas
3861
+ \*/
2520
3862
  paperproto.setSize = function (width, height) {
2521
3863
  return R._engine.setSize.call(this, width, height);
2522
3864
  };
2523
-
3865
+ /*\
3866
+ * Paper.setViewBox
3867
+ [ method ]
3868
+ **
3869
+ * Sets the view box of the paper. Practically it gives you ability to zoom and pan whole paper surface by
3870
+ * specifying new boundaries.
3871
+ **
3872
+ > Parameters
3873
+ **
3874
+ - x (number) new x position, default is `0`
3875
+ - y (number) new y position, default is `0`
3876
+ - w (number) new width of the canvas
3877
+ - h (number) new height of the canvas
3878
+ - fit (boolean) `true` if you want graphics to fit into new boundary box
3879
+ \*/
2524
3880
  paperproto.setViewBox = function (x, y, w, h, fit) {
2525
3881
  return R._engine.setViewBox.call(this, x, y, w, h, fit);
2526
3882
  };
2527
-
2528
-
3883
+ /*\
3884
+ * Paper.top
3885
+ [ property ]
3886
+ **
3887
+ * Points to the topmost element on the paper
3888
+ \*/
3889
+ /*\
3890
+ * Paper.bottom
3891
+ [ property ]
3892
+ **
3893
+ * Points to the bottom element on the paper
3894
+ \*/
2529
3895
  paperproto.top = paperproto.bottom = null;
2530
-
3896
+ /*\
3897
+ * Paper.raphael
3898
+ [ property ]
3899
+ **
3900
+ * Points to the @Raphael object/function
3901
+ \*/
2531
3902
  paperproto.raphael = R;
2532
3903
  var getOffset = function (elem) {
2533
3904
  var box = elem.getBoundingClientRect(),
@@ -2542,7 +3913,20 @@
2542
3913
  x: left
2543
3914
  };
2544
3915
  };
2545
-
3916
+ /*\
3917
+ * Paper.getElementByPoint
3918
+ [ method ]
3919
+ **
3920
+ * Returns you topmost element under given point.
3921
+ **
3922
+ = (object) Raphaël element object
3923
+ > Parameters
3924
+ **
3925
+ - x (number) x coordinate from the top left corner of the window
3926
+ - y (number) y coordinate from the top left corner of the window
3927
+ > Usage
3928
+ | paper.getElementByPoint(mouseX, mouseY).attr({stroke: "#f00"});
3929
+ \*/
2546
3930
  paperproto.getElementByPoint = function (x, y) {
2547
3931
  var paper = this,
2548
3932
  svg = paper.canvas,
@@ -2568,7 +3952,39 @@
2568
3952
  target = target && target.raphael ? paper.getById(target.raphaelid) : null;
2569
3953
  return target;
2570
3954
  };
2571
-
3955
+
3956
+ /*\
3957
+ * Paper.getElementsByBBox
3958
+ [ method ]
3959
+ **
3960
+ * Returns set of elements that have an intersecting bounding box
3961
+ **
3962
+ > Parameters
3963
+ **
3964
+ - bbox (object) bbox to check with
3965
+ = (object) @Set
3966
+ \*/
3967
+ paperproto.getElementsByBBox = function (bbox) {
3968
+ var set = this.set();
3969
+ this.forEach(function (el) {
3970
+ if (R.isBBoxIntersect(el.getBBox(), bbox)) {
3971
+ set.push(el);
3972
+ }
3973
+ });
3974
+ return set;
3975
+ };
3976
+
3977
+ /*\
3978
+ * Paper.getById
3979
+ [ method ]
3980
+ **
3981
+ * Returns you element by its internal ID.
3982
+ **
3983
+ > Parameters
3984
+ **
3985
+ - id (number) id
3986
+ = (object) Raphaël element object
3987
+ \*/
2572
3988
  paperproto.getById = function (id) {
2573
3989
  var bot = this.bottom;
2574
3990
  while (bot) {
@@ -2579,7 +3995,24 @@
2579
3995
  }
2580
3996
  return null;
2581
3997
  };
2582
-
3998
+ /*\
3999
+ * Paper.forEach
4000
+ [ method ]
4001
+ **
4002
+ * Executes given function for each element on the paper
4003
+ *
4004
+ * If callback function returns `false` it will stop loop running.
4005
+ **
4006
+ > Parameters
4007
+ **
4008
+ - callback (function) function to run
4009
+ - thisArg (object) context object for the callback
4010
+ = (object) Paper object
4011
+ > Usage
4012
+ | paper.forEach(function (el) {
4013
+ | el.attr({ stroke: "blue" });
4014
+ | });
4015
+ \*/
2583
4016
  paperproto.forEach = function (callback, thisArg) {
2584
4017
  var bot = this.bottom;
2585
4018
  while (bot) {
@@ -2590,7 +4023,18 @@
2590
4023
  }
2591
4024
  return this;
2592
4025
  };
2593
-
4026
+ /*\
4027
+ * Paper.getElementsByPoint
4028
+ [ method ]
4029
+ **
4030
+ * Returns set of elements that have common point inside
4031
+ **
4032
+ > Parameters
4033
+ **
4034
+ - x (number) x coordinate of the point
4035
+ - y (number) y coordinate of the point
4036
+ = (object) @Set
4037
+ \*/
2594
4038
  paperproto.getElementsByPoint = function (x, y) {
2595
4039
  var set = this.set();
2596
4040
  this.forEach(function (el) {
@@ -2606,12 +4050,44 @@
2606
4050
  function x_y_w_h() {
2607
4051
  return this.x + S + this.y + S + this.width + " \xd7 " + this.height;
2608
4052
  }
2609
-
4053
+ /*\
4054
+ * Element.isPointInside
4055
+ [ method ]
4056
+ **
4057
+ * Determine if given point is inside this element’s shape
4058
+ **
4059
+ > Parameters
4060
+ **
4061
+ - x (number) x coordinate of the point
4062
+ - y (number) y coordinate of the point
4063
+ = (boolean) `true` if point inside the shape
4064
+ \*/
2610
4065
  elproto.isPointInside = function (x, y) {
2611
- var rp = this.realPath = this.realPath || getPath[this.type](this);
4066
+ var rp = this.realPath = getPath[this.type](this);
4067
+ if (this.attr('transform') && this.attr('transform').length) {
4068
+ rp = R.transformPath(rp, this.attr('transform'));
4069
+ }
2612
4070
  return R.isPointInsidePath(rp, x, y);
2613
4071
  };
2614
-
4072
+ /*\
4073
+ * Element.getBBox
4074
+ [ method ]
4075
+ **
4076
+ * Return bounding box for a given element
4077
+ **
4078
+ > Parameters
4079
+ **
4080
+ - isWithoutTransform (boolean) flag, `true` if you want to have bounding box before transformations. Default is `false`.
4081
+ = (object) Bounding box object:
4082
+ o {
4083
+ o x: (number) top left corner x
4084
+ o y: (number) top left corner y
4085
+ o x2: (number) bottom right corner x
4086
+ o y2: (number) bottom right corner y
4087
+ o width: (number) width
4088
+ o height: (number) height
4089
+ o }
4090
+ \*/
2615
4091
  elproto.getBBox = function (isWithoutTransform) {
2616
4092
  if (this.removed) {
2617
4093
  return {};
@@ -2637,7 +4113,13 @@
2637
4113
  }
2638
4114
  return _.bbox;
2639
4115
  };
2640
-
4116
+ /*\
4117
+ * Element.clone
4118
+ [ method ]
4119
+ **
4120
+ = (object) clone of a given element
4121
+ **
4122
+ \*/
2641
4123
  elproto.clone = function () {
2642
4124
  if (this.removed) {
2643
4125
  return null;
@@ -2646,7 +4128,27 @@
2646
4128
  this.__set__ && this.__set__.push(out);
2647
4129
  return out;
2648
4130
  };
2649
-
4131
+ /*\
4132
+ * Element.glow
4133
+ [ method ]
4134
+ **
4135
+ * Return set of elements that create glow-like effect around given element. See @Paper.set.
4136
+ *
4137
+ * Note: Glow is not connected to the element. If you change element attributes it won’t adjust itself.
4138
+ **
4139
+ > Parameters
4140
+ **
4141
+ - glow (object) #optional parameters object with all properties optional:
4142
+ o {
4143
+ o width (number) size of the glow, default is `10`
4144
+ o fill (boolean) will it be filled, default is `false`
4145
+ o opacity (number) opacity, default is `0.5`
4146
+ o offsetx (number) horizontal offset, default is `0`
4147
+ o offsety (number) vertical offset, default is `0`
4148
+ o color (string) glow colour, default is `black`
4149
+ o }
4150
+ = (object) @Paper.set of elements that represents glow
4151
+ \*/
2650
4152
  elproto.glow = function (glow) {
2651
4153
  if (this.type == "text") {
2652
4154
  return null;
@@ -2729,11 +4231,52 @@
2729
4231
  var getTotalLength = getLengthFactory(1),
2730
4232
  getPointAtLength = getLengthFactory(),
2731
4233
  getSubpathsAtLength = getLengthFactory(0, 1);
2732
-
4234
+ /*\
4235
+ * Raphael.getTotalLength
4236
+ [ method ]
4237
+ **
4238
+ * Returns length of the given path in pixels.
4239
+ **
4240
+ > Parameters
4241
+ **
4242
+ - path (string) SVG path string.
4243
+ **
4244
+ = (number) length.
4245
+ \*/
2733
4246
  R.getTotalLength = getTotalLength;
2734
-
4247
+ /*\
4248
+ * Raphael.getPointAtLength
4249
+ [ method ]
4250
+ **
4251
+ * Return coordinates of the point located at the given length on the given path.
4252
+ **
4253
+ > Parameters
4254
+ **
4255
+ - path (string) SVG path string
4256
+ - length (number)
4257
+ **
4258
+ = (object) representation of the point:
4259
+ o {
4260
+ o x: (number) x coordinate
4261
+ o y: (number) y coordinate
4262
+ o alpha: (number) angle of derivative
4263
+ o }
4264
+ \*/
2735
4265
  R.getPointAtLength = getPointAtLength;
2736
-
4266
+ /*\
4267
+ * Raphael.getSubpath
4268
+ [ method ]
4269
+ **
4270
+ * Return subpath of a given path from given length to given length.
4271
+ **
4272
+ > Parameters
4273
+ **
4274
+ - path (string) SVG path string
4275
+ - from (number) position of the start of the segment
4276
+ - to (number) position of the end of the segment
4277
+ **
4278
+ = (string) pathstring for the segment
4279
+ \*/
2737
4280
  R.getSubpath = function (path, from, to) {
2738
4281
  if (this.getTotalLength(path) - to < 1e-6) {
2739
4282
  return getSubpathsAtLength(path, from).end;
@@ -2741,25 +4284,110 @@
2741
4284
  var a = getSubpathsAtLength(path, to, 1);
2742
4285
  return from ? getSubpathsAtLength(a, from).end : a;
2743
4286
  };
2744
-
4287
+ /*\
4288
+ * Element.getTotalLength
4289
+ [ method ]
4290
+ **
4291
+ * Returns length of the path in pixels. Only works for element of “path” type.
4292
+ = (number) length.
4293
+ \*/
2745
4294
  elproto.getTotalLength = function () {
2746
- if (this.type != "path") {return;}
4295
+ var path = this.getPath();
4296
+ if (!path) {
4297
+ return;
4298
+ }
4299
+
2747
4300
  if (this.node.getTotalLength) {
2748
4301
  return this.node.getTotalLength();
2749
4302
  }
2750
- return getTotalLength(this.attrs.path);
2751
- };
2752
-
4303
+
4304
+ return getTotalLength(path);
4305
+ };
4306
+ /*\
4307
+ * Element.getPointAtLength
4308
+ [ method ]
4309
+ **
4310
+ * Return coordinates of the point located at the given length on the given path. Only works for element of “path” type.
4311
+ **
4312
+ > Parameters
4313
+ **
4314
+ - length (number)
4315
+ **
4316
+ = (object) representation of the point:
4317
+ o {
4318
+ o x: (number) x coordinate
4319
+ o y: (number) y coordinate
4320
+ o alpha: (number) angle of derivative
4321
+ o }
4322
+ \*/
2753
4323
  elproto.getPointAtLength = function (length) {
2754
- if (this.type != "path") {return;}
2755
- return getPointAtLength(this.attrs.path, length);
2756
- };
2757
-
4324
+ var path = this.getPath();
4325
+ if (!path) {
4326
+ return;
4327
+ }
4328
+
4329
+ return getPointAtLength(path, length);
4330
+ };
4331
+ /*\
4332
+ * Element.getPath
4333
+ [ method ]
4334
+ **
4335
+ * Returns path of the element. Only works for elements of “path” type and simple elements like circle.
4336
+ = (object) path
4337
+ **
4338
+ \*/
4339
+ elproto.getPath = function () {
4340
+ var path,
4341
+ getPath = R._getPath[this.type];
4342
+
4343
+ if (this.type == "text" || this.type == "set") {
4344
+ return;
4345
+ }
4346
+
4347
+ if (getPath) {
4348
+ path = getPath(this);
4349
+ }
4350
+
4351
+ return path;
4352
+ };
4353
+ /*\
4354
+ * Element.getSubpath
4355
+ [ method ]
4356
+ **
4357
+ * Return subpath of a given element from given length to given length. Only works for element of “path” type.
4358
+ **
4359
+ > Parameters
4360
+ **
4361
+ - from (number) position of the start of the segment
4362
+ - to (number) position of the end of the segment
4363
+ **
4364
+ = (string) pathstring for the segment
4365
+ \*/
2758
4366
  elproto.getSubpath = function (from, to) {
2759
- if (this.type != "path") {return;}
2760
- return R.getSubpath(this.attrs.path, from, to);
2761
- };
2762
-
4367
+ var path = this.getPath();
4368
+ if (!path) {
4369
+ return;
4370
+ }
4371
+
4372
+ return R.getSubpath(path, from, to);
4373
+ };
4374
+ /*\
4375
+ * Raphael.easing_formulas
4376
+ [ property ]
4377
+ **
4378
+ * Object that contains easing formulas for animation. You could extend it with your own. By default it has following list of easing:
4379
+ # <ul>
4380
+ # <li>“linear”</li>
4381
+ # <li>“&lt;” or “easeIn” or “ease-in”</li>
4382
+ # <li>“>” or “easeOut” or “ease-out”</li>
4383
+ # <li>“&lt;>” or “easeInOut” or “ease-in-out”</li>
4384
+ # <li>“backIn” or “back-in”</li>
4385
+ # <li>“backOut” or “back-out”</li>
4386
+ # <li>“elastic”</li>
4387
+ # <li>“bounce”</li>
4388
+ # </ul>
4389
+ # <p>See also <a href="http://raphaeljs.com/easing.html">Easing demo</a>.</p>
4390
+ \*/
2763
4391
  var ef = R.easing_formulas = {
2764
4392
  linear: function (n) {
2765
4393
  return n;
@@ -2960,7 +4588,27 @@
2960
4588
  upto255 = function (color) {
2961
4589
  return color > 255 ? 255 : color < 0 ? 0 : color;
2962
4590
  };
2963
-
4591
+ /*\
4592
+ * Element.animateWith
4593
+ [ method ]
4594
+ **
4595
+ * Acts similar to @Element.animate, but ensure that given animation runs in sync with another given element.
4596
+ **
4597
+ > Parameters
4598
+ **
4599
+ - el (object) element to sync with
4600
+ - anim (object) animation to sync with
4601
+ - params (object) #optional final attributes for the element, see also @Element.attr
4602
+ - ms (number) #optional number of milliseconds for animation to run
4603
+ - easing (string) #optional easing type. Accept on of @Raphael.easing_formulas or CSS format: `cubic&#x2010;bezier(XX,&#160;XX,&#160;XX,&#160;XX)`
4604
+ - callback (function) #optional callback function. Will be called at the end of animation.
4605
+ * or
4606
+ - element (object) element to sync with
4607
+ - anim (object) animation to sync with
4608
+ - animation (object) #optional animation object, see @Raphael.animation
4609
+ **
4610
+ = (object) original element
4611
+ \*/
2964
4612
  elproto.animateWith = function (el, anim, params, ms, easing, callback) {
2965
4613
  var element = this;
2966
4614
  if (element.removed) {
@@ -3055,15 +4703,40 @@
3055
4703
  this.top = percents[percents.length - 1];
3056
4704
  this.percents = percents;
3057
4705
  }
3058
-
4706
+ /*\
4707
+ * Animation.delay
4708
+ [ method ]
4709
+ **
4710
+ * Creates a copy of existing animation object with given delay.
4711
+ **
4712
+ > Parameters
4713
+ **
4714
+ - delay (number) number of ms to pass between animation start and actual animation
4715
+ **
4716
+ = (object) new altered Animation object
4717
+ | var anim = Raphael.animation({cx: 10, cy: 20}, 2e3);
4718
+ | circle1.animate(anim); // run the given animation immediately
4719
+ | circle2.animate(anim.delay(500)); // run the given animation after 500 ms
4720
+ \*/
3059
4721
  Animation.prototype.delay = function (delay) {
3060
4722
  var a = new Animation(this.anim, this.ms);
3061
4723
  a.times = this.times;
3062
4724
  a.del = +delay || 0;
3063
4725
  return a;
3064
4726
  };
3065
-
3066
- Animation.prototype.repeat = function (times) {
4727
+ /*\
4728
+ * Animation.repeat
4729
+ [ method ]
4730
+ **
4731
+ * Creates a copy of existing animation object with given repetition.
4732
+ **
4733
+ > Parameters
4734
+ **
4735
+ - repeat (number) number iterations of animation. For infinite animation pass `Infinity`
4736
+ **
4737
+ = (object) new altered Animation object
4738
+ \*/
4739
+ Animation.prototype.repeat = function (times) {
3067
4740
  var a = new Animation(this.anim, this.ms);
3068
4741
  a.del = this.del;
3069
4742
  a.times = math.floor(mmax(times, 0)) || 1;
@@ -3275,7 +4948,22 @@
3275
4948
  }
3276
4949
  eve("raphael.anim.start." + element.id, element, anim);
3277
4950
  }
3278
-
4951
+ /*\
4952
+ * Raphael.animation
4953
+ [ method ]
4954
+ **
4955
+ * Creates an animation object that can be passed to the @Element.animate or @Element.animateWith methods.
4956
+ * See also @Animation.delay and @Animation.repeat methods.
4957
+ **
4958
+ > Parameters
4959
+ **
4960
+ - params (object) final attributes for the element, see also @Element.attr
4961
+ - ms (number) number of milliseconds for animation to run
4962
+ - easing (string) #optional easing type. Accept one of @Raphael.easing_formulas or CSS format: `cubic&#x2010;bezier(XX,&#160;XX,&#160;XX,&#160;XX)`
4963
+ - callback (function) #optional callback function. Will be called at the end of animation.
4964
+ **
4965
+ = (object) @Animation
4966
+ \*/
3279
4967
  R.animation = function (params, ms, easing, callback) {
3280
4968
  if (params instanceof Animation) {
3281
4969
  return params;
@@ -3301,7 +4989,23 @@
3301
4989
  return new Animation({100: p}, ms);
3302
4990
  }
3303
4991
  };
3304
-
4992
+ /*\
4993
+ * Element.animate
4994
+ [ method ]
4995
+ **
4996
+ * Creates and starts animation for given element.
4997
+ **
4998
+ > Parameters
4999
+ **
5000
+ - params (object) final attributes for the element, see also @Element.attr
5001
+ - ms (number) number of milliseconds for animation to run
5002
+ - easing (string) #optional easing type. Accept one of @Raphael.easing_formulas or CSS format: `cubic&#x2010;bezier(XX,&#160;XX,&#160;XX,&#160;XX)`
5003
+ - callback (function) #optional callback function. Will be called at the end of animation.
5004
+ * or
5005
+ - animation (object) animation object, see @Raphael.animation
5006
+ **
5007
+ = (object) original element
5008
+ \*/
3305
5009
  elproto.animate = function (params, ms, easing, callback) {
3306
5010
  var element = this;
3307
5011
  if (element.removed) {
@@ -3312,14 +5016,49 @@
3312
5016
  runAnimation(anim, element, anim.percents[0], null, element.attr());
3313
5017
  return element;
3314
5018
  };
3315
-
5019
+ /*\
5020
+ * Element.setTime
5021
+ [ method ]
5022
+ **
5023
+ * Sets the status of animation of the element in milliseconds. Similar to @Element.status method.
5024
+ **
5025
+ > Parameters
5026
+ **
5027
+ - anim (object) animation object
5028
+ - value (number) number of milliseconds from the beginning of the animation
5029
+ **
5030
+ = (object) original element if `value` is specified
5031
+ * Note, that during animation following events are triggered:
5032
+ *
5033
+ * On each animation frame event `anim.frame.<id>`, on start `anim.start.<id>` and on end `anim.finish.<id>`.
5034
+ \*/
3316
5035
  elproto.setTime = function (anim, value) {
3317
5036
  if (anim && value != null) {
3318
5037
  this.status(anim, mmin(value, anim.ms) / anim.ms);
3319
5038
  }
3320
5039
  return this;
3321
5040
  };
3322
-
5041
+ /*\
5042
+ * Element.status
5043
+ [ method ]
5044
+ **
5045
+ * Gets or sets the status of animation of the element.
5046
+ **
5047
+ > Parameters
5048
+ **
5049
+ - anim (object) #optional animation object
5050
+ - 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.
5051
+ **
5052
+ = (number) status
5053
+ * or
5054
+ = (array) status if `anim` is not specified. Array of objects in format:
5055
+ o {
5056
+ o anim: (object) animation object
5057
+ o status: (number) status
5058
+ o }
5059
+ * or
5060
+ = (object) original element if `value` is specified
5061
+ \*/
3323
5062
  elproto.status = function (anim, value) {
3324
5063
  var out = [],
3325
5064
  i = 0,
@@ -3348,7 +5087,18 @@
3348
5087
  return out;
3349
5088
  }
3350
5089
  };
3351
-
5090
+ /*\
5091
+ * Element.pause
5092
+ [ method ]
5093
+ **
5094
+ * Stops animation of the element with ability to resume it later on.
5095
+ **
5096
+ > Parameters
5097
+ **
5098
+ - anim (object) #optional animation object
5099
+ **
5100
+ = (object) original element
5101
+ \*/
3352
5102
  elproto.pause = function (anim) {
3353
5103
  for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {
3354
5104
  if (eve("raphael.anim.pause." + this.id, this, animationElements[i].anim) !== false) {
@@ -3357,7 +5107,18 @@
3357
5107
  }
3358
5108
  return this;
3359
5109
  };
3360
-
5110
+ /*\
5111
+ * Element.resume
5112
+ [ method ]
5113
+ **
5114
+ * Resumes animation if it was paused with @Element.pause method.
5115
+ **
5116
+ > Parameters
5117
+ **
5118
+ - anim (object) #optional animation object
5119
+ **
5120
+ = (object) original element
5121
+ \*/
3361
5122
  elproto.resume = function (anim) {
3362
5123
  for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {
3363
5124
  var e = animationElements[i];
@@ -3368,7 +5129,18 @@
3368
5129
  }
3369
5130
  return this;
3370
5131
  };
3371
-
5132
+ /*\
5133
+ * Element.stop
5134
+ [ method ]
5135
+ **
5136
+ * Stops animation of the element.
5137
+ **
5138
+ > Parameters
5139
+ **
5140
+ - anim (object) #optional animation object
5141
+ **
5142
+ = (object) original element
5143
+ \*/
3372
5144
  elproto.stop = function (anim) {
3373
5145
  for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {
3374
5146
  if (eve("raphael.anim.stop." + this.id, this, animationElements[i].anim) !== false) {
@@ -3403,7 +5175,13 @@
3403
5175
  }
3404
5176
  },
3405
5177
  setproto = Set.prototype;
3406
-
5178
+ /*\
5179
+ * Set.push
5180
+ [ method ]
5181
+ **
5182
+ * Adds each argument to the current set.
5183
+ = (object) original element
5184
+ \*/
3407
5185
  setproto.push = function () {
3408
5186
  var item,
3409
5187
  len;
@@ -3417,12 +5195,31 @@
3417
5195
  }
3418
5196
  return this;
3419
5197
  };
3420
-
5198
+ /*\
5199
+ * Set.pop
5200
+ [ method ]
5201
+ **
5202
+ * Removes last element and returns it.
5203
+ = (object) element
5204
+ \*/
3421
5205
  setproto.pop = function () {
3422
5206
  this.length && delete this[this.length--];
3423
5207
  return this.items.pop();
3424
5208
  };
3425
-
5209
+ /*\
5210
+ * Set.forEach
5211
+ [ method ]
5212
+ **
5213
+ * Executes given function for each element in the set.
5214
+ *
5215
+ * If function returns `false` it will stop loop running.
5216
+ **
5217
+ > Parameters
5218
+ **
5219
+ - callback (function) function to run
5220
+ - thisArg (object) context object for the callback
5221
+ = (object) Set object
5222
+ \*/
3426
5223
  setproto.forEach = function (callback, thisArg) {
3427
5224
  for (var i = 0, ii = this.items.length; i < ii; i++) {
3428
5225
  if (callback.call(thisArg, this.items[i], i) === false) {
@@ -3453,13 +5250,30 @@
3453
5250
  }
3454
5251
  return this;
3455
5252
  };
3456
-
5253
+ /*\
5254
+ * Set.clear
5255
+ [ method ]
5256
+ **
5257
+ * Removeds all elements from the set
5258
+ \*/
3457
5259
  setproto.clear = function () {
3458
5260
  while (this.length) {
3459
5261
  this.pop();
3460
5262
  }
3461
5263
  };
3462
-
5264
+ /*\
5265
+ * Set.splice
5266
+ [ method ]
5267
+ **
5268
+ * Removes given element from the set
5269
+ **
5270
+ > Parameters
5271
+ **
5272
+ - index (number) position of the deletion
5273
+ - count (number) number of element to remove
5274
+ - insertion… (object) #optional elements to insert
5275
+ = (object) set elements that were deleted
5276
+ \*/
3463
5277
  setproto.splice = function (index, count, insertion) {
3464
5278
  index = index < 0 ? mmax(this.length + index, 0) : index;
3465
5279
  count = mmax(0, mmin(this.length - index, count));
@@ -3486,7 +5300,17 @@
3486
5300
  }
3487
5301
  return new Set(todel);
3488
5302
  };
3489
-
5303
+ /*\
5304
+ * Set.exclude
5305
+ [ method ]
5306
+ **
5307
+ * Removes given element from the set
5308
+ **
5309
+ > Parameters
5310
+ **
5311
+ - element (object) element to remove
5312
+ = (boolean) `true` if object was found & removed from the set
5313
+ \*/
3490
5314
  setproto.exclude = function (el) {
3491
5315
  for (var i = 0, ii = this.length; i < ii; i++) if (this[i] == el) {
3492
5316
  this.splice(i, 1);
@@ -3511,6 +5335,7 @@
3511
5335
  item = this.items[--i].animate(anim);
3512
5336
  while (i--) {
3513
5337
  this.items[i] && !this.items[i].removed && this.items[i].animateWith(item, anim, anim);
5338
+ (this.items[i] && !this.items[i].removed) || len--;
3514
5339
  }
3515
5340
  return this;
3516
5341
  };
@@ -3547,7 +5372,7 @@
3547
5372
  };
3548
5373
  };
3549
5374
  setproto.clone = function (s) {
3550
- s = new Set;
5375
+ s = this.paper.set();
3551
5376
  for (var i = 0, ii = this.items.length; i < ii; i++) {
3552
5377
  s.push(this.items[i].clone());
3553
5378
  }
@@ -3557,7 +5382,59 @@
3557
5382
  return "Rapha\xebl\u2018s set";
3558
5383
  };
3559
5384
 
3560
-
5385
+ setproto.glow = function(glowConfig) {
5386
+ var ret = this.paper.set();
5387
+ this.forEach(function(shape, index){
5388
+ var g = shape.glow(glowConfig);
5389
+ if(g != null){
5390
+ g.forEach(function(shape2, index2){
5391
+ ret.push(shape2);
5392
+ });
5393
+ }
5394
+ });
5395
+ return ret;
5396
+ };
5397
+
5398
+
5399
+ /*\
5400
+ * Set.isPointInside
5401
+ [ method ]
5402
+ **
5403
+ * Determine if given point is inside this set’s elements
5404
+ **
5405
+ > Parameters
5406
+ **
5407
+ - x (number) x coordinate of the point
5408
+ - y (number) y coordinate of the point
5409
+ = (boolean) `true` if point is inside any of the set's elements
5410
+ \*/
5411
+ setproto.isPointInside = function (x, y) {
5412
+ var isPointInside = false;
5413
+ this.forEach(function (el) {
5414
+ if (el.isPointInside(x, y)) {
5415
+ console.log('runned');
5416
+ isPointInside = true;
5417
+ return false; // stop loop
5418
+ }
5419
+ });
5420
+ return isPointInside;
5421
+ };
5422
+
5423
+ /*\
5424
+ * Raphael.registerFont
5425
+ [ method ]
5426
+ **
5427
+ * Adds given font to the registered set of fonts for Raphaël. Should be used as an internal call from within Cufón’s font file.
5428
+ * Returns original parameter, so it could be used with chaining.
5429
+ # <a href="http://wiki.github.com/sorccu/cufon/about">More about Cufón and how to convert your font form TTF, OTF, etc to JavaScript file.</a>
5430
+ **
5431
+ > Parameters
5432
+ **
5433
+ - font (object) the font to register
5434
+ = (object) the font you passed in
5435
+ > Usage
5436
+ | Cufon.registerFont(Raphael.registerFont({…}));
5437
+ \*/
3561
5438
  R.registerFont = function (font) {
3562
5439
  if (!font.face) {
3563
5440
  return font;
@@ -3597,7 +5474,22 @@
3597
5474
  }
3598
5475
  return font;
3599
5476
  };
3600
-
5477
+ /*\
5478
+ * Paper.getFont
5479
+ [ method ]
5480
+ **
5481
+ * Finds font object in the registered fonts by given parameters. You could specify only one word from the font name, like “Myriad” for “Myriad Pro”.
5482
+ **
5483
+ > Parameters
5484
+ **
5485
+ - family (string) font family name or any word from it
5486
+ - weight (string) #optional font weight
5487
+ - style (string) #optional font style
5488
+ - stretch (string) #optional font stretch
5489
+ = (object) the font object
5490
+ > Usage
5491
+ | paper.print(100, 100, "Test string", paper.getFont("Times", 800), 30);
5492
+ \*/
3601
5493
  paperproto.getFont = function (family, weight, style, stretch) {
3602
5494
  stretch = stretch || "normal";
3603
5495
  style = style || "normal";
@@ -3626,16 +5518,37 @@
3626
5518
  }
3627
5519
  return thefont;
3628
5520
  };
3629
-
3630
- paperproto.print = function (x, y, string, font, size, origin, letter_spacing) {
5521
+ /*\
5522
+ * Paper.print
5523
+ [ method ]
5524
+ **
5525
+ * Creates path that represent given text written using given font at given position with given size.
5526
+ * Result of the method is path element that contains whole text as a separate path.
5527
+ **
5528
+ > Parameters
5529
+ **
5530
+ - x (number) x position of the text
5531
+ - y (number) y position of the text
5532
+ - string (string) text to print
5533
+ - font (object) font object, see @Paper.getFont
5534
+ - size (number) #optional size of the font, default is `16`
5535
+ - origin (string) #optional could be `"baseline"` or `"middle"`, default is `"middle"`
5536
+ - letter_spacing (number) #optional number in range `-1..1`, default is `0`
5537
+ - line_spacing (number) #optional number in range `1..3`, default is `1`
5538
+ = (object) resulting path element, which consist of all letters
5539
+ > Usage
5540
+ | var txt = r.print(10, 50, "print", r.getFont("Museo"), 30).attr({fill: "#fff"});
5541
+ \*/
5542
+ paperproto.print = function (x, y, string, font, size, origin, letter_spacing, line_spacing) {
3631
5543
  origin = origin || "middle"; // baseline|middle
3632
5544
  letter_spacing = mmax(mmin(letter_spacing || 0, 1), -1);
5545
+ line_spacing = mmax(mmin(line_spacing || 1, 3), 1);
3633
5546
  var letters = Str(string)[split](E),
3634
5547
  shift = 0,
3635
5548
  notfirst = 0,
3636
5549
  path = E,
3637
5550
  scale;
3638
- R.is(font, string) && (font = this.getFont(font));
5551
+ R.is(font, "string") && (font = this.getFont(font));
3639
5552
  if (font) {
3640
5553
  scale = (size || 16) / font.face["units-per-em"];
3641
5554
  var bb = font.face.bbox[split](separator),
@@ -3648,7 +5561,7 @@
3648
5561
  shift = 0;
3649
5562
  curr = 0;
3650
5563
  notfirst = 0;
3651
- shifty += lineHeight;
5564
+ shifty += lineHeight * line_spacing;
3652
5565
  } else {
3653
5566
  var prev = notfirst && font.glyphs[letters[i - 1]] || {},
3654
5567
  curr = font.glyphs[letters[i]];
@@ -3666,7 +5579,34 @@
3666
5579
  });
3667
5580
  };
3668
5581
 
3669
-
5582
+ /*\
5583
+ * Paper.add
5584
+ [ method ]
5585
+ **
5586
+ * Imports elements in JSON array in format `{type: type, <attributes>}`
5587
+ **
5588
+ > Parameters
5589
+ **
5590
+ - json (array)
5591
+ = (object) resulting set of imported elements
5592
+ > Usage
5593
+ | paper.add([
5594
+ | {
5595
+ | type: "circle",
5596
+ | cx: 10,
5597
+ | cy: 10,
5598
+ | r: 5
5599
+ | },
5600
+ | {
5601
+ | type: "rect",
5602
+ | x: 10,
5603
+ | y: 10,
5604
+ | width: 10,
5605
+ | height: 10,
5606
+ | fill: "#fc0"
5607
+ | }
5608
+ | ]);
5609
+ \*/
3670
5610
  paperproto.add = function (json) {
3671
5611
  if (R.is(json, "array")) {
3672
5612
  var res = this.set(),
@@ -3681,7 +5621,25 @@
3681
5621
  return res;
3682
5622
  };
3683
5623
 
3684
-
5624
+ /*\
5625
+ * Raphael.format
5626
+ [ method ]
5627
+ **
5628
+ * Simple format function. Replaces construction of type “`{<number>}`” to the corresponding argument.
5629
+ **
5630
+ > Parameters
5631
+ **
5632
+ - token (string) string to format
5633
+ - … (string) rest of arguments will be treated as parameters for replacement
5634
+ = (string) formated string
5635
+ > Usage
5636
+ | var x = 10,
5637
+ | y = 20,
5638
+ | width = 40,
5639
+ | height = 50;
5640
+ | // this will draw a rectangular shape equivalent to "M10,20h40v50h-40z"
5641
+ | paper.path(Raphael.format("M{0},{1}h{2}v{3}h{4}z", x, y, width, height, -width));
5642
+ \*/
3685
5643
  R.format = function (token, params) {
3686
5644
  var args = R.is(params, array) ? [0][concat](params) : arguments;
3687
5645
  token && R.is(token, string) && args.length - 1 && (token = token.replace(formatrg, function (str, i) {
@@ -3689,7 +5647,29 @@
3689
5647
  }));
3690
5648
  return token || E;
3691
5649
  };
3692
-
5650
+ /*\
5651
+ * Raphael.fullfill
5652
+ [ method ]
5653
+ **
5654
+ * A little bit more advanced format function than @Raphael.format. Replaces construction of type “`{<name>}`” to the corresponding argument.
5655
+ **
5656
+ > Parameters
5657
+ **
5658
+ - token (string) string to format
5659
+ - json (object) object which properties will be used as a replacement
5660
+ = (string) formated string
5661
+ > Usage
5662
+ | // this will draw a rectangular shape equivalent to "M10,20h40v50h-40z"
5663
+ | paper.path(Raphael.fullfill("M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']}z", {
5664
+ | x: 10,
5665
+ | y: 20,
5666
+ | dim: {
5667
+ | width: 40,
5668
+ | height: 50,
5669
+ | "negative width": -40
5670
+ | }
5671
+ | }));
5672
+ \*/
3693
5673
  R.fullfill = (function () {
3694
5674
  var tokenRegex = /\{([^\}]+)\}/g,
3695
5675
  objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g, // matches .xxxxx or ["xxxxx"] to run over object properties
@@ -3713,12 +5693,44 @@
3713
5693
  });
3714
5694
  };
3715
5695
  })();
3716
-
5696
+ /*\
5697
+ * Raphael.ninja
5698
+ [ method ]
5699
+ **
5700
+ * If you want to leave no trace of Raphaël (Well, Raphaël creates only one global variable `Raphael`, but anyway.) You can use `ninja` method.
5701
+ * Beware, that in this case plugins could stop working, because they are depending on global variable existance.
5702
+ **
5703
+ = (object) Raphael object
5704
+ > Usage
5705
+ | (function (local_raphael) {
5706
+ | var paper = local_raphael(10, 10, 320, 200);
5707
+ | …
5708
+ | })(Raphael.ninja());
5709
+ \*/
3717
5710
  R.ninja = function () {
3718
5711
  oldRaphael.was ? (g.win.Raphael = oldRaphael.is) : delete Raphael;
3719
5712
  return R;
3720
5713
  };
3721
-
5714
+ /*\
5715
+ * Raphael.st
5716
+ [ property (object) ]
5717
+ **
5718
+ * You can add your own method to elements and sets. It is wise to add a set method for each element method
5719
+ * you added, so you will be able to call the same method on sets too.
5720
+ **
5721
+ * See also @Raphael.el.
5722
+ > Usage
5723
+ | Raphael.el.red = function () {
5724
+ | this.attr({fill: "#f00"});
5725
+ | };
5726
+ | Raphael.st.red = function () {
5727
+ | this.forEach(function (el) {
5728
+ | el.red();
5729
+ | });
5730
+ | };
5731
+ | // then use it
5732
+ | paper.set(paper.circle(100, 100, 20), paper.circle(110, 100, 20)).red();
5733
+ \*/
3722
5734
  R.st = setproto;
3723
5735
  // Firefox <3.6 fix: http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html
3724
5736
  (function (doc, loaded, f) {
@@ -3735,13 +5747,9 @@
3735
5747
  isLoaded();
3736
5748
  })(document, "DOMContentLoaded");
3737
5749
 
3738
- oldRaphael.was ? (g.win.Raphael = R) : (Raphael = R);
3739
-
3740
5750
  eve.on("raphael.DOMload", function () {
3741
5751
  loaded = true;
3742
5752
  });
3743
- })();
3744
-
3745
5753
 
3746
5754
  // ┌─────────────────────────────────────────────────────────────────────┐ \\
3747
5755
  // │ Raphaël - JavaScript Vector Library │ \\
@@ -3752,7 +5760,11 @@
3752
5760
  // │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\
3753
5761
  // │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\
3754
5762
  // └─────────────────────────────────────────────────────────────────────┘ \\
3755
- window.Raphael.svg && function (R) {
5763
+
5764
+ (function(){
5765
+ if (!R.svg) {
5766
+ return;
5767
+ }
3756
5768
  var has = "hasOwnProperty",
3757
5769
  Str = String,
3758
5770
  toFloat = parseFloat,
@@ -3994,7 +6006,7 @@ window.Raphael.svg && function (R) {
3994
6006
  attr = {};
3995
6007
  attr["marker-" + se] = "url(#" + markerId + ")";
3996
6008
  if (to || from) {
3997
- attr.d = Raphael.getSubpath(attrs.path, from, to);
6009
+ attr.d = R.getSubpath(attrs.path, from, to);
3998
6010
  }
3999
6011
  $(node, attr);
4000
6012
  o._.arrows[se + "Path"] = pathId;
@@ -4010,7 +6022,7 @@ window.Raphael.svg && function (R) {
4010
6022
  from = 0;
4011
6023
  to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0);
4012
6024
  }
4013
- o._.arrows[se + "Path"] && $(node, {d: Raphael.getSubpath(attrs.path, from, to)});
6025
+ o._.arrows[se + "Path"] && $(node, {d: R.getSubpath(attrs.path, from, to)});
4014
6026
  delete o._.arrows[se + "Path"];
4015
6027
  delete o._.arrows[se + "Marker"];
4016
6028
  delete o._.arrows[se + "dx"];
@@ -4068,6 +6080,11 @@ window.Raphael.svg && function (R) {
4068
6080
  break;
4069
6081
  case "href":
4070
6082
  case "title":
6083
+ var hl = $("title");
6084
+ var val = R._g.doc.createTextNode(value);
6085
+ hl.appendChild(val);
6086
+ node.appendChild(hl);
6087
+ break;
4071
6088
  case "target":
4072
6089
  var pn = node.parentNode;
4073
6090
  if (pn.tagName.toLowerCase() != "a") {
@@ -4339,16 +6356,57 @@ window.Raphael.svg && function (R) {
4339
6356
  Element = function (node, svg) {
4340
6357
  var X = 0,
4341
6358
  Y = 0;
4342
-
6359
+ /*\
6360
+ * Element.node
6361
+ [ property (object) ]
6362
+ **
6363
+ * Gives you a reference to the DOM object, so you can assign event handlers or just mess around.
6364
+ **
6365
+ * Note: Don’t mess with it.
6366
+ > Usage
6367
+ | // draw a circle at coordinate 10,10 with radius of 10
6368
+ | var c = paper.circle(10, 10, 10);
6369
+ | c.node.onclick = function () {
6370
+ | c.attr("fill", "red");
6371
+ | };
6372
+ \*/
4343
6373
  this[0] = this.node = node;
4344
-
6374
+ /*\
6375
+ * Element.raphael
6376
+ [ property (object) ]
6377
+ **
6378
+ * Internal reference to @Raphael object. In case it is not available.
6379
+ > Usage
6380
+ | Raphael.el.red = function () {
6381
+ | var hsb = this.paper.raphael.rgb2hsb(this.attr("fill"));
6382
+ | hsb.h = 1;
6383
+ | this.attr({fill: this.paper.raphael.hsb2rgb(hsb).hex});
6384
+ | }
6385
+ \*/
4345
6386
  node.raphael = true;
4346
-
6387
+ /*\
6388
+ * Element.id
6389
+ [ property (number) ]
6390
+ **
6391
+ * Unique id of the element. Especially usesful when you want to listen to events of the element,
6392
+ * because all events are fired in format `<module>.<action>.<id>`. Also useful for @Paper.getById method.
6393
+ \*/
4347
6394
  this.id = R._oid++;
4348
6395
  node.raphaelid = this.id;
4349
6396
  this.matrix = R.matrix();
4350
6397
  this.realPath = null;
4351
-
6398
+ /*\
6399
+ * Element.paper
6400
+ [ property (object) ]
6401
+ **
6402
+ * Internal reference to “paper” where object drawn. Mainly for use in plugins and element extensions.
6403
+ > Usage
6404
+ | Raphael.el.cross = function () {
6405
+ | this.attr({fill: "red"});
6406
+ | this.paper.path("M10,10L50,50M50,10L10,50")
6407
+ | .attr({stroke: "red"});
6408
+ | }
6409
+ \*/
4352
6410
  this.paper = svg;
4353
6411
  this.attrs = this.attrs || {};
4354
6412
  this._ = {
@@ -4361,11 +6419,21 @@ window.Raphael.svg && function (R) {
4361
6419
  dirty: 1
4362
6420
  };
4363
6421
  !svg.bottom && (svg.bottom = this);
4364
-
6422
+ /*\
6423
+ * Element.prev
6424
+ [ property (object) ]
6425
+ **
6426
+ * Reference to the previous element in the hierarchy.
6427
+ \*/
4365
6428
  this.prev = svg.top;
4366
6429
  svg.top && (svg.top.next = this);
4367
6430
  svg.top = this;
4368
-
6431
+ /*\
6432
+ * Element.next
6433
+ [ property (object) ]
6434
+ **
6435
+ * Reference to the next element in the hierarchy.
6436
+ \*/
4369
6437
  this.next = null;
4370
6438
  },
4371
6439
  elproto = R.el;
@@ -4385,7 +6453,20 @@ window.Raphael.svg && function (R) {
4385
6453
  });
4386
6454
  return p;
4387
6455
  };
4388
-
6456
+ /*\
6457
+ * Element.rotate
6458
+ [ method ]
6459
+ **
6460
+ * Deprecated! Use @Element.transform instead.
6461
+ * Adds rotation by given angle around given point to the list of
6462
+ * transformations of the element.
6463
+ > Parameters
6464
+ - deg (number) angle in degrees
6465
+ - cx (number) #optional x coordinate of the centre of rotation
6466
+ - cy (number) #optional y coordinate of the centre of rotation
6467
+ * If cx & cy aren’t specified centre of the shape is used as a point of rotation.
6468
+ = (object) @Element
6469
+ \*/
4389
6470
  elproto.rotate = function (deg, cx, cy) {
4390
6471
  if (this.removed) {
4391
6472
  return this;
@@ -4405,7 +6486,21 @@ window.Raphael.svg && function (R) {
4405
6486
  this.transform(this._.transform.concat([["r", deg, cx, cy]]));
4406
6487
  return this;
4407
6488
  };
4408
-
6489
+ /*\
6490
+ * Element.scale
6491
+ [ method ]
6492
+ **
6493
+ * Deprecated! Use @Element.transform instead.
6494
+ * Adds scale by given amount relative to given point to the list of
6495
+ * transformations of the element.
6496
+ > Parameters
6497
+ - sx (number) horisontal scale amount
6498
+ - sy (number) vertical scale amount
6499
+ - cx (number) #optional x coordinate of the centre of scale
6500
+ - cy (number) #optional y coordinate of the centre of scale
6501
+ * If cx & cy aren’t specified centre of the shape is used instead.
6502
+ = (object) @Element
6503
+ \*/
4409
6504
  elproto.scale = function (sx, sy, cx, cy) {
4410
6505
  if (this.removed) {
4411
6506
  return this;
@@ -4427,7 +6522,17 @@ window.Raphael.svg && function (R) {
4427
6522
  this.transform(this._.transform.concat([["s", sx, sy, cx, cy]]));
4428
6523
  return this;
4429
6524
  };
4430
-
6525
+ /*\
6526
+ * Element.translate
6527
+ [ method ]
6528
+ **
6529
+ * Deprecated! Use @Element.transform instead.
6530
+ * Adds translation by given amount to the list of transformations of the element.
6531
+ > Parameters
6532
+ - dx (number) horisontal shift
6533
+ - dy (number) vertical shift
6534
+ = (object) @Element
6535
+ \*/
4431
6536
  elproto.translate = function (dx, dy) {
4432
6537
  if (this.removed) {
4433
6538
  return this;
@@ -4441,7 +6546,43 @@ window.Raphael.svg && function (R) {
4441
6546
  this.transform(this._.transform.concat([["t", dx, dy]]));
4442
6547
  return this;
4443
6548
  };
4444
-
6549
+ /*\
6550
+ * Element.transform
6551
+ [ method ]
6552
+ **
6553
+ * Adds transformation to the element which is separate to other attributes,
6554
+ * i.e. translation doesn’t change `x` or `y` of the rectange. The format
6555
+ * of transformation string is similar to the path string syntax:
6556
+ | "t100,100r30,100,100s2,2,100,100r45s1.5"
6557
+ * Each letter is a command. There are four commands: `t` is for translate, `r` is for rotate, `s` is for
6558
+ * scale and `m` is for matrix.
6559
+ *
6560
+ * There are also alternative “absolute” translation, rotation and scale: `T`, `R` and `S`. They will not take previous transformation into account. For example, `...T100,0` will always move element 100 px horisontally, while `...t100,0` could move it vertically if there is `r90` before. Just compare results of `r90t100,0` and `r90T100,0`.
6561
+ *
6562
+ * So, the example line above could be read like “translate by 100, 100; rotate 30° around 100, 100; scale twice around 100, 100;
6563
+ * rotate 45° around centre; scale 1.5 times relative to centre”. As you can see rotate and scale commands have origin
6564
+ * coordinates as optional parameters, the default is the centre point of the element.
6565
+ * Matrix accepts six parameters.
6566
+ > Usage
6567
+ | var el = paper.rect(10, 20, 300, 200);
6568
+ | // translate 100, 100, rotate 45°, translate -100, 0
6569
+ | el.transform("t100,100r45t-100,0");
6570
+ | // if you want you can append or prepend transformations
6571
+ | el.transform("...t50,50");
6572
+ | el.transform("s2...");
6573
+ | // or even wrap
6574
+ | el.transform("t50,50...t-50-50");
6575
+ | // to reset transformation call method with empty string
6576
+ | el.transform("");
6577
+ | // to get current value call it without parameters
6578
+ | console.log(el.transform());
6579
+ > Parameters
6580
+ - tstr (string) #optional transformation string
6581
+ * If tstr isn’t specified
6582
+ = (string) current transformation string
6583
+ * else
6584
+ = (object) @Element
6585
+ \*/
4445
6586
  elproto.transform = function (tstr) {
4446
6587
  var _ = this._;
4447
6588
  if (tstr == null) {
@@ -4460,17 +6601,34 @@ window.Raphael.svg && function (R) {
4460
6601
 
4461
6602
  return this;
4462
6603
  };
4463
-
6604
+ /*\
6605
+ * Element.hide
6606
+ [ method ]
6607
+ **
6608
+ * Makes element invisible. See @Element.show.
6609
+ = (object) @Element
6610
+ \*/
4464
6611
  elproto.hide = function () {
4465
6612
  !this.removed && this.paper.safari(this.node.style.display = "none");
4466
6613
  return this;
4467
6614
  };
4468
-
6615
+ /*\
6616
+ * Element.show
6617
+ [ method ]
6618
+ **
6619
+ * Makes element visible. See @Element.hide.
6620
+ = (object) @Element
6621
+ \*/
4469
6622
  elproto.show = function () {
4470
6623
  !this.removed && this.paper.safari(this.node.style.display = "");
4471
6624
  return this;
4472
6625
  };
4473
-
6626
+ /*\
6627
+ * Element.remove
6628
+ [ method ]
6629
+ **
6630
+ * Removes element from the paper.
6631
+ \*/
4474
6632
  elproto.remove = function () {
4475
6633
  if (this.removed || !this.node.parentNode) {
4476
6634
  return;
@@ -4508,7 +6666,87 @@ window.Raphael.svg && function (R) {
4508
6666
  hide && this.hide();
4509
6667
  return bbox;
4510
6668
  };
4511
-
6669
+ /*\
6670
+ * Element.attr
6671
+ [ method ]
6672
+ **
6673
+ * Sets the attributes of the element.
6674
+ > Parameters
6675
+ - attrName (string) attribute’s name
6676
+ - value (string) value
6677
+ * or
6678
+ - params (object) object of name/value pairs
6679
+ * or
6680
+ - attrName (string) attribute’s name
6681
+ * or
6682
+ - attrNames (array) in this case method returns array of current values for given attribute names
6683
+ = (object) @Element if attrsName & value or params are passed in.
6684
+ = (...) value of the attribute if only attrsName is passed in.
6685
+ = (array) array of values of the attribute if attrsNames is passed in.
6686
+ = (object) object of attributes if nothing is passed in.
6687
+ > Possible parameters
6688
+ # <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>
6689
+ 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`, `medium`, length: `long`, `short`, `midium`.
6690
+ o clip-rect (string) comma or space separated values: x, y, width and height
6691
+ o cursor (string) CSS type of the cursor
6692
+ o cx (number) the x-axis coordinate of the center of the circle, or ellipse
6693
+ o cy (number) the y-axis coordinate of the center of the circle, or ellipse
6694
+ o fill (string) colour, gradient or image
6695
+ o fill-opacity (number)
6696
+ o font (string)
6697
+ o font-family (string)
6698
+ o font-size (number) font size in pixels
6699
+ o font-weight (string)
6700
+ o height (number)
6701
+ o href (string) URL, if specified element behaves as hyperlink
6702
+ o opacity (number)
6703
+ o path (string) SVG path string format
6704
+ o r (number) radius of the circle, ellipse or rounded corner on the rect
6705
+ o rx (number) horisontal radius of the ellipse
6706
+ o ry (number) vertical radius of the ellipse
6707
+ o src (string) image URL, only works for @Element.image element
6708
+ o stroke (string) stroke colour
6709
+ o stroke-dasharray (string) [“”, “`-`”, “`.`”, “`-.`”, “`-..`”, “`. `”, “`- `”, “`--`”, “`- .`”, “`--.`”, “`--..`”]
6710
+ o stroke-linecap (string) [“`butt`”, “`square`”, “`round`”]
6711
+ o stroke-linejoin (string) [“`bevel`”, “`round`”, “`miter`”]
6712
+ o stroke-miterlimit (number)
6713
+ o stroke-opacity (number)
6714
+ o stroke-width (number) stroke width in pixels, default is '1'
6715
+ o target (string) used with href
6716
+ o text (string) contents of the text element. Use `\n` for multiline text
6717
+ o text-anchor (string) [“`start`”, “`middle`”, “`end`”], default is “`middle`”
6718
+ o title (string) will create tooltip with a given text
6719
+ o transform (string) see @Element.transform
6720
+ o width (number)
6721
+ o x (number)
6722
+ o y (number)
6723
+ > Gradients
6724
+ * Linear gradient format: “`‹angle›-‹colour›[-‹colour›[:‹offset›]]*-‹colour›`”, example: “`90-#fff-#000`” – 90°
6725
+ * gradient from white to black or “`0-#fff-#f00:20-#000`” – 0° gradient from white via red (at 20%) to black.
6726
+ *
6727
+ * radial gradient: “`r[(‹fx›, ‹fy›)]‹colour›[-‹colour›[:‹offset›]]*-‹colour›`”, example: “`r#fff-#000`” –
6728
+ * gradient from white to black or “`r(0.25, 0.75)#fff-#000`” – gradient from white to black with focus point
6729
+ * at 0.25, 0.75. Focus point coordinates are in 0..1 range. Radial gradients can only be applied to circles and ellipses.
6730
+ > Path String
6731
+ # <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>
6732
+ > Colour Parsing
6733
+ # <ul>
6734
+ # <li>Colour name (“<code>red</code>”, “<code>green</code>”, “<code>cornflowerblue</code>”, etc)</li>
6735
+ # <li>#••• — shortened HTML colour: (“<code>#000</code>”, “<code>#fc0</code>”, etc)</li>
6736
+ # <li>#•••••• — full length HTML colour: (“<code>#000000</code>”, “<code>#bd2300</code>”)</li>
6737
+ # <li>rgb(•••, •••, •••) — red, green and blue channels’ values: (“<code>rgb(200,&nbsp;100,&nbsp;0)</code>”)</li>
6738
+ # <li>rgb(•••%, •••%, •••%) — same as above, but in %: (“<code>rgb(100%,&nbsp;175%,&nbsp;0%)</code>”)</li>
6739
+ # <li>rgba(•••, •••, •••, •••) — red, green and blue channels’ values: (“<code>rgba(200,&nbsp;100,&nbsp;0, .5)</code>”)</li>
6740
+ # <li>rgba(•••%, •••%, •••%, •••%) — same as above, but in %: (“<code>rgba(100%,&nbsp;175%,&nbsp;0%, 50%)</code>”)</li>
6741
+ # <li>hsb(•••, •••, •••) — hue, saturation and brightness values: (“<code>hsb(0.5,&nbsp;0.25,&nbsp;1)</code>”)</li>
6742
+ # <li>hsb(•••%, •••%, •••%) — same as above, but in %</li>
6743
+ # <li>hsba(•••, •••, •••, •••) — same as above, but with opacity</li>
6744
+ # <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>
6745
+ # <li>hsl(•••%, •••%, •••%) — same as above, but in %</li>
6746
+ # <li>hsla(•••, •••, •••, •••) — same as above, but with opacity</li>
6747
+ # <li>Optionally for hsb and hsl you could specify hue as a degree: “<code>hsl(240deg,&nbsp;1,&nbsp;.5)</code>” or, if you want to go fancy, “<code>hsl(240°,&nbsp;1,&nbsp;.5)</code>”</li>
6748
+ # </ul>
6749
+ \*/
4512
6750
  elproto.attr = function (name, value) {
4513
6751
  if (this.removed) {
4514
6752
  return this;
@@ -4569,7 +6807,13 @@ window.Raphael.svg && function (R) {
4569
6807
  setFillAndStroke(this, params);
4570
6808
  return this;
4571
6809
  };
4572
-
6810
+ /*\
6811
+ * Element.toFront
6812
+ [ method ]
6813
+ **
6814
+ * Moves the element so it is the closest to the viewer’s eyes, on top of other elements.
6815
+ = (object) @Element
6816
+ \*/
4573
6817
  elproto.toFront = function () {
4574
6818
  if (this.removed) {
4575
6819
  return this;
@@ -4583,7 +6827,13 @@ window.Raphael.svg && function (R) {
4583
6827
  svg.top != this && R._tofront(this, svg);
4584
6828
  return this;
4585
6829
  };
4586
-
6830
+ /*\
6831
+ * Element.toBack
6832
+ [ method ]
6833
+ **
6834
+ * Moves the element so it is the furthest from the viewer’s eyes, behind other elements.
6835
+ = (object) @Element
6836
+ \*/
4587
6837
  elproto.toBack = function () {
4588
6838
  if (this.removed) {
4589
6839
  return this;
@@ -4598,7 +6848,13 @@ window.Raphael.svg && function (R) {
4598
6848
  var svg = this.paper;
4599
6849
  return this;
4600
6850
  };
4601
-
6851
+ /*\
6852
+ * Element.insertAfter
6853
+ [ method ]
6854
+ **
6855
+ * Inserts current object after the given one.
6856
+ = (object) @Element
6857
+ \*/
4602
6858
  elproto.insertAfter = function (element) {
4603
6859
  if (this.removed) {
4604
6860
  return this;
@@ -4612,7 +6868,13 @@ window.Raphael.svg && function (R) {
4612
6868
  R._insertafter(this, element, this.paper);
4613
6869
  return this;
4614
6870
  };
4615
-
6871
+ /*\
6872
+ * Element.insertBefore
6873
+ [ method ]
6874
+ **
6875
+ * Inserts current object before the given one.
6876
+ = (object) @Element
6877
+ \*/
4616
6878
  elproto.insertBefore = function (element) {
4617
6879
  if (this.removed) {
4618
6880
  return this;
@@ -4643,6 +6905,7 @@ window.Raphael.svg && function (R) {
4643
6905
  }
4644
6906
  t.node.removeAttribute("filter");
4645
6907
  }
6908
+ return t;
4646
6909
  };
4647
6910
  R._engine.circle = function (svg, x, y, r) {
4648
6911
  var el = $("circle");
@@ -4784,7 +7047,16 @@ window.Raphael.svg && function (R) {
4784
7047
  this._viewBox = [x, y, w, h, !!fit];
4785
7048
  return this;
4786
7049
  };
4787
-
7050
+ /*\
7051
+ * Paper.renderfix
7052
+ [ method ]
7053
+ **
7054
+ * Fixes the issue of Firefox and IE9 regarding subpixel rendering. If paper is dependant
7055
+ * on other elements after reflow it could shift half pixel which cause for lines to lost their crispness.
7056
+ * This method fixes the issue.
7057
+ **
7058
+ Special thanks to Mariusz Nowak (http://www.medikoo.com/) for this method.
7059
+ \*/
4788
7060
  R.prototype.renderfix = function () {
4789
7061
  var cnvs = this.canvas,
4790
7062
  s = cnvs.style,
@@ -4807,7 +7079,12 @@ window.Raphael.svg && function (R) {
4807
7079
  }
4808
7080
  }
4809
7081
  };
4810
-
7082
+ /*\
7083
+ * Paper.clear
7084
+ [ method ]
7085
+ **
7086
+ * Clears the paper, i.e. removes all the elements.
7087
+ \*/
4811
7088
  R.prototype.clear = function () {
4812
7089
  R.eve("raphael.clear", this);
4813
7090
  var c = this.canvas;
@@ -4819,7 +7096,12 @@ window.Raphael.svg && function (R) {
4819
7096
  c.appendChild(this.desc);
4820
7097
  c.appendChild(this.defs = $("defs"));
4821
7098
  };
4822
-
7099
+ /*\
7100
+ * Paper.remove
7101
+ [ method ]
7102
+ **
7103
+ * Removes the paper from the DOM.
7104
+ \*/
4823
7105
  R.prototype.remove = function () {
4824
7106
  eve("raphael.remove", this);
4825
7107
  this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas);
@@ -4838,7 +7120,7 @@ window.Raphael.svg && function (R) {
4838
7120
  };
4839
7121
  })(method);
4840
7122
  }
4841
- }(window.Raphael);
7123
+ })();
4842
7124
 
4843
7125
  // ┌─────────────────────────────────────────────────────────────────────┐ \\
4844
7126
  // │ Raphaël - JavaScript Vector Library │ \\
@@ -4849,7 +7131,11 @@ window.Raphael.svg && function (R) {
4849
7131
  // │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\
4850
7132
  // │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\
4851
7133
  // └─────────────────────────────────────────────────────────────────────┘ \\
4852
- window.Raphael.vml && function (R) {
7134
+
7135
+ (function(){
7136
+ if (!R.vml) {
7137
+ return;
7138
+ }
4853
7139
  var has = "hasOwnProperty",
4854
7140
  Str = String,
4855
7141
  toFloat = parseFloat,
@@ -5025,6 +7311,7 @@ window.Raphael.vml && function (R) {
5025
7311
  rx = +a.rx || +a.r || 0,
5026
7312
  ry = +a.ry || +a.r || 0;
5027
7313
  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));
7314
+ o._.dirty = 1;
5028
7315
  }
5029
7316
  if ("clip-rect" in params) {
5030
7317
  var rect = Str(params["clip-rect"]).split(separator);
@@ -5314,7 +7601,7 @@ window.Raphael.vml && function (R) {
5314
7601
  split,
5315
7602
  isGrad = ~Str(this.attrs.fill).indexOf("-"),
5316
7603
  isPatt = !Str(this.attrs.fill).indexOf("url(");
5317
- matrix.translate(-.5, -.5);
7604
+ matrix.translate(1, 1);
5318
7605
  if (isPatt || isGrad || this.type == "image") {
5319
7606
  skew.matrix = "1 0 0 1";
5320
7607
  skew.offset = "0 0";
@@ -5555,6 +7842,7 @@ window.Raphael.vml && function (R) {
5555
7842
  s.margin = 0;
5556
7843
  delete this.attrs.blur;
5557
7844
  }
7845
+ return this;
5558
7846
  };
5559
7847
 
5560
7848
  R._engine.path = function (pathString, vml) {
@@ -5812,4 +8100,12 @@ window.Raphael.vml && function (R) {
5812
8100
  };
5813
8101
  })(method);
5814
8102
  }
5815
- }(window.Raphael);
8103
+ })();
8104
+
8105
+ // EXPOSE
8106
+ // SVG and VML are appended just before the EXPOSE line
8107
+ // Even with AMD, Raphael should be defined globally
8108
+ oldRaphael.was ? (g.win.Raphael = R) : (Raphael = R);
8109
+
8110
+ return R;
8111
+ }));