raphael-rails 2.1.1 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+ }));