fabric-rails 0.0.8 → 0.9.16

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 1.0.11 (19 February 2013)
2
+
3
+ - fabric.js version 1.0.11
4
+
5
+ ## 1.0.10 (18 February 2013)
6
+
7
+ - fabric.js version 1.0.10
8
+
1
9
  ## 0.0.8 (19 September 2012)
2
10
 
3
11
  - fabric.js version 0.9.8
data/Gemfile.lock CHANGED
@@ -1,59 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fabric-rails (0.0.7)
5
- railties (>= 3.2.0, < 5.0)
6
- thor (~> 0.14)
4
+ fabric-rails (1.0.10)
7
5
 
8
6
  GEM
9
7
  remote: http://rubygems.org/
10
8
  specs:
11
- actionpack (3.2.1)
12
- activemodel (= 3.2.1)
13
- activesupport (= 3.2.1)
14
- builder (~> 3.0.0)
15
- erubis (~> 2.7.0)
16
- journey (~> 1.0.1)
17
- rack (~> 1.4.0)
18
- rack-cache (~> 1.1)
19
- rack-test (~> 0.6.1)
20
- sprockets (~> 2.1.2)
21
- activemodel (3.2.1)
22
- activesupport (= 3.2.1)
23
- builder (~> 3.0.0)
24
- activesupport (3.2.1)
25
- i18n (~> 0.6)
26
- multi_json (~> 1.0)
27
- builder (3.0.0)
28
- erubis (2.7.0)
29
- hike (1.2.1)
30
- i18n (0.6.0)
31
- journey (1.0.3)
32
- json (1.6.5)
33
- multi_json (1.1.0)
34
- rack (1.4.1)
35
- rack-cache (1.2)
36
- rack (>= 0.4)
37
- rack-ssl (1.3.2)
38
- rack
39
- rack-test (0.6.1)
40
- rack (>= 1.0)
41
- railties (3.2.1)
42
- actionpack (= 3.2.1)
43
- activesupport (= 3.2.1)
44
- rack-ssl (~> 1.3.2)
45
- rake (>= 0.8.7)
46
- rdoc (~> 3.4)
47
- thor (~> 0.14.6)
48
- rake (0.9.2.2)
49
- rdoc (3.12)
50
- json (~> 1.4)
51
- sprockets (2.1.2)
52
- hike (~> 1.2)
53
- rack (~> 1.0)
54
- tilt (~> 1.1, != 1.3.0)
55
- thor (0.14.6)
56
- tilt (1.3.3)
57
9
 
58
10
  PLATFORMS
59
11
  ruby
data/fabric-rails.gemspec CHANGED
@@ -14,8 +14,8 @@ Gem::Specification.new do |s|
14
14
  s.required_rubygems_version = ">= 1.3.6"
15
15
  s.rubyforge_project = "fabric-rails"
16
16
 
17
- s.add_dependency "railties", ">= 3.2.0", "< 5.0"
18
- s.add_dependency "thor", "~> 0.14"
17
+ # s.add_dependency "railties", ">= 3.2.0", "< 5.0"
18
+ # s.add_dependency "thor", "~> 0.14"
19
19
 
20
20
  s.files = `git ls-files`.split("\n")
21
21
  s.executables = []
@@ -1,6 +1,6 @@
1
1
  module Fabric
2
2
  module Rails
3
- VERSION = "0.0.8"
4
- FABRIC_VERSION = "0.9.8"
3
+ VERSION = "0.9.16"
4
+ FABRIC_VERSION = "0.9.16"
5
5
  end
6
6
  end
@@ -1,7 +1,7 @@
1
1
  /* build: `node build.js modules=ALL` */
2
2
  /*! Fabric.js Copyright 2008-2012, Printio (Juriy Zaytsev, Maxim Chernyak) */
3
3
 
4
- var fabric = fabric || { version: "0.9.8" };
4
+ var fabric = fabric || { version: "0.9.16" };
5
5
 
6
6
  if (typeof exports != 'undefined') {
7
7
  exports.fabric = fabric;
@@ -1784,7 +1784,12 @@ fabric.Observable = {
1784
1784
  this.__eventListeners = { };
1785
1785
  }
1786
1786
  if (this.__eventListeners[eventName]) {
1787
- fabric.util.removeFromArray(this.__eventListeners[eventName], handler);
1787
+ if (handler) {
1788
+ fabric.util.removeFromArray(this.__eventListeners[eventName], handler);
1789
+ }
1790
+ else {
1791
+ this.__eventListeners[eventName].length = 0;
1792
+ }
1788
1793
  }
1789
1794
  },
1790
1795
 
@@ -1796,7 +1801,7 @@ fabric.Observable = {
1796
1801
  */
1797
1802
  fire: function(eventName, options) {
1798
1803
  if (!this.__eventListeners) {
1799
- this.__eventListeners = { }
1804
+ this.__eventListeners = { };
1800
1805
  }
1801
1806
  var listenersForEvent = this.__eventListeners[eventName];
1802
1807
  if (!listenersForEvent) return;
@@ -1842,7 +1847,7 @@ fabric.Observable.off = fabric.Observable.stopObserving;
1842
1847
  array.splice(idx, 1);
1843
1848
  }
1844
1849
  return array;
1845
- };
1850
+ }
1846
1851
 
1847
1852
  /**
1848
1853
  * Returns random number between 2 specified ones.
@@ -1914,19 +1919,19 @@ fabric.Observable.off = fabric.Observable.stopObserving;
1914
1919
 
1915
1920
  var start = +new Date(),
1916
1921
  duration = options.duration || 500,
1917
- finish = start + duration, time, pos,
1922
+ finish = start + duration, time,
1918
1923
  onChange = options.onChange || function() { },
1919
1924
  abort = options.abort || function() { return false; },
1920
1925
  easing = options.easing || function(t, b, c, d) {return -c * Math.cos(t/d * (Math.PI/2)) + c + b;},
1921
1926
  startValue = 'startValue' in options ? options.startValue : 0,
1922
- endValue = 'endValue' in options ? options.endValue : 100;
1927
+ endValue = 'endValue' in options ? options.endValue : 100,
1923
1928
  byValue = options.byValue || endValue - startValue;
1924
1929
 
1925
1930
  options.onStart && options.onStart();
1926
1931
 
1927
1932
  (function tick() {
1928
1933
  time = +new Date();
1929
- currentTime = time > finish ? duration : (time - start);
1934
+ var currentTime = time > finish ? duration : (time - start);
1930
1935
  onChange(easing(currentTime, startValue, byValue, duration));
1931
1936
  if (time > finish || abort()) {
1932
1937
  options.onComplete && options.onComplete();
@@ -1941,7 +1946,7 @@ fabric.Observable.off = fabric.Observable.stopObserving;
1941
1946
  fabric.window.mozRequestAnimationFrame ||
1942
1947
  fabric.window.oRequestAnimationFrame ||
1943
1948
  fabric.window.msRequestAnimationFrame ||
1944
- function(callback, element) {
1949
+ function(callback) {
1945
1950
  fabric.window.setTimeout(callback, 1000 / 60);
1946
1951
  };
1947
1952
  /**
@@ -2014,6 +2019,15 @@ fabric.Observable.off = fabric.Observable.stopObserving;
2014
2019
  });
2015
2020
  }
2016
2021
 
2022
+ /**
2023
+ * Groups SVG elements (usually those retrieved from SVG document)
2024
+ * @static
2025
+ * @memberOf fabric.util
2026
+ * @method groupSVGElements
2027
+ * @param {Array} elements
2028
+ * @param {Object} options optional
2029
+ * @return {String} path optional
2030
+ */
2017
2031
  function groupSVGElements(elements, options, path) {
2018
2032
  var object = elements.length > 1
2019
2033
  ? new fabric.PathGroup(elements, options)
@@ -2037,9 +2051,9 @@ fabric.Observable.off = fabric.Observable.stopObserving;
2037
2051
  fabric.util.groupSVGElements = groupSVGElements;
2038
2052
  })();
2039
2053
  (function() {
2040
-
2054
+
2041
2055
  var slice = Array.prototype.slice;
2042
-
2056
+
2043
2057
  if (!Array.prototype.indexOf) {
2044
2058
  Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
2045
2059
  if (this === void 0 || this === null) {
@@ -2069,7 +2083,7 @@ fabric.Observable.off = fabric.Observable.stopObserving;
2069
2083
  }
2070
2084
  }
2071
2085
  return -1;
2072
- }
2086
+ };
2073
2087
  }
2074
2088
 
2075
2089
  if (!Array.prototype.forEach) {
@@ -2077,7 +2091,7 @@ fabric.Observable.off = fabric.Observable.stopObserving;
2077
2091
  for (var i = 0, len = this.length >>> 0; i < len; i++) {
2078
2092
  if (i in this) {
2079
2093
  fn.call(context, this[i], i, this);
2080
- }
2094
+ }
2081
2095
  }
2082
2096
  };
2083
2097
  }
@@ -2186,8 +2200,8 @@ fabric.Observable.off = fabric.Observable.stopObserving;
2186
2200
  */
2187
2201
  function max(array, byProperty) {
2188
2202
  if (!array || array.length === 0) return undefined;
2189
-
2190
- var i = array.length - 1,
2203
+
2204
+ var i = array.length - 1,
2191
2205
  result = byProperty ? array[i][byProperty] : array[i];
2192
2206
  if (byProperty) {
2193
2207
  while (i--) {
@@ -2215,8 +2229,8 @@ fabric.Observable.off = fabric.Observable.stopObserving;
2215
2229
  */
2216
2230
  function min(array, byProperty) {
2217
2231
  if (!array || array.length === 0) return undefined;
2218
-
2219
- var i = array.length - 1,
2232
+
2233
+ var i = array.length - 1,
2220
2234
  result = byProperty ? array[i][byProperty] : array[i];
2221
2235
 
2222
2236
  if (byProperty) {
@@ -2242,7 +2256,7 @@ fabric.Observable.off = fabric.Observable.stopObserving;
2242
2256
  min: min,
2243
2257
  max: max
2244
2258
  };
2245
-
2259
+
2246
2260
  })();
2247
2261
  (function(){
2248
2262
 
@@ -2333,11 +2347,11 @@ fabric.util.string = {
2333
2347
  }());
2334
2348
 
2335
2349
  (function() {
2336
-
2350
+
2337
2351
  var slice = Array.prototype.slice,
2338
2352
  apply = Function.prototype.apply,
2339
- dummy = function() { };
2340
-
2353
+ Dummy = function() { };
2354
+
2341
2355
  if (!Function.prototype.bind) {
2342
2356
  /**
2343
2357
  * Cross-browser approximation of ES5 Function.prototype.bind (not fully spec conforming)
@@ -2349,22 +2363,22 @@ fabric.util.string = {
2349
2363
  Function.prototype.bind = function(thisArg) {
2350
2364
  var fn = this, args = slice.call(arguments, 1), bound;
2351
2365
  if (args.length) {
2352
- bound = function() {
2353
- return apply.call(fn, this instanceof dummy ? this : thisArg, args.concat(slice.call(arguments)));
2366
+ bound = function() {
2367
+ return apply.call(fn, this instanceof Dummy ? this : thisArg, args.concat(slice.call(arguments)));
2354
2368
  };
2355
2369
  }
2356
2370
  else {
2357
- bound = function() {
2358
- return apply.call(fn, this instanceof dummy ? this : thisArg, arguments);
2371
+ bound = function() {
2372
+ return apply.call(fn, this instanceof Dummy ? this : thisArg, arguments);
2359
2373
  };
2360
2374
  }
2361
- dummy.prototype = this.prototype;
2362
- bound.prototype = new dummy;
2363
-
2375
+ Dummy.prototype = this.prototype;
2376
+ bound.prototype = new Dummy();
2377
+
2364
2378
  return bound;
2365
2379
  };
2366
2380
  }
2367
-
2381
+
2368
2382
  })();
2369
2383
  (function() {
2370
2384
 
@@ -2381,7 +2395,7 @@ fabric.util.string = {
2381
2395
  var addMethods = function(klass, source, parent) {
2382
2396
  for (var property in source) {
2383
2397
 
2384
- if (property in klass.prototype && typeof klass.prototype[property] == 'function') {
2398
+ if (property in klass.prototype && typeof klass.prototype[property] === 'function') {
2385
2399
 
2386
2400
  klass.prototype[property] = (function(property) {
2387
2401
  return function() {
@@ -2394,7 +2408,7 @@ fabric.util.string = {
2394
2408
  if (property !== 'initialize') {
2395
2409
  return returnValue;
2396
2410
  }
2397
- }
2411
+ };
2398
2412
  })(property);
2399
2413
  }
2400
2414
  else {
@@ -2412,7 +2426,7 @@ fabric.util.string = {
2412
2426
  }
2413
2427
  };
2414
2428
 
2415
- function subclass() { };
2429
+ function Subclass() { }
2416
2430
 
2417
2431
  /**
2418
2432
  * Helper for creation of "classes"
@@ -2434,8 +2448,8 @@ fabric.util.string = {
2434
2448
  klass.subclasses = [ ];
2435
2449
 
2436
2450
  if (parent) {
2437
- subclass.prototype = parent.prototype;
2438
- klass.prototype = new subclass;
2451
+ Subclass.prototype = parent.prototype;
2452
+ klass.prototype = new Subclass();
2439
2453
  parent.subclasses.push(klass);
2440
2454
  }
2441
2455
  for (var i = 0, length = properties.length; i < length; i++) {
@@ -2450,7 +2464,7 @@ fabric.util.string = {
2450
2464
 
2451
2465
  fabric.util.createClass = createClass;
2452
2466
  })();
2453
- (function (global) {
2467
+ (function () {
2454
2468
 
2455
2469
  /* EVENT HANDLING */
2456
2470
 
@@ -2635,26 +2649,26 @@ fabric.util.string = {
2635
2649
  return { x: pointerX(event), y: pointerY(event) };
2636
2650
  }
2637
2651
 
2638
- function pointerX(event) {
2652
+ var pointerX = function(event) {
2639
2653
  var docElement = fabric.document.documentElement,
2640
2654
  body = fabric.document.body || { scrollLeft: 0 };
2641
2655
 
2642
2656
  // looks like in IE (<9) clientX at certain point (apparently when mouseup fires on VML element)
2643
2657
  // is represented as COM object, with all the consequences, like "unknown" type and error on [[Get]]
2644
2658
  // need to investigate later
2645
- return event.pageX || ((typeof event.clientX != 'unknown' ? event.clientX : 0) +
2659
+ return event.pageX || ((typeof event.clientX !== 'unknown' ? event.clientX : 0) +
2646
2660
  (docElement.scrollLeft || body.scrollLeft) -
2647
2661
  (docElement.clientLeft || 0));
2648
- }
2662
+ };
2649
2663
 
2650
- function pointerY(event) {
2664
+ var pointerY = function(event) {
2651
2665
  var docElement = fabric.document.documentElement,
2652
2666
  body = fabric.document.body || { scrollTop: 0 };
2653
2667
 
2654
- return event.pageY || ((typeof event.clientY != 'unknown' ? event.clientY : 0) +
2668
+ return event.pageY || ((typeof event.clientY !== 'unknown' ? event.clientY : 0) +
2655
2669
  (docElement.scrollTop || body.scrollTop) -
2656
2670
  (docElement.clientTop || 0));
2657
- }
2671
+ };
2658
2672
 
2659
2673
  if (fabric.isTouchSupported) {
2660
2674
  pointerX = function(event) {
@@ -2669,7 +2683,7 @@ fabric.util.string = {
2669
2683
 
2670
2684
  fabric.util.object.extend(fabric.util, fabric.Observable);
2671
2685
 
2672
- })(this);
2686
+ })();
2673
2687
  (function () {
2674
2688
 
2675
2689
  /**
@@ -2681,7 +2695,7 @@ fabric.util.string = {
2681
2695
  * @return {HTMLElement} Element that was passed as a first argument
2682
2696
  */
2683
2697
  function setStyle(element, styles) {
2684
- var elementStyle = element.style, match;
2698
+ var elementStyle = element.style;
2685
2699
  if (!elementStyle) {
2686
2700
  return element;
2687
2701
  }
@@ -2708,8 +2722,6 @@ fabric.util.string = {
2708
2722
  var parseEl = fabric.document.createElement('div'),
2709
2723
  supportsOpacity = typeof parseEl.style.opacity === 'string',
2710
2724
  supportsFilters = typeof parseEl.style.filter === 'string',
2711
- view = fabric.document.defaultView,
2712
- supportsGCS = view && typeof view.getComputedStyle !== 'undefined',
2713
2725
  reOpacity = /alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,
2714
2726
 
2715
2727
  /** @ignore */
@@ -2744,7 +2756,7 @@ fabric.util.string = {
2744
2756
 
2745
2757
  })();
2746
2758
  (function() {
2747
-
2759
+
2748
2760
  var _slice = Array.prototype.slice;
2749
2761
 
2750
2762
  /**
@@ -2765,12 +2777,13 @@ fabric.util.string = {
2765
2777
  * @param {Object} arrayLike
2766
2778
  * @return {Array}
2767
2779
  */
2768
- function toArray(arrayLike) {
2780
+ var toArray = function(arrayLike) {
2769
2781
  return _slice.call(arrayLike, 0);
2770
- }
2782
+ };
2771
2783
 
2784
+ var sliceCanConvertNodelists;
2772
2785
  try {
2773
- var sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array;
2786
+ sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array;
2774
2787
  }
2775
2788
  catch(err) { }
2776
2789
 
@@ -2818,7 +2831,7 @@ fabric.util.string = {
2818
2831
  function addClass(element, className) {
2819
2832
  if ((' ' + element.className + ' ').indexOf(' ' + className + ' ') === -1) {
2820
2833
  element.className += (element.className ? ' ' : '') + className;
2821
- }
2834
+ }
2822
2835
  }
2823
2836
 
2824
2837
  /**
@@ -2856,7 +2869,7 @@ fabric.util.string = {
2856
2869
  valueT += element.offsetTop || 0;
2857
2870
  valueL += element.offsetLeft || 0;
2858
2871
  element = element.offsetParent;
2859
- }
2872
+ }
2860
2873
  while (element);
2861
2874
  return ({ left: valueL, top: valueT });
2862
2875
  }
@@ -2866,12 +2879,12 @@ fabric.util.string = {
2866
2879
 
2867
2880
  var selectProp = 'userSelect' in style
2868
2881
  ? 'userSelect'
2869
- : 'MozUserSelect' in style
2870
- ? 'MozUserSelect'
2871
- : 'WebkitUserSelect' in style
2872
- ? 'WebkitUserSelect'
2873
- : 'KhtmlUserSelect' in style
2874
- ? 'KhtmlUserSelect'
2882
+ : 'MozUserSelect' in style
2883
+ ? 'MozUserSelect'
2884
+ : 'WebkitUserSelect' in style
2885
+ ? 'WebkitUserSelect'
2886
+ : 'KhtmlUserSelect' in style
2887
+ ? 'KhtmlUserSelect'
2875
2888
  : '';
2876
2889
 
2877
2890
  /**
@@ -2888,7 +2901,7 @@ fabric.util.string = {
2888
2901
  if (selectProp) {
2889
2902
  element.style[selectProp] = 'none';
2890
2903
  }
2891
- else if (typeof element.unselectable == 'string') {
2904
+ else if (typeof element.unselectable === 'string') {
2892
2905
  element.unselectable = 'on';
2893
2906
  }
2894
2907
  return element;
@@ -2908,7 +2921,7 @@ fabric.util.string = {
2908
2921
  if (selectProp) {
2909
2922
  element.style[selectProp] = '';
2910
2923
  }
2911
- else if (typeof element.unselectable == 'string') {
2924
+ else if (typeof element.unselectable === 'string') {
2912
2925
  element.unselectable = '';
2913
2926
  }
2914
2927
  return element;
@@ -2928,28 +2941,28 @@ fabric.util.string = {
2928
2941
  * @param {Function} callback Callback to execute when script is finished loading
2929
2942
  */
2930
2943
  function getScript(url, callback) {
2931
- var headEl = fabric.document.getElementsByTagName("head")[0],
2932
- scriptEl = fabric.document.createElement('script'),
2933
- loading = true;
2934
-
2935
- scriptEl.type = 'text/javascript';
2936
- scriptEl.setAttribute('runat', 'server');
2937
-
2938
- /** @ignore */
2939
- scriptEl.onload = /** @ignore */ scriptEl.onreadystatechange = function(e) {
2940
- if (loading) {
2941
- if (typeof this.readyState == 'string' &&
2942
- this.readyState !== 'loaded' &&
2943
- this.readyState !== 'complete') return;
2944
- loading = false;
2945
- callback(e || fabric.window.event);
2946
- scriptEl = scriptEl.onload = scriptEl.onreadystatechange = null;
2947
- }
2948
- };
2949
- scriptEl.src = url;
2950
- headEl.appendChild(scriptEl);
2951
- // causes issue in Opera
2952
- // headEl.removeChild(scriptEl);
2944
+ var headEl = fabric.document.getElementsByTagName("head")[0],
2945
+ scriptEl = fabric.document.createElement('script'),
2946
+ loading = true;
2947
+
2948
+ scriptEl.type = 'text/javascript';
2949
+ scriptEl.setAttribute('runat', 'server');
2950
+
2951
+ /** @ignore */
2952
+ scriptEl.onload = /** @ignore */ scriptEl.onreadystatechange = function(e) {
2953
+ if (loading) {
2954
+ if (typeof this.readyState === 'string' &&
2955
+ this.readyState !== 'loaded' &&
2956
+ this.readyState !== 'complete') return;
2957
+ loading = false;
2958
+ callback(e || fabric.window.event);
2959
+ scriptEl = scriptEl.onload = scriptEl.onreadystatechange = null;
2960
+ }
2961
+ };
2962
+ scriptEl.src = url;
2963
+ headEl.appendChild(scriptEl);
2964
+ // causes issue in Opera
2965
+ // headEl.removeChild(scriptEl);
2953
2966
  }
2954
2967
 
2955
2968
  fabric.util.getScript = getScript;
@@ -2961,14 +2974,14 @@ fabric.util.string = {
2961
2974
  fabric.util.addClass = addClass;
2962
2975
  fabric.util.wrapElement = wrapElement;
2963
2976
  fabric.util.getElementOffset = getElementOffset;
2964
-
2977
+
2965
2978
  })();
2966
2979
  (function(){
2967
-
2980
+
2968
2981
  function addParamToUrl(url, param) {
2969
2982
  return url + (/\?/.test(url) ? '&' : '?') + param;
2970
2983
  }
2971
-
2984
+
2972
2985
  var makeXHR = (function() {
2973
2986
  var factories = [
2974
2987
  function() { return new ActiveXObject("Microsoft.XMLHTTP"); },
@@ -2987,8 +3000,8 @@ fabric.util.string = {
2987
3000
  }
2988
3001
  })();
2989
3002
 
2990
- function emptyFn() { };
2991
-
3003
+ function emptyFn() { }
3004
+
2992
3005
  /**
2993
3006
  * Cross-browser abstraction for sending XMLHttpRequest
2994
3007
  * @method request
@@ -3005,34 +3018,34 @@ fabric.util.string = {
3005
3018
 
3006
3019
  var method = options.method ? options.method.toUpperCase() : 'GET',
3007
3020
  onComplete = options.onComplete || function() { },
3008
- request = makeXHR(),
3021
+ xhr = makeXHR(),
3009
3022
  body;
3010
-
3023
+
3011
3024
  /** @ignore */
3012
- request.onreadystatechange = function() {
3013
- if (request.readyState === 4) {
3014
- onComplete(request);
3015
- request.onreadystatechange = emptyFn;
3025
+ xhr.onreadystatechange = function() {
3026
+ if (xhr.readyState === 4) {
3027
+ onComplete(xhr);
3028
+ xhr.onreadystatechange = emptyFn;
3016
3029
  }
3017
3030
  };
3018
-
3031
+
3019
3032
  if (method === 'GET') {
3020
3033
  body = null;
3021
- if (typeof options.parameters == 'string') {
3034
+ if (typeof options.parameters === 'string') {
3022
3035
  url = addParamToUrl(url, options.parameters);
3023
3036
  }
3024
3037
  }
3025
3038
 
3026
- request.open(method, url, true);
3027
-
3039
+ xhr.open(method, url, true);
3040
+
3028
3041
  if (method === 'POST' || method === 'PUT') {
3029
- request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
3042
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
3030
3043
  }
3031
3044
 
3032
- request.send(body);
3033
- return request;
3034
- };
3035
-
3045
+ xhr.send(body);
3046
+ return xhr;
3047
+ }
3048
+
3036
3049
  fabric.util.request = request;
3037
3050
  })();
3038
3051
  (function() {
@@ -3058,7 +3071,8 @@ fabric.util.string = {
3058
3071
  * @memberOf fabric.util.ease
3059
3072
  */
3060
3073
  function easeInOutQuad(t, b, c, d) {
3061
- if ((t/=d/2) < 1) return c/2*t*t + b;
3074
+ t /= (d/2);
3075
+ if (t < 1) return c/2*t*t + b;
3062
3076
  return -c/2 * ((--t)*(t-2) - 1) + b;
3063
3077
  }
3064
3078
 
@@ -3083,7 +3097,8 @@ fabric.util.string = {
3083
3097
  * @memberOf fabric.util.ease
3084
3098
  */
3085
3099
  function easeInOutCubic(t, b, c, d) {
3086
- if ((t/=d/2) < 1) return c/2*t*t*t + b;
3100
+ t /= d/2;
3101
+ if (t < 1) return c/2*t*t*t + b;
3087
3102
  return c/2*((t-=2)*t*t + 2) + b;
3088
3103
  }
3089
3104
 
@@ -3108,7 +3123,8 @@ fabric.util.string = {
3108
3123
  * @memberOf fabric.util.ease
3109
3124
  */
3110
3125
  function easeInOutQuart(t, b, c, d) {
3111
- if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
3126
+ t /= d/2;
3127
+ if (t < 1) return c/2*t*t*t*t + b;
3112
3128
  return -c/2 * ((t-=2)*t*t*t - 2) + b;
3113
3129
  }
3114
3130
 
@@ -3133,7 +3149,8 @@ fabric.util.string = {
3133
3149
  * @memberOf fabric.util.ease
3134
3150
  */
3135
3151
  function easeInOutQuint(t, b, c, d) {
3136
- if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
3152
+ t /= d/2;
3153
+ if (t < 1) return c/2*t*t*t*t*t + b;
3137
3154
  return c/2*((t-=2)*t*t*t*t + 2) + b;
3138
3155
  }
3139
3156
 
@@ -3166,7 +3183,7 @@ fabric.util.string = {
3166
3183
  * @memberOf fabric.util.ease
3167
3184
  */
3168
3185
  function easeInExpo(t, b, c, d) {
3169
- return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
3186
+ return (t===0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
3170
3187
  }
3171
3188
 
3172
3189
  /**
@@ -3174,7 +3191,7 @@ fabric.util.string = {
3174
3191
  * @memberOf fabric.util.ease
3175
3192
  */
3176
3193
  function easeOutExpo(t, b, c, d) {
3177
- return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
3194
+ return (t===d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
3178
3195
  }
3179
3196
 
3180
3197
  /**
@@ -3182,9 +3199,10 @@ fabric.util.string = {
3182
3199
  * @memberOf fabric.util.ease
3183
3200
  */
3184
3201
  function easeInOutExpo(t, b, c, d) {
3185
- if (t==0) return b;
3186
- if (t==d) return b+c;
3187
- if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
3202
+ if (t===0) return b;
3203
+ if (t===d) return b+c;
3204
+ t /= d/2;
3205
+ if (t < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
3188
3206
  return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
3189
3207
  }
3190
3208
 
@@ -3209,7 +3227,8 @@ fabric.util.string = {
3209
3227
  * @memberOf fabric.util.ease
3210
3228
  */
3211
3229
  function easeInOutCirc(t, b, c, d) {
3212
- if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
3230
+ t /= d/2;
3231
+ if (t < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
3213
3232
  return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
3214
3233
  }
3215
3234
 
@@ -3219,9 +3238,12 @@ fabric.util.string = {
3219
3238
  */
3220
3239
  function easeInElastic(t, b, c, d) {
3221
3240
  var s=1.70158;var p=0;var a=c;
3222
- if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
3223
- if (a < Math.abs(c)) { a=c; var s=p/4; }
3224
- else var s = p/(2*Math.PI) * Math.asin (c/a);
3241
+ if (t===0) return b;
3242
+ t /= d;
3243
+ if (t===1) return b+c;
3244
+ if (!p) p=d*0.3;
3245
+ if (a < Math.abs(c)) { a=c; s=p/4; }
3246
+ else s = p/(2*Math.PI) * Math.asin (c/a);
3225
3247
  return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
3226
3248
  }
3227
3249
 
@@ -3231,9 +3253,12 @@ fabric.util.string = {
3231
3253
  */
3232
3254
  function easeOutElastic(t, b, c, d) {
3233
3255
  var s=1.70158;var p=0;var a=c;
3234
- if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
3235
- if (a < Math.abs(c)) { a=c; var s=p/4; }
3236
- else var s = p/(2*Math.PI) * Math.asin (c/a);
3256
+ if (t===0) return b;
3257
+ t /= d;
3258
+ if (t===1) return b+c;
3259
+ if (!p) p=d*0.3;
3260
+ if (a < Math.abs(c)) { a=c; s=p/4; }
3261
+ else s = p/(2*Math.PI) * Math.asin (c/a);
3237
3262
  return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
3238
3263
  }
3239
3264
 
@@ -3243,11 +3268,14 @@ fabric.util.string = {
3243
3268
  */
3244
3269
  function easeInOutElastic(t, b, c, d) {
3245
3270
  var s=1.70158;var p=0;var a=c;
3246
- if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
3247
- if (a < Math.abs(c)) { a=c; var s=p/4; }
3248
- else var s = p/(2*Math.PI) * Math.asin (c/a);
3249
- if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
3250
- return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
3271
+ if (t===0) return b;
3272
+ t /= d/2;
3273
+ if (t===2) return b+c;
3274
+ if (!p) p=d*(0.3*1.5);
3275
+ if (a < Math.abs(c)) { a=c; s=p/4; }
3276
+ else s = p/(2*Math.PI) * Math.asin (c/a);
3277
+ if (t < 1) return -0.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
3278
+ return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b;
3251
3279
  }
3252
3280
 
3253
3281
  /**
@@ -3255,7 +3283,7 @@ fabric.util.string = {
3255
3283
  * @memberOf fabric.util.ease
3256
3284
  */
3257
3285
  function easeInBack(t, b, c, d, s) {
3258
- if (s == undefined) s = 1.70158;
3286
+ if (s === undefined) s = 1.70158;
3259
3287
  return c*(t/=d)*t*((s+1)*t - s) + b;
3260
3288
  }
3261
3289
 
@@ -3264,7 +3292,7 @@ fabric.util.string = {
3264
3292
  * @memberOf fabric.util.ease
3265
3293
  */
3266
3294
  function easeOutBack(t, b, c, d, s) {
3267
- if (s == undefined) s = 1.70158;
3295
+ if (s === undefined) s = 1.70158;
3268
3296
  return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
3269
3297
  }
3270
3298
 
@@ -3273,8 +3301,9 @@ fabric.util.string = {
3273
3301
  * @memberOf fabric.util.ease
3274
3302
  */
3275
3303
  function easeInOutBack(t, b, c, d, s) {
3276
- if (s == undefined) s = 1.70158;
3277
- if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
3304
+ if (s === undefined) s = 1.70158;
3305
+ t /= d/2;
3306
+ if (t < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
3278
3307
  return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
3279
3308
  }
3280
3309
 
@@ -3294,11 +3323,11 @@ fabric.util.string = {
3294
3323
  if ((t/=d) < (1/2.75)) {
3295
3324
  return c*(7.5625*t*t) + b;
3296
3325
  } else if (t < (2/2.75)) {
3297
- return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
3326
+ return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
3298
3327
  } else if (t < (2.5/2.75)) {
3299
- return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
3328
+ return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
3300
3329
  } else {
3301
- return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
3330
+ return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
3302
3331
  }
3303
3332
  }
3304
3333
 
@@ -3307,8 +3336,8 @@ fabric.util.string = {
3307
3336
  * @memberOf fabric.util.ease
3308
3337
  */
3309
3338
  function easeInOutBounce(t, b, c, d) {
3310
- if (t < d/2) return easeInBounce (t*2, 0, c, d) * .5 + b;
3311
- return easeOutBounce (t*2-d, 0, c, d) * .5 + c*.5 + b;
3339
+ if (t < d/2) return easeInBounce (t*2, 0, c, d) * 0.5 + b;
3340
+ return easeOutBounce (t*2-d, 0, c, d) * 0.5 + c*0.5 + b;
3312
3341
  }
3313
3342
 
3314
3343
  /** @namespace fabric.util.ease */
@@ -3435,7 +3464,7 @@ fabric.util.string = {
3435
3464
 
3436
3465
  ownAttributes = extend(ownAttributes, extend(getGlobalStylesForElement(element), fabric.parseStyleAttribute(element)));
3437
3466
  return extend(parentAttributes, ownAttributes);
3438
- };
3467
+ }
3439
3468
 
3440
3469
  /**
3441
3470
  * Parses "transform" attribute, returning an array of values
@@ -3566,9 +3595,9 @@ fabric.util.string = {
3566
3595
  matrix = args;
3567
3596
  break;
3568
3597
  }
3569
- })
3598
+ });
3570
3599
  return matrix;
3571
- }
3600
+ };
3572
3601
  })();
3573
3602
 
3574
3603
  /**
@@ -3588,17 +3617,21 @@ fabric.util.string = {
3588
3617
  var asPairs = points.indexOf(',') > -1;
3589
3618
 
3590
3619
  points = points.split(/\s+/);
3591
- var parsedPoints = [ ];
3620
+ var parsedPoints = [ ], i, len;
3592
3621
 
3593
3622
  // points could look like "10,20 30,40" or "10 20 30 40"
3594
3623
  if (asPairs) {
3595
- for (var i = 0, len = points.length; i < len; i++) {
3596
- var pair = points[i].split(',');
3597
- parsedPoints.push({ x: parseFloat(pair[0]), y: parseFloat(pair[1]) });
3598
- }
3624
+ i = 0;
3625
+ len = points.length;
3626
+ for (; i < len; i++) {
3627
+ var pair = points[i].split(',');
3628
+ parsedPoints.push({ x: parseFloat(pair[0]), y: parseFloat(pair[1]) });
3629
+ }
3599
3630
  }
3600
3631
  else {
3601
- for (var i = 0, len = points.length; i < len; i+=2) {
3632
+ i = 0;
3633
+ len = points.length;
3634
+ for (; i < len; i+=2) {
3602
3635
  parsedPoints.push({ x: parseFloat(points[i]), y: parseFloat(points[i+1]) });
3603
3636
  }
3604
3637
  }
@@ -3609,7 +3642,7 @@ fabric.util.string = {
3609
3642
  }
3610
3643
 
3611
3644
  return parsedPoints;
3612
- };
3645
+ }
3613
3646
 
3614
3647
  /**
3615
3648
  * Parses "style" attribute, retuning an object with values
@@ -3622,22 +3655,24 @@ fabric.util.string = {
3622
3655
  function parseStyleAttribute(element) {
3623
3656
  var oStyle = { },
3624
3657
  style = element.getAttribute('style');
3625
- if (style) {
3626
- if (typeof style == 'string') {
3627
- style = style.replace(/;$/, '').split(';').forEach(function (current) {
3628
- var attr = current.split(':');
3629
- oStyle[normalizeAttr(attr[0].trim().toLowerCase())] = attr[1].trim();
3630
- });
3631
- } else {
3632
- for (var prop in style) {
3633
- if (typeof style[prop] !== 'undefined') {
3634
- oStyle[normalizeAttr(prop.toLowerCase())] = style[prop];
3635
- }
3636
- }
3658
+
3659
+ if (!style) return oStyle;
3660
+
3661
+ if (typeof style === 'string') {
3662
+ style = style.replace(/;$/, '').split(';').forEach(function (current) {
3663
+ var attr = current.split(':');
3664
+ oStyle[normalizeAttr(attr[0].trim().toLowerCase())] = attr[1].trim();
3665
+ });
3666
+ }
3667
+ else {
3668
+ for (var prop in style) {
3669
+ if (typeof style[prop] === 'undefined') continue;
3670
+ oStyle[normalizeAttr(prop.toLowerCase())] = style[prop];
3637
3671
  }
3638
3672
  }
3673
+
3639
3674
  return oStyle;
3640
- };
3675
+ }
3641
3676
 
3642
3677
  function resolveGradients(instances) {
3643
3678
  for (var i = instances.length; i--; ) {
@@ -3666,7 +3701,7 @@ fabric.util.string = {
3666
3701
  * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
3667
3702
  */
3668
3703
  function parseElements(elements, callback, options, reviver) {
3669
- var instances = Array(elements.length), i = elements.length;
3704
+ var instances = new Array(elements.length), i = elements.length;
3670
3705
 
3671
3706
  function checkIfDone() {
3672
3707
  if (--i === 0) {
@@ -3707,7 +3742,7 @@ fabric.util.string = {
3707
3742
  checkIfDone();
3708
3743
  }
3709
3744
  }
3710
- };
3745
+ }
3711
3746
 
3712
3747
  /**
3713
3748
  * Returns CSS rules for a given SVG document
@@ -3731,12 +3766,12 @@ fabric.util.string = {
3731
3766
  styleContents = styleContents.replace(/\/\*[\s\S]*?\*\//g, '');
3732
3767
 
3733
3768
  rules = styleContents.match(/[^{]*\{[\s\S]*?\}/g);
3734
- rules = rules.map(function(rule) { return rule.trim() });
3769
+ rules = rules.map(function(rule) { return rule.trim(); });
3735
3770
 
3736
3771
  rules.forEach(function(rule) {
3737
- var match = rule.match(/([\s\S]*?)\s*\{([^}]*)\}/),
3738
- rule = match[1],
3739
- declaration = match[2].trim(),
3772
+ var match = rule.match(/([\s\S]*?)\s*\{([^}]*)\}/);
3773
+ rule = match[1];
3774
+ var declaration = match[2].trim(),
3740
3775
  propertyValuePairs = declaration.replace(/;$/, '').split(/\s*;\s*/);
3741
3776
 
3742
3777
  if (!allRules[rule]) {
@@ -3898,7 +3933,7 @@ fabric.util.string = {
3898
3933
  * @param {String} url
3899
3934
  * @param {Function} callback
3900
3935
  */
3901
- get: function (url, callback) {
3936
+ get: function () {
3902
3937
  /* NOOP */
3903
3938
  },
3904
3939
 
@@ -3907,7 +3942,7 @@ fabric.util.string = {
3907
3942
  * @param {String} url
3908
3943
  * @param {Object} object
3909
3944
  */
3910
- set: function (url, object) {
3945
+ set: function () {
3911
3946
  /* NOOP */
3912
3947
  }
3913
3948
  };
@@ -3991,7 +4026,7 @@ fabric.util.string = {
3991
4026
  }
3992
4027
  }
3993
4028
  else if (fabric.window.ActiveXObject) {
3994
- var doc = new ActiveXObject('Microsoft.XMLDOM');
4029
+ doc = new ActiveXObject('Microsoft.XMLDOM');
3995
4030
  doc.async = 'false';
3996
4031
  //IE chokes on DOCTYPE
3997
4032
  doc.loadXML(string.replace(/<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i,''));
@@ -4045,7 +4080,7 @@ fabric.util.string = {
4045
4080
  createSVGFontFacesMarkup: createSVGFontFacesMarkup
4046
4081
  });
4047
4082
 
4048
- })(typeof exports != 'undefined' ? exports : this);
4083
+ })(typeof exports !== 'undefined' ? exports : this);
4049
4084
 
4050
4085
  (function() {
4051
4086
 
@@ -4140,10 +4175,8 @@ fabric.util.string = {
4140
4175
  */
4141
4176
 
4142
4177
  var colorStopEls = el.getElementsByTagName('stop'),
4143
- el,
4144
4178
  offset,
4145
4179
  colorStops = { },
4146
- colorStopFromStyle,
4147
4180
  coords = {
4148
4181
  x1: el.getAttribute('x1') || 0,
4149
4182
  y1: el.getAttribute('y1') || 0,
@@ -4215,15 +4248,17 @@ fabric.util.string = {
4215
4248
  function getGradientDefs(doc) {
4216
4249
  var linearGradientEls = doc.getElementsByTagName('linearGradient'),
4217
4250
  radialGradientEls = doc.getElementsByTagName('radialGradient'),
4218
- el,
4251
+ el, i,
4219
4252
  gradientDefs = { };
4220
4253
 
4221
- for (var i = linearGradientEls.length; i--; ) {
4254
+ i = linearGradientEls.length;
4255
+ for (; i--; ) {
4222
4256
  el = linearGradientEls[i];
4223
4257
  gradientDefs[el.getAttribute('id')] = el;
4224
4258
  }
4225
4259
 
4226
- for (var i = radialGradientEls.length; i--; ) {
4260
+ i = radialGradientEls.length;
4261
+ for (; i--; ) {
4227
4262
  el = radialGradientEls[i];
4228
4263
  gradientDefs[el.getAttribute('id')] = el;
4229
4264
  }
@@ -4235,20 +4270,20 @@ fabric.util.string = {
4235
4270
 
4236
4271
  })();
4237
4272
  (function(global) {
4238
-
4273
+
4239
4274
  "use strict";
4240
-
4275
+
4241
4276
  /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */
4242
-
4277
+
4243
4278
  var fabric = global.fabric || (global.fabric = { });
4244
4279
 
4245
- if (fabric.Point) {
4280
+ if (fabric.Point) {
4246
4281
  fabric.warn('fabric.Point is already defined');
4247
4282
  return;
4248
4283
  }
4249
4284
 
4250
4285
  fabric.Point = Point;
4251
-
4286
+
4252
4287
  /**
4253
4288
  * @name Point
4254
4289
  * @memberOf fabric
@@ -4262,11 +4297,11 @@ fabric.util.string = {
4262
4297
  this.init(x, y);
4263
4298
  }
4264
4299
  }
4265
-
4300
+
4266
4301
  Point.prototype = /** @scope fabric.Point.prototype */ {
4267
-
4302
+
4268
4303
  constructor: Point,
4269
-
4304
+
4270
4305
  /**
4271
4306
  * @method init
4272
4307
  * @param {Number} x
@@ -4276,7 +4311,7 @@ fabric.util.string = {
4276
4311
  this.x = x;
4277
4312
  this.y = y;
4278
4313
  },
4279
-
4314
+
4280
4315
  /**
4281
4316
  * @method add
4282
4317
  * @param {fabric.Point} that
@@ -4285,7 +4320,7 @@ fabric.util.string = {
4285
4320
  add: function (that) {
4286
4321
  return new Point(this.x + that.x, this.y + that.y);
4287
4322
  },
4288
-
4323
+
4289
4324
  /**
4290
4325
  * @method addEquals
4291
4326
  * @param {fabric.Point} that
@@ -4296,7 +4331,7 @@ fabric.util.string = {
4296
4331
  this.y += that.y;
4297
4332
  return this;
4298
4333
  },
4299
-
4334
+
4300
4335
  /**
4301
4336
  * @method scalarAdd
4302
4337
  * @param {Number} scalar
@@ -4305,7 +4340,7 @@ fabric.util.string = {
4305
4340
  scalarAdd: function (scalar) {
4306
4341
  return new Point(this.x + scalar, this.y + scalar);
4307
4342
  },
4308
-
4343
+
4309
4344
  /**
4310
4345
  * @method scalarAddEquals
4311
4346
  * @param {Number} scalar
@@ -4316,7 +4351,7 @@ fabric.util.string = {
4316
4351
  this.y += scalar;
4317
4352
  return this;
4318
4353
  },
4319
-
4354
+
4320
4355
  /**
4321
4356
  * @method subtract
4322
4357
  * @param {fabric.Point} that
@@ -4325,7 +4360,7 @@ fabric.util.string = {
4325
4360
  subtract: function (that) {
4326
4361
  return new Point(this.x - that.x, this.y - that.y);
4327
4362
  },
4328
-
4363
+
4329
4364
  /**
4330
4365
  * @method subtractEquals
4331
4366
  * @param {fabric.Point} that
@@ -4336,89 +4371,89 @@ fabric.util.string = {
4336
4371
  this.y -= that.y;
4337
4372
  return this;
4338
4373
  },
4339
-
4374
+
4340
4375
  scalarSubtract: function (scalar) {
4341
4376
  return new Point(this.x - scalar, this.y - scalar);
4342
4377
  },
4343
-
4378
+
4344
4379
  scalarSubtractEquals: function (scalar) {
4345
4380
  this.x -= scalar;
4346
4381
  this.y -= scalar;
4347
4382
  return this;
4348
4383
  },
4349
-
4384
+
4350
4385
  multiply: function (scalar) {
4351
4386
  return new Point(this.x * scalar, this.y * scalar);
4352
4387
  },
4353
-
4388
+
4354
4389
  multiplyEquals: function (scalar) {
4355
4390
  this.x *= scalar;
4356
4391
  this.y *= scalar;
4357
4392
  return this;
4358
4393
  },
4359
-
4394
+
4360
4395
  divide: function (scalar) {
4361
4396
  return new Point(this.x / scalar, this.y / scalar);
4362
4397
  },
4363
-
4398
+
4364
4399
  divideEquals: function (scalar) {
4365
4400
  this.x /= scalar;
4366
4401
  this.y /= scalar;
4367
4402
  return this;
4368
4403
  },
4369
-
4404
+
4370
4405
  eq: function (that) {
4371
- return (this.x == that.x && this.y == that.y);
4406
+ return (this.x === that.x && this.y === that.y);
4372
4407
  },
4373
-
4408
+
4374
4409
  lt: function (that) {
4375
4410
  return (this.x < that.x && this.y < that.y);
4376
4411
  },
4377
-
4412
+
4378
4413
  lte: function (that) {
4379
4414
  return (this.x <= that.x && this.y <= that.y);
4380
4415
  },
4381
-
4416
+
4382
4417
  gt: function (that) {
4383
4418
  return (this.x > that.x && this.y > that.y);
4384
4419
  },
4385
-
4420
+
4386
4421
  gte: function (that) {
4387
4422
  return (this.x >= that.x && this.y >= that.y);
4388
4423
  },
4389
-
4424
+
4390
4425
  lerp: function (that, t) {
4391
4426
  return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t);
4392
4427
  },
4393
-
4428
+
4394
4429
  distanceFrom: function (that) {
4395
4430
  var dx = this.x - that.x,
4396
4431
  dy = this.y - that.y;
4397
4432
  return Math.sqrt(dx * dx + dy * dy);
4398
4433
  },
4399
-
4434
+
4400
4435
  min: function (that) {
4401
4436
  return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y));
4402
4437
  },
4403
-
4438
+
4404
4439
  max: function (that) {
4405
4440
  return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y));
4406
4441
  },
4407
-
4442
+
4408
4443
  toString: function () {
4409
4444
  return this.x + "," + this.y;
4410
4445
  },
4411
-
4446
+
4412
4447
  setXY: function (x, y) {
4413
4448
  this.x = x;
4414
4449
  this.y = y;
4415
4450
  },
4416
-
4451
+
4417
4452
  setFromPoint: function (that) {
4418
4453
  this.x = that.x;
4419
4454
  this.y = that.y;
4420
4455
  },
4421
-
4456
+
4422
4457
  swap: function (that) {
4423
4458
  var x = this.x,
4424
4459
  y = this.y;
@@ -4428,8 +4463,8 @@ fabric.util.string = {
4428
4463
  that.y = y;
4429
4464
  }
4430
4465
  };
4431
-
4432
- })(typeof exports != 'undefined' ? exports : this);
4466
+
4467
+ })(typeof exports !== 'undefined' ? exports : this);
4433
4468
  (function(global) {
4434
4469
 
4435
4470
  "use strict";
@@ -4492,7 +4527,7 @@ fabric.util.string = {
4492
4527
  ua_t = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x),
4493
4528
  ub_t = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x),
4494
4529
  u_b = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);
4495
- if (u_b != 0) {
4530
+ if (u_b !== 0) {
4496
4531
  var ua = ua_t / u_b,
4497
4532
  ub = ub_t / u_b;
4498
4533
  if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {
@@ -4504,7 +4539,7 @@ fabric.util.string = {
4504
4539
  }
4505
4540
  }
4506
4541
  else {
4507
- if (ua_t == 0 || ub_t == 0) {
4542
+ if (ua_t === 0 || ub_t === 0) {
4508
4543
  result = new Intersection("Coincident");
4509
4544
  }
4510
4545
  else {
@@ -4578,18 +4613,18 @@ fabric.util.string = {
4578
4613
  return result;
4579
4614
  };
4580
4615
 
4581
- })(typeof exports != 'undefined' ? exports : this);
4616
+ })(typeof exports !== 'undefined' ? exports : this);
4582
4617
  (function(global) {
4583
-
4618
+
4584
4619
  "use strict";
4585
-
4620
+
4586
4621
  var fabric = global.fabric || (global.fabric = { });
4587
-
4622
+
4588
4623
  if (fabric.Color) {
4589
4624
  fabric.warn('fabric.Color is already defined.');
4590
4625
  return;
4591
4626
  }
4592
-
4627
+
4593
4628
  /**
4594
4629
  * The purpose of {@link fabric.Color} is to abstract and encapsulate common color operations;
4595
4630
  * {@link fabric.Color} is a constructor and creates instances of {@link fabric.Color} objects.
@@ -4606,11 +4641,11 @@ fabric.util.string = {
4606
4641
  this._tryParsingColor(color);
4607
4642
  }
4608
4643
  }
4609
-
4644
+
4610
4645
  fabric.Color = Color;
4611
-
4646
+
4612
4647
  fabric.Color.prototype = /** @scope fabric.Color.prototype */ {
4613
-
4648
+
4614
4649
  /**
4615
4650
  * @private
4616
4651
  * @method _tryParsingColor
@@ -4672,19 +4707,19 @@ fabric.util.string = {
4672
4707
  var source = this.getSource();
4673
4708
 
4674
4709
  var r = source[0].toString(16);
4675
- r = (r.length == 1) ? ('0' + r) : r;
4710
+ r = (r.length === 1) ? ('0' + r) : r;
4676
4711
 
4677
4712
  var g = source[1].toString(16);
4678
- g = (g.length == 1) ? ('0' + g) : g;
4713
+ g = (g.length === 1) ? ('0' + g) : g;
4679
4714
 
4680
4715
  var b = source[2].toString(16);
4681
- b = (b.length == 1) ? ('0' + b) : b;
4716
+ b = (b.length === 1) ? ('0' + b) : b;
4682
4717
 
4683
4718
  return r.toUpperCase() + g.toUpperCase() + b.toUpperCase();
4684
4719
  },
4685
4720
 
4686
4721
  /**
4687
- * Gets value of alpha channel for this color
4722
+ * Gets value of alpha channel for this color
4688
4723
  * @method getAlpha
4689
4724
  * @return {Number} 0-1
4690
4725
  */
@@ -4726,8 +4761,9 @@ fabric.util.string = {
4726
4761
  toBlackWhite: function(threshold) {
4727
4762
  var source = this.getSource(),
4728
4763
  average = (source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0),
4729
- currentAlpha = source[3],
4730
- threshold = threshold || 127;
4764
+ currentAlpha = source[3];
4765
+
4766
+ threshold = threshold || 127;
4731
4767
 
4732
4768
  average = (Number(average) < Number(threshold)) ? 0 : 255;
4733
4769
  this.setSource([average, average, average, currentAlpha]);
@@ -4760,14 +4796,14 @@ fabric.util.string = {
4760
4796
  return this;
4761
4797
  }
4762
4798
  };
4763
-
4799
+
4764
4800
  /**
4765
4801
  * Regex matching color in RGB or RGBA formats (ex: rgb(0, 0, 0), rgb(255, 100, 10, 0.5), rgb(1,1,1))
4766
4802
  * @static
4767
4803
  * @field
4768
4804
  */
4769
4805
  fabric.Color.reRGBa = /^rgba?\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(\d+(?:\.\d+)?))?\)$/;
4770
-
4806
+
4771
4807
  /**
4772
4808
  * Regex matching color in HEX format (ex: #FF5555, 010155, aff)
4773
4809
  * @static
@@ -4784,7 +4820,7 @@ fabric.util.string = {
4784
4820
  fabric.Color.fromRgb = function(color) {
4785
4821
  return Color.fromSource(Color.sourceFromRgb(color));
4786
4822
  };
4787
-
4823
+
4788
4824
  /**
4789
4825
  * Returns array represenatation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format
4790
4826
  * @method sourceFromRgb
@@ -4822,7 +4858,7 @@ fabric.util.string = {
4822
4858
  fabric.Color.fromHex = function(color) {
4823
4859
  return Color.fromSource(Color.sourceFromHex(color));
4824
4860
  };
4825
-
4861
+
4826
4862
  /**
4827
4863
  * Returns array represenatation (ex: [100, 100, 200, 1]) of a color that's in HEX format
4828
4864
  * @static
@@ -4846,7 +4882,7 @@ fabric.util.string = {
4846
4882
  ];
4847
4883
  }
4848
4884
  };
4849
-
4885
+
4850
4886
  /**
4851
4887
  * Returns new color object, when given color in array representation (ex: [200, 100, 100, 0.5])
4852
4888
  * @static
@@ -4859,8 +4895,8 @@ fabric.util.string = {
4859
4895
  return oColor;
4860
4896
  };
4861
4897
 
4862
- })(typeof exports != 'undefined' ? exports : this);
4863
- (function (global) {
4898
+ })(typeof exports !== 'undefined' ? exports : this);
4899
+ (function () {
4864
4900
 
4865
4901
  "use strict";
4866
4902
 
@@ -4924,6 +4960,28 @@ fabric.util.string = {
4924
4960
  */
4925
4961
  backgroundImageStretch: true,
4926
4962
 
4963
+ /**
4964
+ * Overlay image of canvas instance
4965
+ * Should be set via `setOverlayImage`
4966
+ * @property
4967
+ * @type String
4968
+ */
4969
+ overlayImage: '',
4970
+
4971
+ /**
4972
+ * Left offset of overlay image (if present)
4973
+ * @property
4974
+ * @type Number
4975
+ */
4976
+ overlayImageLeft: 0,
4977
+
4978
+ /**
4979
+ * Top offset of overlay image (if present)
4980
+ * @property
4981
+ * @type Number
4982
+ */
4983
+ overlayImageTop: 0,
4984
+
4927
4985
  /**
4928
4986
  * Indicates whether toObject/toDatalessObject should include default values
4929
4987
  * @property
@@ -4965,17 +5023,10 @@ fabric.util.string = {
4965
5023
  * @method onBeforeScaleRotate
4966
5024
  * @param {fabric.Object} target Object that's about to be scaled/rotated
4967
5025
  */
4968
- onBeforeScaleRotate: function (target) {
5026
+ onBeforeScaleRotate: function () {
4969
5027
  /* NOOP */
4970
5028
  },
4971
5029
 
4972
- /**
4973
- * Callback; invoked on every redraw of canvas and is being passed a number indicating current fps
4974
- * @method onFpsUpdate
4975
- * @param {Number} fps
4976
- */
4977
- onFpsUpdate: null,
4978
-
4979
5030
  _initStatic: function(el, options) {
4980
5031
  this._objects = [];
4981
5032
 
@@ -5343,39 +5394,25 @@ fabric.util.string = {
5343
5394
  this.clearContext(canvasToDrawOn);
5344
5395
  }
5345
5396
 
5346
- var length = this._objects.length,
5347
- activeGroup = this.getActiveGroup(),
5348
- startTime = new Date();
5397
+ var activeGroup = this.getActiveGroup();
5349
5398
 
5350
5399
  if (this.clipTo) {
5351
- canvasToDrawOn.save();
5352
- canvasToDrawOn.beginPath();
5353
- this.clipTo(canvasToDrawOn);
5354
- canvasToDrawOn.clip();
5400
+ this._clipCanvas(canvasToDrawOn);
5355
5401
  }
5356
5402
 
5357
5403
  canvasToDrawOn.fillStyle = this.backgroundColor;
5358
5404
  canvasToDrawOn.fillRect(0, 0, this.width, this.height);
5359
5405
 
5360
- if (typeof this.backgroundImage == 'object') {
5361
- canvasToDrawOn.save();
5362
- canvasToDrawOn.globalAlpha = this.backgroundImageOpacity;
5363
-
5364
- if (this.backgroundImageStretch) {
5365
- canvasToDrawOn.drawImage(this.backgroundImage, 0, 0, this.width, this.height);
5366
- }
5367
- else {
5368
- canvasToDrawOn.drawImage(this.backgroundImage, 0, 0);
5369
- }
5370
- canvasToDrawOn.restore();
5406
+ if (typeof this.backgroundImage === 'object') {
5407
+ this._drawBackroundImage(canvasToDrawOn);
5371
5408
  }
5372
5409
 
5373
- if (length) {
5374
- for (var i = 0; i < length; ++i) {
5375
- if (!activeGroup ||
5376
- (activeGroup && this._objects[i] && !activeGroup.contains(this._objects[i]))) {
5377
- this._draw(canvasToDrawOn, this._objects[i]);
5378
- }
5410
+ this.fire('before:render');
5411
+
5412
+ for (var i = 0, length = this._objects.length; i < length; ++i) {
5413
+ if (!activeGroup ||
5414
+ (activeGroup && this._objects[i] && !activeGroup.contains(this._objects[i]))) {
5415
+ this._draw(canvasToDrawOn, this._objects[i]);
5379
5416
  }
5380
5417
  }
5381
5418
 
@@ -5389,23 +5426,38 @@ fabric.util.string = {
5389
5426
  }
5390
5427
 
5391
5428
  if (this.overlayImage) {
5392
- this.contextContainer.drawImage(this.overlayImage, 0, 0);
5429
+ this.contextContainer.drawImage(this.overlayImage, this.overlayImageLeft, this.overlayImageTop);
5393
5430
  }
5394
5431
 
5395
5432
  if (this.controlsAboveOverlay) {
5396
5433
  this.drawControls(this.contextContainer);
5397
5434
  }
5398
5435
 
5399
- if (this.onFpsUpdate) {
5400
- var elapsedTime = new Date() - startTime;
5401
- this.onFpsUpdate(~~(1000 / elapsedTime));
5402
- }
5403
-
5404
5436
  this.fire('after:render');
5405
5437
 
5406
5438
  return this;
5407
5439
  },
5408
5440
 
5441
+ _clipCanvas: function(canvasToDrawOn) {
5442
+ canvasToDrawOn.save();
5443
+ canvasToDrawOn.beginPath();
5444
+ this.clipTo(canvasToDrawOn);
5445
+ canvasToDrawOn.clip();
5446
+ },
5447
+
5448
+ _drawBackroundImage: function(canvasToDrawOn) {
5449
+ canvasToDrawOn.save();
5450
+ canvasToDrawOn.globalAlpha = this.backgroundImageOpacity;
5451
+
5452
+ if (this.backgroundImageStretch) {
5453
+ canvasToDrawOn.drawImage(this.backgroundImage, 0, 0, this.width, this.height);
5454
+ }
5455
+ else {
5456
+ canvasToDrawOn.drawImage(this.backgroundImage, 0, 0);
5457
+ }
5458
+ canvasToDrawOn.restore();
5459
+ },
5460
+
5409
5461
  /**
5410
5462
  * Method to render only the top canvas.
5411
5463
  * Also used to render the group selection box.
@@ -5417,7 +5469,7 @@ fabric.util.string = {
5417
5469
  this.clearContext(this.contextTop || this.contextContainer);
5418
5470
 
5419
5471
  if (this.overlayImage) {
5420
- this.contextContainer.drawImage(this.overlayImage, 0, 0);
5472
+ this.contextContainer.drawImage(this.overlayImage, this.overlayImageLeft, this.overlayImageTop);
5421
5473
  }
5422
5474
 
5423
5475
  // we render the top context - last object
@@ -5470,8 +5522,12 @@ fabric.util.string = {
5470
5522
  * @return {String}
5471
5523
  */
5472
5524
  toDataURL: function (format, quality) {
5525
+ var canvasEl = this.upperCanvasEl || this.lowerCanvasEl;
5526
+
5473
5527
  this.renderAll(true);
5474
- var data = (this.upperCanvasEl || this.lowerCanvasEl).toDataURL('image/' + format, quality);
5528
+ var data = (fabric.StaticCanvas.supports('toDataURLWithQuality'))
5529
+ ? canvasEl.toDataURL('image/' + format, quality)
5530
+ : canvasEl.toDataURL('image/' + format);
5475
5531
  this.renderAll();
5476
5532
  return data;
5477
5533
  },
@@ -5634,8 +5690,9 @@ fabric.util.string = {
5634
5690
  var data = {
5635
5691
  objects: this._objects.map(function (instance) {
5636
5692
  // TODO (kangax): figure out how to clean this up
5693
+ var originalValue;
5637
5694
  if (!this.includeDefaultValues) {
5638
- var originalValue = instance.includeDefaultValues;
5695
+ originalValue = instance.includeDefaultValues;
5639
5696
  instance.includeDefaultValues = false;
5640
5697
  }
5641
5698
  var object = instance[methodName]();
@@ -5929,7 +5986,7 @@ fabric.util.string = {
5929
5986
  *
5930
5987
  * @method supports
5931
5988
  * @param methodName {String} Method to check support for;
5932
- * Could be one of "getImageData" or "toDataURL"
5989
+ * Could be one of "getImageData", "toDataURL" or "toDataURLWithQuality"
5933
5990
  * @return {Boolean | null} `true` if method is supported (or at least exists),
5934
5991
  * `null` if canvas element or context can not be initialized
5935
5992
  */
@@ -5956,6 +6013,14 @@ fabric.util.string = {
5956
6013
  case 'toDataURL':
5957
6014
  return typeof el.toDataURL !== 'undefined';
5958
6015
 
6016
+ case 'toDataURLWithQuality':
6017
+ try {
6018
+ el.toDataURL('image/jpeg', 0);
6019
+ return true;
6020
+ }
6021
+ catch (e) { }
6022
+ return false;
6023
+
5959
6024
  default:
5960
6025
  return null;
5961
6026
  }
@@ -5970,8 +6035,7 @@ fabric.util.string = {
5970
6035
  */
5971
6036
  fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject;
5972
6037
 
5973
- })(typeof exports != 'undefined' ? exports : this);
5974
-
6038
+ })();
5975
6039
  (function() {
5976
6040
 
5977
6041
  var extend = fabric.util.object.extend,
@@ -6013,13 +6077,14 @@ fabric.util.string = {
6013
6077
 
6014
6078
  this._initStatic(el, options);
6015
6079
  this._initInteractive();
6080
+ this._createCacheCanvas();
6016
6081
 
6017
6082
  fabric.Canvas.activeInstance = this;
6018
6083
  };
6019
6084
 
6020
6085
  function ProtoProxy(){ }
6021
6086
  ProtoProxy.prototype = fabric.StaticCanvas.prototype;
6022
- fabric.Canvas.prototype = new ProtoProxy;
6087
+ fabric.Canvas.prototype = new ProtoProxy();
6023
6088
 
6024
6089
  var InteractiveMethods = /** @scope fabric.Canvas.prototype */ {
6025
6090
 
@@ -6107,6 +6172,24 @@ fabric.util.string = {
6107
6172
  */
6108
6173
  containerClass: 'canvas-container',
6109
6174
 
6175
+ /**
6176
+ * When true, object detection happens on per-pixel basis rather than on per-bounding-box
6177
+ * @property
6178
+ * @type Boolean
6179
+ */
6180
+ perPixelTargetFind: false,
6181
+
6182
+ /**
6183
+ * Number of pixels around target pixel to tolerate (consider active) during object detection
6184
+ * @property
6185
+ * @type Number
6186
+ */
6187
+ targetFindTolerance: 0,
6188
+
6189
+ /**
6190
+ * @method _initInteractive
6191
+ * @private
6192
+ */
6110
6193
  _initInteractive: function() {
6111
6194
  this._currentTransform = null;
6112
6195
  this._groupSelector = null;
@@ -6158,7 +6241,7 @@ fabric.util.string = {
6158
6241
  _this.__onMouseMove(e);
6159
6242
  };
6160
6243
 
6161
- this._onResize = function (e) {
6244
+ this._onResize = function () {
6162
6245
  _this.calcOffset();
6163
6246
  };
6164
6247
 
@@ -6185,6 +6268,8 @@ fabric.util.string = {
6185
6268
  */
6186
6269
  __onMouseUp: function (e) {
6187
6270
 
6271
+ var target;
6272
+
6188
6273
  if (this.isDrawingMode && this._isCurrentlyDrawing) {
6189
6274
  this._finalizeDrawingPath();
6190
6275
  this.fire('mouse:up', { e: e });
@@ -6193,9 +6278,9 @@ fabric.util.string = {
6193
6278
 
6194
6279
  if (this._currentTransform) {
6195
6280
 
6196
- var transform = this._currentTransform,
6197
- target = transform.target;
6281
+ var transform = this._currentTransform;
6198
6282
 
6283
+ target = transform.target;
6199
6284
  if (target._scaling) {
6200
6285
  target._scaling = false;
6201
6286
  }
@@ -6242,7 +6327,7 @@ fabric.util.string = {
6242
6327
  }, 50);
6243
6328
 
6244
6329
  this.fire('mouse:up', { target: target, e: e });
6245
- target && target.fire('mouseup', { e: e })
6330
+ target && target.fire('mouseup', { e: e });
6246
6331
  },
6247
6332
 
6248
6333
  /**
@@ -6257,7 +6342,7 @@ fabric.util.string = {
6257
6342
  __onMouseDown: function (e) {
6258
6343
 
6259
6344
  // accept only left clicks
6260
- var isLeftClick = 'which' in e ? e.which == 1 : e.button == 1;
6345
+ var isLeftClick = 'which' in e ? e.which === 1 : e.button === 1;
6261
6346
  if (!isLeftClick && !fabric.isTouchSupported) return;
6262
6347
 
6263
6348
  if (this.isDrawingMode) {
@@ -6293,7 +6378,7 @@ fabric.util.string = {
6293
6378
  // rotate and scale will happen at the same time
6294
6379
  this.stateful && target.saveState();
6295
6380
 
6296
- if (corner = target._findTargetCorner(e, this._offset)) {
6381
+ if ((corner = target._findTargetCorner(e, this._offset))) {
6297
6382
  this.onBeforeScaleRotate(target);
6298
6383
  }
6299
6384
 
@@ -6329,6 +6414,8 @@ fabric.util.string = {
6329
6414
  */
6330
6415
  __onMouseMove: function (e) {
6331
6416
 
6417
+ var target;
6418
+
6332
6419
  if (this.isDrawingMode) {
6333
6420
  if (this._isCurrentlyDrawing) {
6334
6421
  this._captureDrawingPath(e);
@@ -6337,11 +6424,12 @@ fabric.util.string = {
6337
6424
  return;
6338
6425
  }
6339
6426
 
6340
- var groupSelector = this._groupSelector;
6427
+ var groupSelector = this._groupSelector, pointer;
6341
6428
 
6342
6429
  // We initially clicked in an empty area, so we draw a box for multiple selection.
6343
6430
  if (groupSelector !== null) {
6344
- var pointer = getPointer(e);
6431
+ pointer = getPointer(e);
6432
+
6345
6433
  groupSelector.left = pointer.x - this._offset.left - groupSelector.ex;
6346
6434
  groupSelector.top = pointer.y - this._offset.top - groupSelector.ey;
6347
6435
  this.renderTop();
@@ -6355,7 +6443,7 @@ fabric.util.string = {
6355
6443
  // what part of the pictures we are hovering to change the caret symbol.
6356
6444
  // We won't do that while dragging or rotating in order to improve the
6357
6445
  // performance.
6358
- var target = this.findTarget(e);
6446
+ target = this.findTarget(e);
6359
6447
 
6360
6448
  if (!target) {
6361
6449
  // image/text was hovered-out from, we remove its borders
@@ -6377,8 +6465,9 @@ fabric.util.string = {
6377
6465
  }
6378
6466
  else {
6379
6467
  // object is being transformed (scaled/rotated/moved/etc.)
6380
- var pointer = getPointer(e),
6381
- x = pointer.x,
6468
+ pointer = getPointer(e);
6469
+
6470
+ var x = pointer.x,
6382
6471
  y = pointer.y;
6383
6472
 
6384
6473
  this._currentTransform.target.isMoving = true;
@@ -6495,6 +6584,49 @@ fabric.util.string = {
6495
6584
  return { x: x, y: y };
6496
6585
  },
6497
6586
 
6587
+ _isTargetTransparent: function (target, x, y) {
6588
+ var cacheContext = this.contextCache;
6589
+
6590
+ var hasBorders = target.hasBorders, transparentCorners = target.transparentCorners;
6591
+ target.hasBorders = target.transparentCorners = false;
6592
+
6593
+ this._draw(cacheContext, target);
6594
+
6595
+ target.hasBorders = hasBorders;
6596
+ target.transparentCorners = transparentCorners;
6597
+
6598
+ // If tolerance is > 0 adjust start coords to take into account. If moves off Canvas fix to 0
6599
+ if (this.targetFindTolerance > 0) {
6600
+ if (x > this.targetFindTolerance) {
6601
+ x -= this.targetFindTolerance;
6602
+ }
6603
+ else {
6604
+ x = 0;
6605
+ }
6606
+ if (y > this.targetFindTolerance) {
6607
+ y -= this.targetFindTolerance;
6608
+ }
6609
+ else {
6610
+ y = 0;
6611
+ }
6612
+ }
6613
+
6614
+ var isTransparent = true;
6615
+ var imageData = cacheContext.getImageData(
6616
+ x, y, (this.targetFindTolerance * 2) || 1, (this.targetFindTolerance * 2) || 1);
6617
+
6618
+ // Split image data - for tolerance > 1, pixelDataSize = 4;
6619
+ for (var i = 3; i < imageData.data.length; i += 4) {
6620
+ var temp = imageData.data[i];
6621
+ isTransparent = temp <= 0;
6622
+ if (isTransparent === false) break; //Stop if colour found
6623
+ }
6624
+
6625
+ imageData = null;
6626
+ this.clearContext(cacheContext);
6627
+ return isTransparent;
6628
+ },
6629
+
6498
6630
  /**
6499
6631
  * @private
6500
6632
  * @method _shouldClearSelection
@@ -6522,7 +6654,7 @@ fabric.util.string = {
6522
6654
  corner,
6523
6655
  pointer = getPointer(e);
6524
6656
 
6525
- if (corner = target._findTargetCorner(e, this._offset)) {
6657
+ if ((corner = target._findTargetCorner(e, this._offset))) {
6526
6658
  action = (corner === 'ml' || corner === 'mr')
6527
6659
  ? 'scaleX'
6528
6660
  : (corner === 'mt' || corner === 'mb')
@@ -6652,17 +6784,14 @@ fabric.util.string = {
6652
6784
  minY = utilMin(this._freeDrawingYPoints),
6653
6785
  maxX = utilMax(this._freeDrawingXPoints),
6654
6786
  maxY = utilMax(this._freeDrawingYPoints),
6655
- ctx = this.contextTop,
6656
6787
  path = [ ],
6657
- xPoint,
6658
- yPoint,
6659
6788
  xPoints = this._freeDrawingXPoints,
6660
6789
  yPoints = this._freeDrawingYPoints;
6661
6790
 
6662
6791
  path.push('M ', xPoints[0] - minX, ' ', yPoints[0] - minY, ' ');
6663
6792
 
6664
- for (var i = 1; xPoint = xPoints[i], yPoint = yPoints[i]; i++) {
6665
- path.push('L ', xPoint - minX, ' ', yPoint - minY, ' ');
6793
+ for (var i = 1, len = xPoints.length; i < len; i++) {
6794
+ path.push('L ', xPoints[i] - minX, ' ', yPoints[i] - minY, ' ');
6666
6795
  }
6667
6796
 
6668
6797
  // TODO (kangax): maybe remove Path creation from here, to decouple fabric.Canvas from fabric.Path,
@@ -6827,9 +6956,7 @@ fabric.util.string = {
6827
6956
  },
6828
6957
 
6829
6958
  _findSelectedObjects: function (e) {
6830
- var target,
6831
- targetRegion,
6832
- group = [ ],
6959
+ var group = [ ],
6833
6960
  x1 = this._groupSelector.ex,
6834
6961
  y1 = this._groupSelector.ey,
6835
6962
  x2 = x1 + this._groupSelector.left,
@@ -6858,7 +6985,7 @@ fabric.util.string = {
6858
6985
  this.setActiveObject(group[0], e);
6859
6986
  }
6860
6987
  else if (group.length > 1) {
6861
- var group = new fabric.Group(group);
6988
+ group = new fabric.Group(group);
6862
6989
  this.setActiveGroup(group);
6863
6990
  group.saveCoords();
6864
6991
  this.fire('selection:created', { target: group });
@@ -6887,9 +7014,25 @@ fabric.util.string = {
6887
7014
  }
6888
7015
 
6889
7016
  // then check all of the objects on canvas
7017
+ // Cache all targets where their bounding box contains point.
7018
+ var possibleTargets = [];
6890
7019
  for (var i = this._objects.length; i--; ) {
6891
7020
  if (this._objects[i] && this.containsPoint(e, this._objects[i])) {
6892
- target = this._objects[i];
7021
+ if (this.perPixelTargetFind || this._objects[i].perPixelTargetFind) {
7022
+ possibleTargets[possibleTargets.length] = this._objects[i];
7023
+ }
7024
+ else {
7025
+ target = this._objects[i];
7026
+ this.relatedTarget = target;
7027
+ break;
7028
+ }
7029
+ }
7030
+ }
7031
+ for (var j = 0, len = possibleTargets.length; j < len; j++) {
7032
+ pointer = this.getPointer(e);
7033
+ var isTransparent = this._isTargetTransparent(possibleTargets[j], pointer.x, pointer.y);
7034
+ if (!isTransparent) {
7035
+ target = possibleTargets[j];
6893
7036
  this.relatedTarget = target;
6894
7037
  break;
6895
7038
  }
@@ -6927,6 +7070,13 @@ fabric.util.string = {
6927
7070
  this.contextTop = this.upperCanvasEl.getContext('2d');
6928
7071
  },
6929
7072
 
7073
+ _createCacheCanvas: function () {
7074
+ this.cacheCanvasEl = this._createCanvasElement();
7075
+ this.cacheCanvasEl.setAttribute('width', this.width);
7076
+ this.cacheCanvasEl.setAttribute('height', this.height);
7077
+ this.contextCache = this.cacheCanvasEl.getContext('2d');
7078
+ },
7079
+
6930
7080
  /**
6931
7081
  * @private
6932
7082
  * @method _initWrapperElement
@@ -7279,95 +7429,96 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
7279
7429
  }
7280
7430
  }
7281
7431
 
7282
- var _this = this,
7283
- numLoadedObjects = 0,
7284
- numTotalObjects = objects.length;
7432
+ /** @ignore */
7433
+ function loadObject(obj, index) {
7285
7434
 
7286
- if (numTotalObjects === 0 && callback) {
7287
- callback();
7288
- }
7435
+ var pathProp = obj.paths ? 'paths' : 'path';
7436
+ var path = obj[pathProp];
7289
7437
 
7290
- try {
7291
- objects.forEach(function (obj, index) {
7292
-
7293
- var pathProp = obj.paths ? 'paths' : 'path';
7294
- var path = obj[pathProp];
7295
-
7296
- delete obj[pathProp];
7297
-
7298
- if (typeof path !== 'string') {
7299
- switch (obj.type) {
7300
- case 'image':
7301
- fabric[fabric.util.string.capitalize(obj.type)].fromObject(obj, function (o) {
7302
- onObjectLoaded(o, index);
7303
- });
7304
- break;
7305
- default:
7306
- var klass = fabric[fabric.util.string.camelize(fabric.util.string.capitalize(obj.type))];
7307
- if (klass && klass.fromObject) {
7308
- // restore path
7309
- if (path) {
7310
- obj[pathProp] = path;
7311
- }
7312
- onObjectLoaded(klass.fromObject(obj), index);
7313
- }
7314
- break;
7315
- }
7438
+ delete obj[pathProp];
7439
+
7440
+ if (typeof path !== 'string') {
7441
+ if (obj.type === 'image') {
7442
+ fabric[fabric.util.string.capitalize(obj.type)].fromObject(obj, function (o) {
7443
+ onObjectLoaded(o, index);
7444
+ });
7316
7445
  }
7317
7446
  else {
7318
- if (obj.type === 'image') {
7319
- fabric.util.loadImage(path, function (image) {
7320
- var oImg = new fabric.Image(image);
7447
+ var klass = fabric[fabric.util.string.camelize(fabric.util.string.capitalize(obj.type))];
7448
+ if (!klass || !klass.fromObject) return;
7321
7449
 
7322
- oImg.setSourcePath(path);
7450
+ // restore path
7451
+ if (path) {
7452
+ obj[pathProp] = path;
7453
+ }
7454
+ onObjectLoaded(klass.fromObject(obj), index);
7455
+ }
7456
+ }
7457
+ else {
7458
+ if (obj.type === 'image') {
7459
+ fabric.util.loadImage(path, function (image) {
7460
+ var oImg = new fabric.Image(image);
7323
7461
 
7324
- fabric.util.object.extend(oImg, obj);
7325
- oImg.setAngle(obj.angle);
7462
+ oImg.setSourcePath(path);
7326
7463
 
7327
- onObjectLoaded(oImg, index);
7328
- });
7329
- }
7330
- else if (obj.type === 'text') {
7464
+ fabric.util.object.extend(oImg, obj);
7465
+ oImg.setAngle(obj.angle);
7331
7466
 
7332
- if (obj.useNative) {
7333
- onObjectLoaded(fabric.Text.fromObject(obj), index);
7334
- }
7335
- else {
7336
- obj.path = path;
7337
- var object = fabric.Text.fromObject(obj);
7338
- var onscriptload = function () {
7339
- // TODO (kangax): find out why Opera refuses to work without this timeout
7340
- if (Object.prototype.toString.call(fabric.window.opera) === '[object Opera]') {
7341
- setTimeout(function () {
7342
- onObjectLoaded(object, index);
7343
- }, 500);
7344
- }
7345
- else {
7346
- onObjectLoaded(object, index);
7347
- }
7348
- }
7467
+ onObjectLoaded(oImg, index);
7468
+ });
7469
+ }
7470
+ else if (obj.type === 'text') {
7349
7471
 
7350
- fabric.util.getScript(path, onscriptload);
7351
- }
7472
+ if (obj.useNative) {
7473
+ onObjectLoaded(fabric.Text.fromObject(obj), index);
7352
7474
  }
7353
7475
  else {
7354
- fabric.loadSVGFromURL(path, function (elements, options) {
7355
- var object = fabric.util.groupSVGElements(elements, obj, path);
7356
-
7357
- // copy parameters from serialied json to object (left, top, scaleX, scaleY, etc.)
7358
- // skip this step if an object is a PathGroup, since we already passed it options object before
7359
- if (!(object instanceof fabric.PathGroup)) {
7360
- fabric.util.object.extend(object, obj);
7361
- if (typeof obj.angle !== 'undefined') {
7362
- object.setAngle(obj.angle);
7363
- }
7476
+ obj.path = path;
7477
+ var object = fabric.Text.fromObject(obj);
7478
+ var onscriptload = function () {
7479
+ // TODO (kangax): find out why Opera refuses to work without this timeout
7480
+ if (Object.prototype.toString.call(fabric.window.opera) === '[object Opera]') {
7481
+ setTimeout(function () {
7482
+ onObjectLoaded(object, index);
7483
+ }, 500);
7364
7484
  }
7485
+ else {
7486
+ onObjectLoaded(object, index);
7487
+ }
7488
+ };
7365
7489
 
7366
- onObjectLoaded(object, index);
7367
- });
7490
+ fabric.util.getScript(path, onscriptload);
7368
7491
  }
7369
7492
  }
7370
- }, this);
7493
+ else {
7494
+ fabric.loadSVGFromURL(path, function (elements) {
7495
+ var object = fabric.util.groupSVGElements(elements, obj, path);
7496
+
7497
+ // copy parameters from serialied json to object (left, top, scaleX, scaleY, etc.)
7498
+ // skip this step if an object is a PathGroup, since we already passed it options object before
7499
+ if (!(object instanceof fabric.PathGroup)) {
7500
+ fabric.util.object.extend(object, obj);
7501
+ if (typeof obj.angle !== 'undefined') {
7502
+ object.setAngle(obj.angle);
7503
+ }
7504
+ }
7505
+
7506
+ onObjectLoaded(object, index);
7507
+ });
7508
+ }
7509
+ }
7510
+ }
7511
+
7512
+ var _this = this,
7513
+ numLoadedObjects = 0,
7514
+ numTotalObjects = objects.length;
7515
+
7516
+ if (numTotalObjects === 0 && callback) {
7517
+ callback();
7518
+ }
7519
+
7520
+ try {
7521
+ objects.forEach(loadObject, this);
7371
7522
  }
7372
7523
  catch(e) {
7373
7524
  fabric.log(e.message);
@@ -7503,7 +7654,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
7503
7654
 
7504
7655
  var fabric = global.fabric || (global.fabric = { }),
7505
7656
  extend = fabric.util.object.extend,
7506
- clone = fabric.util.object.clone,
7507
7657
  toFixed = fabric.util.toFixed,
7508
7658
  capitalize = fabric.util.string.capitalize,
7509
7659
  getPointer = fabric.util.getPointer,
@@ -7593,6 +7743,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
7593
7743
  */
7594
7744
  cornersize: 12,
7595
7745
 
7746
+ /**
7747
+ * @property
7748
+ * @type Boolean
7749
+ */
7750
+ transparentCorners: true,
7751
+
7596
7752
  /**
7597
7753
  * @property
7598
7754
  * @type Number
@@ -7706,9 +7862,11 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
7706
7862
  * @property
7707
7863
  * @type Number
7708
7864
  */
7709
- _theta: 0,
7865
+ _theta: 0,
7866
+
7867
+ perPixelTargetFind: false,
7710
7868
 
7711
- includeDefaultValues: true,
7869
+ includeDefaultValues: true,
7712
7870
 
7713
7871
  /**
7714
7872
  * List of properties to consider when checking if state of an object is changed (fabric.Object#hasStateChanged);
@@ -7742,7 +7900,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
7742
7900
  initialize: function(options) {
7743
7901
  if (options) {
7744
7902
  this.setOptions(options);
7745
- this._initGradient(options);
7746
7903
  }
7747
7904
  },
7748
7905
 
@@ -7750,7 +7907,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
7750
7907
  * @method initGradient
7751
7908
  */
7752
7909
  _initGradient: function(options) {
7753
- if (options.fill && typeof options.fill == 'object' && !(options.fill instanceof fabric.Gradient)) {
7910
+ if (options.fill && typeof options.fill === 'object' && !(options.fill instanceof fabric.Gradient)) {
7754
7911
  this.set('fill', new fabric.Gradient(options.fill));
7755
7912
  }
7756
7913
  },
@@ -7767,6 +7924,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
7767
7924
  this.set(prop, options[prop]);
7768
7925
  }
7769
7926
  }
7927
+ this._initGradient(options);
7770
7928
  },
7771
7929
 
7772
7930
  /**
@@ -7812,7 +7970,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
7812
7970
  selectable: this.selectable,
7813
7971
  hasControls: this.hasControls,
7814
7972
  hasBorders: this.hasBorders,
7815
- hasRotatingPoint: this.hasRotatingPoint
7973
+ hasRotatingPoint: this.hasRotatingPoint,
7974
+ transparentCorners: this.transparentCorners,
7975
+ perPixelTargetFind: this.perPixelTargetFind
7816
7976
  };
7817
7977
 
7818
7978
  if (!this.includeDefaultValues) {
@@ -8025,7 +8185,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8025
8185
 
8026
8186
  if (this.active && !noTransform) {
8027
8187
  this.drawBorders(ctx);
8028
- this.hideCorners || this.drawCorners(ctx);
8188
+ this.drawCorners(ctx);
8029
8189
  }
8030
8190
  ctx.restore();
8031
8191
  },
@@ -8058,29 +8218,34 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8058
8218
  scale: function(value) {
8059
8219
  this.scaleX = value;
8060
8220
  this.scaleY = value;
8221
+ this.setCoords();
8061
8222
  return this;
8062
8223
  },
8063
8224
 
8064
8225
  /**
8065
- * Scales an object to a given width (scaling by x/y equally)
8226
+ * Scales an object to a given width, with respect to bounding box (scaling by x/y equally)
8066
8227
  * @method scaleToWidth
8067
8228
  * @param value {Number} new width value
8068
8229
  * @return {fabric.Object} thisArg
8069
8230
  * @chainable
8070
8231
  */
8071
8232
  scaleToWidth: function(value) {
8072
- return this.scale(value / this.width);
8233
+ // adjust to bounding rect factor so that rotated shapes would fit as well
8234
+ var boundingRectFactor = this.getBoundingRectWidth() / this.getWidth();
8235
+ return this.scale(value / this.width / boundingRectFactor);
8073
8236
  },
8074
8237
 
8075
8238
  /**
8076
- * Scales an object to a given height (scaling by x/y equally)
8239
+ * Scales an object to a given height, with respect to bounding box (scaling by x/y equally)
8077
8240
  * @method scaleToHeight
8078
8241
  * @param value {Number} new height value
8079
8242
  * @return {fabric.Object} thisArg
8080
8243
  * @chainable
8081
8244
  */
8082
8245
  scaleToHeight: function(value) {
8083
- return this.scale(value / this.height);
8246
+ // adjust to bounding rect factor so that rotated shapes would fit as well
8247
+ var boundingRectFactor = this.getBoundingRectHeight() / this.getHeight();
8248
+ return this.scale(value / this.height / boundingRectFactor);
8084
8249
  },
8085
8250
 
8086
8251
  /**
@@ -8130,6 +8295,11 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8130
8295
  this.currentWidth = (this.width + strokeWidth) * this.scaleX + padding * 2;
8131
8296
  this.currentHeight = (this.height + strokeWidth) * this.scaleY + padding * 2;
8132
8297
 
8298
+ //If width is negative, make postive. Fixes path selection issue
8299
+ if(this.currentWidth < 0){
8300
+ this.currentWidth = Math.abs(this.currentWidth);
8301
+ }
8302
+
8133
8303
  this._hypotenuse = Math.sqrt(
8134
8304
  Math.pow(this.currentWidth / 2, 2) +
8135
8305
  Math.pow(this.currentHeight / 2, 2));
@@ -8209,6 +8379,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8209
8379
  * @return {Number} width value
8210
8380
  */
8211
8381
  getBoundingRectWidth: function() {
8382
+ this.oCoords || this.setCoords();
8212
8383
  var xCoords = [this.oCoords.tl.x, this.oCoords.tr.x, this.oCoords.br.x, this.oCoords.bl.x];
8213
8384
  var minX = fabric.util.array.min(xCoords);
8214
8385
  var maxX = fabric.util.array.max(xCoords);
@@ -8221,6 +8392,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8221
8392
  * @return {Number} height value
8222
8393
  */
8223
8394
  getBoundingRectHeight: function() {
8395
+ this.oCoords || this.setCoords();
8224
8396
  var yCoords = [this.oCoords.tl.y, this.oCoords.tr.y, this.oCoords.br.y, this.oCoords.bl.y];
8225
8397
  var minY = fabric.util.array.min(yCoords);
8226
8398
  var maxY = fabric.util.array.max(yCoords);
@@ -8266,7 +8438,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8266
8438
  ~~(h + padding2 + strokeWidth * this.scaleY)
8267
8439
  );
8268
8440
 
8269
- if (this.hasRotatingPoint && !this.hideCorners && !this.lockRotation) {
8441
+ if (this.hasRotatingPoint && !this.lockRotation && this.hasControls) {
8270
8442
 
8271
8443
  var rotateHeight = (
8272
8444
  this.flipY
@@ -8274,8 +8446,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8274
8446
  : -h - (strokeWidth * this.scaleY) - (padding * 2)
8275
8447
  ) / 2;
8276
8448
 
8277
- var rotateWidth = (-w/2);
8278
-
8279
8449
  ctx.beginPath();
8280
8450
  ctx.moveTo(0, rotateHeight);
8281
8451
  ctx.lineTo(0, rotateHeight + (this.flipY ? this.rotatingPointOffset : -this.rotatingPointOffset));
@@ -8298,8 +8468,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8298
8468
  x = -this.width/2, y = -this.height/2,
8299
8469
  _this = this,
8300
8470
  padding = this.padding,
8301
- width = this.getWidth(),
8302
- height = this.getHeight(),
8303
8471
  dashedArrayLength = this.strokeDashArray.length;
8304
8472
 
8305
8473
  ctx.save();
@@ -8308,6 +8476,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8308
8476
  function renderSide(xMultiplier, yMultiplier) {
8309
8477
 
8310
8478
  var lineLength = 0,
8479
+ lengthDiff = 0,
8311
8480
  sideLength = (yMultiplier ? _this.height : _this.width) + padding * 2;
8312
8481
 
8313
8482
  while (lineLength < sideLength) {
@@ -8316,7 +8485,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8316
8485
  lineLength += lengthOfSubPath;
8317
8486
 
8318
8487
  if (lineLength > sideLength) {
8319
- var lengthDiff = lineLength - sideLength;
8488
+ lengthDiff = lineLength - sideLength;
8320
8489
  }
8321
8490
 
8322
8491
  // track coords
@@ -8372,7 +8541,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8372
8541
  scaleOffsetSizeX = (size2 - size) / this.scaleX,
8373
8542
  scaleOffsetSizeY = (size2 - size) / this.scaleY,
8374
8543
  height = this.height,
8375
- width = this.width;
8544
+ width = this.width,
8545
+ methodName = this.transparentCorners ? 'strokeRect' : 'fillRect';
8376
8546
 
8377
8547
  ctx.save();
8378
8548
 
@@ -8386,28 +8556,28 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8386
8556
  _top = top - scaleOffsetY - strokeWidth2 - paddingY;
8387
8557
 
8388
8558
  ctx.clearRect(_left, _top, sizeX, sizeY);
8389
- ctx.strokeRect(_left, _top, sizeX, sizeY);
8559
+ ctx[methodName](_left, _top, sizeX, sizeY);
8390
8560
 
8391
8561
  // top-right
8392
8562
  _left = left + width - scaleOffsetX + strokeWidth2 + paddingX;
8393
8563
  _top = top - scaleOffsetY - strokeWidth2 - paddingY;
8394
8564
 
8395
8565
  ctx.clearRect(_left, _top, sizeX, sizeY);
8396
- ctx.strokeRect(_left, _top, sizeX, sizeY);
8566
+ ctx[methodName](_left, _top, sizeX, sizeY);
8397
8567
 
8398
8568
  // bottom-left
8399
8569
  _left = left - scaleOffsetX - strokeWidth2 - paddingX;
8400
8570
  _top = top + height + scaleOffsetSizeY + strokeWidth2 + paddingY;
8401
8571
 
8402
8572
  ctx.clearRect(_left, _top, sizeX, sizeY);
8403
- ctx.strokeRect(_left, _top, sizeX, sizeY);
8573
+ ctx[methodName](_left, _top, sizeX, sizeY);
8404
8574
 
8405
8575
  // bottom-right
8406
8576
  _left = left + width + scaleOffsetSizeX + strokeWidth2 + paddingX;
8407
8577
  _top = top + height + scaleOffsetSizeY + strokeWidth2 + paddingY;
8408
8578
 
8409
8579
  ctx.clearRect(_left, _top, sizeX, sizeY);
8410
- ctx.strokeRect(_left, _top, sizeX, sizeY);
8580
+ ctx[methodName](_left, _top, sizeX, sizeY);
8411
8581
 
8412
8582
  if (!this.lockUniScaling) {
8413
8583
  // middle-top
@@ -8415,28 +8585,28 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8415
8585
  _top = top - scaleOffsetY - strokeWidth2 - paddingY;
8416
8586
 
8417
8587
  ctx.clearRect(_left, _top, sizeX, sizeY);
8418
- ctx.strokeRect(_left, _top, sizeX, sizeY);
8588
+ ctx[methodName](_left, _top, sizeX, sizeY);
8419
8589
 
8420
8590
  // middle-bottom
8421
8591
  _left = left + width/2 - scaleOffsetX;
8422
8592
  _top = top + height + scaleOffsetSizeY + strokeWidth2 + paddingY;
8423
8593
 
8424
8594
  ctx.clearRect(_left, _top, sizeX, sizeY);
8425
- ctx.strokeRect(_left, _top, sizeX, sizeY);
8595
+ ctx[methodName](_left, _top, sizeX, sizeY);
8426
8596
 
8427
8597
  // middle-right
8428
8598
  _left = left + width + scaleOffsetSizeX + strokeWidth2 + paddingX;
8429
8599
  _top = top + height/2 - scaleOffsetY;
8430
8600
 
8431
8601
  ctx.clearRect(_left, _top, sizeX, sizeY);
8432
- ctx.strokeRect(_left, _top, sizeX, sizeY);
8602
+ ctx[methodName](_left, _top, sizeX, sizeY);
8433
8603
 
8434
8604
  // middle-left
8435
8605
  _left = left - scaleOffsetX - strokeWidth2 - paddingX;
8436
8606
  _top = top + height/2 - scaleOffsetY;
8437
8607
 
8438
8608
  ctx.clearRect(_left, _top, sizeX, sizeY);
8439
- ctx.strokeRect(_left, _top, sizeX, sizeY);
8609
+ ctx[methodName](_left, _top, sizeX, sizeY);
8440
8610
  }
8441
8611
 
8442
8612
  // middle-top-rotate
@@ -8449,7 +8619,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8449
8619
  : (top - (this.rotatingPointOffset / this.scaleY) - sizeY/2 - strokeWidth2 - paddingY);
8450
8620
 
8451
8621
  ctx.clearRect(_left, _top, sizeX, sizeY);
8452
- ctx.strokeRect(_left, _top, sizeX, sizeY);
8622
+ ctx[methodName](_left, _top, sizeX, sizeY);
8453
8623
  }
8454
8624
 
8455
8625
  ctx.restore();
@@ -8511,12 +8681,11 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8511
8681
  */
8512
8682
  toDataURL: function(callback) {
8513
8683
  var el = fabric.document.createElement('canvas');
8514
- if (!el.getContext && typeof G_vmlCanvasManager != 'undefined') {
8684
+ if (!el.getContext && typeof G_vmlCanvasManager !== 'undefined') {
8515
8685
  G_vmlCanvasManager.initElement(el);
8516
8686
  }
8517
8687
 
8518
- this.setCoords();
8519
- el.width = this.getBoundingRectWidth();
8688
+ el.width = this.getBoundingRectWidth();
8520
8689
  el.height = this.getBoundingRectHeight();
8521
8690
 
8522
8691
  fabric.util.wrapElement(el, 'div');
@@ -8614,7 +8783,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8614
8783
  tr: new fabric.Point(oCoords.tr.x, oCoords.tr.y),
8615
8784
  bl: new fabric.Point(oCoords.bl.x, oCoords.bl.y),
8616
8785
  br: new fabric.Point(oCoords.br.x, oCoords.br.y)
8617
- }
8786
+ };
8618
8787
  }
8619
8788
  var thisCoords = getCoords(this.oCoords),
8620
8789
  otherCoords = getCoords(other.oCoords);
@@ -8648,8 +8817,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8648
8817
  var oCoords = this.oCoords,
8649
8818
  tl = new fabric.Point(oCoords.tl.x, oCoords.tl.y),
8650
8819
  tr = new fabric.Point(oCoords.tr.x, oCoords.tr.y),
8651
- bl = new fabric.Point(oCoords.bl.x, oCoords.bl.y),
8652
- br = new fabric.Point(oCoords.br.x, oCoords.br.y);
8820
+ bl = new fabric.Point(oCoords.bl.x, oCoords.bl.y);
8653
8821
 
8654
8822
  return tl.x > selectionTL.x
8655
8823
  && tr.x < selectionBR.x
@@ -8684,29 +8852,33 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8684
8852
  lines;
8685
8853
 
8686
8854
  for (var i in this.oCoords) {
8855
+
8687
8856
  if (i === 'mtr' && !this.hasRotatingPoint) {
8688
- return false;
8857
+ continue;
8689
8858
  }
8859
+
8690
8860
  if (this.lockUniScaling && (i === 'mt' || i === 'mr' || i === 'mb' || i === 'ml')) {
8691
- return false;
8861
+ continue;
8692
8862
  }
8693
8863
 
8694
8864
  lines = this._getImageLines(this.oCoords[i].corner, i);
8865
+
8695
8866
  // debugging
8867
+
8696
8868
  // canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);
8697
- // canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);
8698
- //
8699
- // canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);
8700
- // canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);
8701
- //
8702
- // canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);
8703
- // canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);
8704
- //
8705
- // canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);
8706
- // canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);
8869
+ // canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);
8870
+
8871
+ // canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);
8872
+ // canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);
8873
+
8874
+ // canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);
8875
+ // canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);
8876
+
8877
+ // canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);
8878
+ // canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);
8707
8879
 
8708
8880
  xpoints = this._findCrossPoints(ex, ey, lines);
8709
- if (xpoints % 2 == 1 && xpoints != 0) {
8881
+ if (xpoints % 2 === 1 && xpoints !== 0) {
8710
8882
  this.__corner = i;
8711
8883
  return i;
8712
8884
  }
@@ -8739,7 +8911,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8739
8911
  continue;
8740
8912
  }
8741
8913
  // optimisation 3: vertical line case
8742
- if ((iLine.o.x == iLine.d.x) && (iLine.o.x >= ex)) {
8914
+ if ((iLine.o.x === iLine.d.x) && (iLine.o.x >= ex)) {
8743
8915
  xi = iLine.o.x;
8744
8916
  yi = ey;
8745
8917
  }
@@ -8758,7 +8930,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8758
8930
  xcount += 1;
8759
8931
  }
8760
8932
  // optimisation 4: specific for square images
8761
- if (xcount == 2) {
8933
+ if (xcount === 2) {
8762
8934
  break;
8763
8935
  }
8764
8936
  }
@@ -8771,7 +8943,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8771
8943
  * @private
8772
8944
  * @param oCoords {Object} coordinates of the image corners
8773
8945
  */
8774
- _getImageLines: function(oCoords, i) {
8946
+ _getImageLines: function(oCoords) {
8775
8947
  return {
8776
8948
  topline: {
8777
8949
  o: oCoords.tl,
@@ -8789,7 +8961,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
8789
8961
  o: oCoords.bl,
8790
8962
  d: oCoords.tl
8791
8963
  }
8792
- }
8964
+ };
8793
8965
  },
8794
8966
 
8795
8967
  /**
@@ -9010,11 +9182,44 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9010
9182
  return this.toObject();
9011
9183
  },
9012
9184
 
9185
+ /**
9186
+ * @method setGradientFill
9187
+ */
9013
9188
  setGradientFill: function(options) {
9014
9189
  this.set('fill', fabric.Gradient.forObject(this, options));
9015
9190
  },
9016
9191
 
9017
- animate: function(property, to, options) {
9192
+ /**
9193
+ * @method animate
9194
+ *
9195
+ * As object — multiple properties
9196
+ *
9197
+ * object.animate({ left: ..., top: ... });
9198
+ * object.animate({ left: ..., top: ... }, { duration: ... });
9199
+ *
9200
+ * As string — one property
9201
+ *
9202
+ * object.animate('left', ...);
9203
+ * object.animate('left', { duration: ... });
9204
+ *
9205
+ */
9206
+ animate: function() {
9207
+ if (arguments[0] && typeof arguments[0] === 'object') {
9208
+ for (var prop in arguments[0]) {
9209
+ this._animate(prop, arguments[0][prop], arguments[1]);
9210
+ }
9211
+ }
9212
+ else {
9213
+ this._animate.apply(this, arguments);
9214
+ }
9215
+ return this;
9216
+ },
9217
+
9218
+ /**
9219
+ * @private
9220
+ * @method _animate
9221
+ */
9222
+ _animate: function(property, to, options) {
9018
9223
  var obj = this;
9019
9224
 
9020
9225
  options || (options = { });
@@ -9023,7 +9228,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9023
9228
  options.from = this.get(property);
9024
9229
  }
9025
9230
 
9026
- if (/[+-]/.test((to + '').charAt(0))) {
9231
+ if (/[+\-]/.test((to + '').charAt(0))) {
9027
9232
  to = this.get(property) + parseFloat(to);
9028
9233
  }
9029
9234
 
@@ -9176,7 +9381,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9176
9381
 
9177
9382
  });
9178
9383
 
9179
- })(typeof exports != 'undefined' ? exports : this);
9384
+ })(typeof exports !== 'undefined' ? exports : this);
9180
9385
 
9181
9386
  (function(global) {
9182
9387
 
@@ -9184,7 +9389,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9184
9389
 
9185
9390
  var fabric = global.fabric || (global.fabric = { }),
9186
9391
  extend = fabric.util.object.extend,
9187
- parentSet = fabric.Object.prototype.set,
9188
9392
  coordProps = { 'x1': 1, 'x2': 1, 'y1': 1, 'y2': 1 };
9189
9393
 
9190
9394
  if (fabric.Line) {
@@ -9212,6 +9416,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9212
9416
  * @return {fabric.Line} thisArg
9213
9417
  */
9214
9418
  initialize: function(points, options) {
9419
+ options = options || { };
9420
+
9215
9421
  if (!points) {
9216
9422
  points = [0, 0, 0, 0];
9217
9423
  }
@@ -9361,7 +9567,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9361
9567
  return new fabric.Line(points, object);
9362
9568
  };
9363
9569
 
9364
- })(typeof exports != 'undefined' ? exports : this);
9570
+ })(typeof exports !== 'undefined' ? exports : this);
9365
9571
  (function(global) {
9366
9572
 
9367
9573
  "use strict";
@@ -9436,7 +9642,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9436
9642
  _render: function(ctx, noTransform) {
9437
9643
  ctx.beginPath();
9438
9644
  // multiply by currently set alpha (the one that was set by path group where this object is contained, for example)
9439
- ctx.globalAlpha *= this.opacity;
9645
+ ctx.globalAlpha = this.group ? (ctx.globalAlpha * this.opacity) : this.opacity;
9440
9646
  ctx.arc(noTransform ? this.left : 0, noTransform ? this.top : 0, this.radius, 0, piBy2, false);
9441
9647
  ctx.closePath();
9442
9648
  if (this.fill) {
@@ -9505,7 +9711,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9505
9711
  options || (options = { });
9506
9712
  var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES);
9507
9713
  if (!isValidRadius(parsedAttributes)) {
9508
- throw Error('value of `r` attribute is required and can not be negative');
9714
+ throw new Error('value of `r` attribute is required and can not be negative');
9509
9715
  }
9510
9716
  if ('left' in parsedAttributes) {
9511
9717
  parsedAttributes.left -= (options.width / 2) || 0;
@@ -9534,30 +9740,30 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9534
9740
  return new fabric.Circle(object);
9535
9741
  };
9536
9742
 
9537
- })(typeof exports != 'undefined' ? exports : this);
9743
+ })(typeof exports !== 'undefined' ? exports : this);
9538
9744
  (function(global) {
9539
-
9745
+
9540
9746
  "use strict";
9541
-
9747
+
9542
9748
  var fabric = global.fabric || (global.fabric = { });
9543
-
9749
+
9544
9750
  if (fabric.Triangle) {
9545
9751
  fabric.warn('fabric.Triangle is already defined');
9546
9752
  return;
9547
9753
  }
9548
-
9549
- /**
9754
+
9755
+ /**
9550
9756
  * @class Triangle
9551
9757
  * @extends fabric.Object
9552
9758
  */
9553
9759
  fabric.Triangle = fabric.util.createClass(fabric.Object, /** @scope fabric.Triangle.prototype */ {
9554
-
9760
+
9555
9761
  /**
9556
9762
  * @property
9557
9763
  * @type String
9558
9764
  */
9559
9765
  type: 'triangle',
9560
-
9766
+
9561
9767
  /**
9562
9768
  * Constructor
9563
9769
  * @method initialize
@@ -9566,28 +9772,28 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9566
9772
  */
9567
9773
  initialize: function(options) {
9568
9774
  options = options || { };
9569
-
9775
+
9570
9776
  this.callSuper('initialize', options);
9571
-
9777
+
9572
9778
  this.set('width', options.width || 100)
9573
9779
  .set('height', options.height || 100);
9574
9780
  },
9575
-
9781
+
9576
9782
  /**
9577
9783
  * @private
9578
9784
  * @method _render
9579
9785
  * @param ctx {CanvasRenderingContext2D} Context to render on
9580
9786
  */
9581
- _render: function(ctx) {
9787
+ _render: function(ctx) {
9582
9788
  var widthBy2 = this.width / 2,
9583
9789
  heightBy2 = this.height / 2;
9584
-
9790
+
9585
9791
  ctx.beginPath();
9586
9792
  ctx.moveTo(-widthBy2, heightBy2);
9587
9793
  ctx.lineTo(0, -heightBy2);
9588
9794
  ctx.lineTo(widthBy2, heightBy2);
9589
9795
  ctx.closePath();
9590
-
9796
+
9591
9797
  if (this.fill) {
9592
9798
  ctx.fill();
9593
9799
  }
@@ -9595,7 +9801,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9595
9801
  ctx.stroke();
9596
9802
  }
9597
9803
  },
9598
-
9804
+
9599
9805
  /**
9600
9806
  * Returns complexity of an instance
9601
9807
  * @method complexity
@@ -9604,7 +9810,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9604
9810
  complexity: function() {
9605
9811
  return 1;
9606
9812
  },
9607
-
9813
+
9608
9814
  /**
9609
9815
  * Returns svg representation of an instance
9610
9816
  * @method toSVG
@@ -9628,7 +9834,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9628
9834
  '/>';
9629
9835
  }
9630
9836
  });
9631
-
9837
+
9632
9838
  /**
9633
9839
  * Returns fabric.Triangle instance from an object representation
9634
9840
  * @static
@@ -9640,7 +9846,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9640
9846
  return new fabric.Triangle(object);
9641
9847
  };
9642
9848
 
9643
- })(typeof exports != 'undefined' ? exports : this);
9849
+ })(typeof exports !== 'undefined' ? exports : this);
9644
9850
  (function(global){
9645
9851
 
9646
9852
  "use strict";
@@ -9732,7 +9938,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9732
9938
  _render: function(ctx, noTransform) {
9733
9939
  ctx.beginPath();
9734
9940
  ctx.save();
9735
- ctx.globalAlpha *= this.opacity;
9941
+ ctx.globalAlpha = this.group ? (ctx.globalAlpha * this.opacity) : this.opacity;
9736
9942
  if (this.transformMatrix && this.group) {
9737
9943
  ctx.translate(this.cx, this.cy);
9738
9944
  }
@@ -9805,7 +10011,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9805
10011
  return new fabric.Ellipse(object);
9806
10012
  };
9807
10013
 
9808
- })(typeof exports != 'undefined' ? exports : this);
10014
+ })(typeof exports !== 'undefined' ? exports : this);
9809
10015
  (function(global) {
9810
10016
 
9811
10017
  "use strict";
@@ -9824,18 +10030,21 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9824
10030
  fabric.Rect = fabric.util.createClass(fabric.Object, /** @scope fabric.Rect.prototype */ {
9825
10031
 
9826
10032
  /**
10033
+ * Type of the instance
9827
10034
  * @property
9828
10035
  * @type String
9829
10036
  */
9830
10037
  type: 'rect',
9831
10038
 
9832
10039
  /**
10040
+ * Horizontal border radius
9833
10041
  * @property
9834
10042
  * @type Number
9835
10043
  */
9836
10044
  rx: 0,
9837
10045
 
9838
10046
  /**
10047
+ * Vertical border radius
9839
10048
  * @property
9840
10049
  * @type Number
9841
10050
  */
@@ -9848,6 +10057,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9848
10057
  * @return {Object} thisArg
9849
10058
  */
9850
10059
  initialize: function(options) {
10060
+ options = options || { };
10061
+
9851
10062
  this._initStateProperties();
9852
10063
  this.callSuper('initialize', options);
9853
10064
  this._initRxRy();
@@ -9890,7 +10101,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9890
10101
  h = this.height;
9891
10102
 
9892
10103
  ctx.beginPath();
9893
- ctx.globalAlpha *= this.opacity;
10104
+ ctx.globalAlpha = this.group ? (ctx.globalAlpha * this.opacity) : this.opacity;
9894
10105
 
9895
10106
  if (this.transformMatrix && this.group) {
9896
10107
  ctx.translate(
@@ -9926,7 +10137,11 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9926
10137
  }
9927
10138
  },
9928
10139
 
9929
- // since our coordinate system differs from that of SVG
10140
+ /**
10141
+ * @method _normalizeLeftTopProperties
10142
+ * @private
10143
+ * Since coordinate system differs from that of SVG
10144
+ */
9930
10145
  _normalizeLeftTopProperties: function(parsedAttributes) {
9931
10146
  if (parsedAttributes.left) {
9932
10147
  this.set('left', parsedAttributes.left + this.getWidth() / 2);
@@ -9940,6 +10155,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
9940
10155
  },
9941
10156
 
9942
10157
  /**
10158
+ * Returns complexity of an instance
9943
10159
  * @method complexity
9944
10160
  * @return {Number} complexity
9945
10161
  */
@@ -10025,7 +10241,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
10025
10241
  return new fabric.Rect(object);
10026
10242
  };
10027
10243
 
10028
- })(typeof exports != 'undefined' ? exports : this);
10244
+ })(typeof exports !== 'undefined' ? exports : this);
10029
10245
  (function(global) {
10030
10246
 
10031
10247
  "use strict";
@@ -10177,7 +10393,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
10177
10393
  return new fabric.Polyline(points, object);
10178
10394
  };
10179
10395
 
10180
- })(typeof exports != 'undefined' ? exports : this);
10396
+ })(typeof exports !== 'undefined' ? exports : this);
10181
10397
  (function(global) {
10182
10398
 
10183
10399
  "use strict";
@@ -10193,9 +10409,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
10193
10409
  return;
10194
10410
  }
10195
10411
 
10196
- function byX(p) { return p.x; }
10197
- function byY(p) { return p.y; }
10198
-
10199
10412
  /**
10200
10413
  * @class Polygon
10201
10414
  * @extends fabric.Object
@@ -10348,7 +10561,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
10348
10561
  return new fabric.Polygon(object.points, object);
10349
10562
  };
10350
10563
 
10351
- })(typeof exports != 'undefined' ? exports : this);
10564
+ })(typeof exports !== 'undefined' ? exports : this);
10352
10565
  (function(global) {
10353
10566
 
10354
10567
  var commandLengths = {
@@ -10417,7 +10630,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
10417
10630
  var sfactor_sq = 1 / d - 0.25;
10418
10631
  if (sfactor_sq < 0) sfactor_sq = 0;
10419
10632
  var sfactor = Math.sqrt(sfactor_sq);
10420
- if (sweep == large) sfactor = -sfactor;
10633
+ if (sweep === large) sfactor = -sfactor;
10421
10634
  var xc = 0.5 * (x0 + x1) - sfactor * (y1-y0);
10422
10635
  var yc = 0.5 * (y0 + y1) + sfactor * (x1-x0);
10423
10636
 
@@ -10425,9 +10638,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
10425
10638
  var th1 = Math.atan2(y1-yc, x1-xc);
10426
10639
 
10427
10640
  var th_arc = th1-th0;
10428
- if (th_arc < 0 && sweep == 1){
10641
+ if (th_arc < 0 && sweep === 1){
10429
10642
  th_arc += 2*Math.PI;
10430
- } else if (th_arc > 0 && sweep == 0) {
10643
+ } else if (th_arc > 0 && sweep === 0) {
10431
10644
  th_arc -= 2 * Math.PI;
10432
10645
  }
10433
10646
 
@@ -10481,10 +10694,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
10481
10694
  fabric.warn('fabric.Path is already defined');
10482
10695
  return;
10483
10696
  }
10484
- if (!fabric.Object) {
10485
- fabric.warn('fabric.Path requires fabric.Object');
10486
- return;
10487
- }
10488
10697
 
10489
10698
  /**
10490
10699
  * @private
@@ -10530,7 +10739,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
10530
10739
  this.setOptions(options);
10531
10740
 
10532
10741
  if (!path) {
10533
- throw Error('`path` argument is required');
10742
+ throw new Error('`path` argument is required');
10534
10743
  }
10535
10744
 
10536
10745
  var fromArray = _toString.call(path) === '[object Array]';
@@ -10982,7 +11191,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
10982
11191
  chunks,
10983
11192
  parsed;
10984
11193
 
10985
- for (var i = 0, j, chunksParsed, len = this.path.length; i < len; i++) {
11194
+ for (var i = 0, chunksParsed, len = this.path.length; i < len; i++) {
10986
11195
  currentPath = this.path[i];
10987
11196
  chunks = currentPath.slice(1).trim().replace(/(\d)-/g, '$1###-').split(/\s|,|###/);
10988
11197
  chunksParsed = [ currentPath.charAt(0) ];
@@ -11110,7 +11319,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11110
11319
  return new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options));
11111
11320
  };
11112
11321
 
11113
- })(typeof exports != 'undefined' ? exports : this);
11322
+ })(typeof exports !== 'undefined' ? exports : this);
11114
11323
  (function(global) {
11115
11324
 
11116
11325
  "use strict";
@@ -11118,7 +11327,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11118
11327
  var fabric = global.fabric || (global.fabric = { }),
11119
11328
  extend = fabric.util.object.extend,
11120
11329
  invoke = fabric.util.array.invoke,
11121
- parentSet = fabric.Object.prototype.set,
11122
11330
  parentToObject = fabric.Object.prototype.toObject,
11123
11331
  camelize = fabric.util.string.camelize,
11124
11332
  capitalize = fabric.util.string.capitalize;
@@ -11226,7 +11434,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11226
11434
  */
11227
11435
  toObject: function() {
11228
11436
  return extend(parentToObject.call(this), {
11229
- paths: invoke(this.getObjects(), 'clone'),
11437
+ paths: invoke(this.getObjects(), 'toObject'),
11230
11438
  sourcePath: this.sourcePath
11231
11439
  });
11232
11440
  },
@@ -11339,7 +11547,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11339
11547
  }
11340
11548
 
11341
11549
  /**
11342
- * Creates fabric.Triangle instance from an object representation
11550
+ * Creates fabric.PathGroup instance from an object representation
11343
11551
  * @static
11344
11552
  * @method fabric.PathGroup.fromObject
11345
11553
  * @param {Object} object
@@ -11350,7 +11558,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11350
11558
  return new fabric.PathGroup(paths, object);
11351
11559
  };
11352
11560
 
11353
- })(typeof exports != 'undefined' ? exports : this);
11561
+ })(typeof exports !== 'undefined' ? exports : this);
11354
11562
  (function(global){
11355
11563
 
11356
11564
  "use strict";
@@ -11386,6 +11594,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11386
11594
  * @return {Object} thisArg
11387
11595
  */
11388
11596
  initialize: function(objects, options) {
11597
+ options = options || { };
11598
+
11389
11599
  this.objects = objects || [];
11390
11600
  this.originalState = { };
11391
11601
 
@@ -11546,7 +11756,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11546
11756
  */
11547
11757
  toObject: function() {
11548
11758
  return extend(this.callSuper('toObject'), {
11549
- objects: invoke(this.objects, 'clone')
11759
+ objects: invoke(this.objects, 'toObject')
11550
11760
  });
11551
11761
  },
11552
11762
 
@@ -11561,8 +11771,11 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11561
11771
 
11562
11772
  var groupScaleFactor = Math.max(this.scaleX, this.scaleY);
11563
11773
 
11564
- for (var i = 0, len = this.objects.length, object; object = this.objects[i]; i++) {
11774
+ for (var i = 0, len = this.objects.length; i < len; i++) {
11775
+
11776
+ var object = this.objects[i];
11565
11777
  var originalScaleFactor = object.borderScaleFactor;
11778
+
11566
11779
  object.borderScaleFactor = groupScaleFactor;
11567
11780
  object.render(ctx);
11568
11781
  object.borderScaleFactor = originalScaleFactor;
@@ -11592,7 +11805,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11592
11805
  */
11593
11806
  complexity: function() {
11594
11807
  return this.getObjects().reduce(function(total, object) {
11595
- total += (typeof object.complexity == 'function') ? object.complexity() : 0;
11808
+ total += (typeof object.complexity === 'function') ? object.complexity() : 0;
11596
11809
  return total;
11597
11810
  }, 0);
11598
11811
  },
@@ -11621,8 +11834,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11621
11834
  var groupLeft = this.get('left'),
11622
11835
  groupTop = this.get('top'),
11623
11836
  groupAngle = this.getAngle() * (Math.PI / 180),
11624
- objectLeft = object.get('originalLeft'),
11625
- objectTop = object.get('originalTop'),
11626
11837
  rotatedTop = Math.cos(groupAngle) * object.get('top') + Math.sin(groupAngle) * object.get('left'),
11627
11838
  rotatedLeft = -Math.sin(groupAngle) * object.get('top') + Math.cos(groupAngle) * object.get('left');
11628
11839
 
@@ -11752,7 +11963,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11752
11963
  aX.push(o.oCoords[prop].x);
11753
11964
  aY.push(o.oCoords[prop].y);
11754
11965
  }
11755
- };
11966
+ }
11756
11967
 
11757
11968
  minX = min(aX);
11758
11969
  maxX = max(aX);
@@ -11834,7 +12045,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11834
12045
 
11835
12046
  fabric.Group.async = true;
11836
12047
 
11837
- })(typeof exports != 'undefined' ? exports : this);
12048
+ })(typeof exports !== 'undefined' ? exports : this);
11838
12049
  (function(global) {
11839
12050
 
11840
12051
  "use strict";
@@ -11848,11 +12059,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11848
12059
  if (global.fabric.Image) {
11849
12060
  fabric.warn('fabric.Image is already defined.');
11850
12061
  return;
11851
- };
11852
-
11853
- if (!fabric.Object) {
11854
- fabric.warn('fabric.Object is required for fabric.Image initialization');
11855
- return;
11856
12062
  }
11857
12063
 
11858
12064
  /**
@@ -11867,18 +12073,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11867
12073
  */
11868
12074
  active: false,
11869
12075
 
11870
- /**
11871
- * @property
11872
- * @type Boolean
11873
- */
11874
- bordervisibility: false,
11875
-
11876
- /**
11877
- * @property
11878
- * @type Boolean
11879
- */
11880
- cornervisibility: false,
11881
-
11882
12076
  /**
11883
12077
  * @property
11884
12078
  * @type String
@@ -11941,26 +12135,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
11941
12135
  };
11942
12136
  },
11943
12137
 
11944
- /**
11945
- * Sets border visibility
11946
- * @method setBorderVisibility
11947
- * @param {Boolean} visible When true, border is set to be visible
11948
- */
11949
- setBorderVisibility: function(visible) {
11950
- this._resetWidthHeight();
11951
- this._adjustWidthHeightToBorders(showBorder);
11952
- this.setCoords();
11953
- },
11954
-
11955
- /**
11956
- * Sets corner visibility
11957
- * @method setCornersVisibility
11958
- * @param {Boolean} visible When true, corners are set to be visible
11959
- */
11960
- setCornersVisibility: function(visible) {
11961
- this.cornervisibility = !!visible;
11962
- },
11963
-
11964
12138
  /**
11965
12139
  * Renders image on a specified context
11966
12140
  * @method render
@@ -12060,10 +12234,10 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
12060
12234
  var isLikelyNode = typeof Buffer !== 'undefined' && typeof window === 'undefined',
12061
12235
  imgEl = this._originalImage,
12062
12236
  canvasEl = fabric.document.createElement('canvas'),
12063
- replacement = isLikelyNode ? new (require('canvas').Image) : fabric.document.createElement('img'),
12237
+ replacement = isLikelyNode ? new (require('canvas').Image)() : fabric.document.createElement('img'),
12064
12238
  _this = this;
12065
12239
 
12066
- if (!canvasEl.getContext && typeof G_vmlCanvasManager != 'undefined') {
12240
+ if (!canvasEl.getContext && typeof G_vmlCanvasManager !== 'undefined') {
12067
12241
  G_vmlCanvasManager.initElement(canvasEl);
12068
12242
  }
12069
12243
 
@@ -12102,6 +12276,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
12102
12276
 
12103
12277
  /**
12104
12278
  * @private
12279
+ * @method _render
12105
12280
  */
12106
12281
  _render: function(ctx) {
12107
12282
  ctx.drawImage(
@@ -12115,20 +12290,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
12115
12290
 
12116
12291
  /**
12117
12292
  * @private
12118
- */
12119
- _adjustWidthHeightToBorders: function(showBorder) {
12120
- if (showBorder) {
12121
- this.currentBorder = this.borderwidth;
12122
- this.width += (2 * this.currentBorder);
12123
- this.height += (2 * this.currentBorder);
12124
- }
12125
- else {
12126
- this.currentBorder = 0;
12127
- }
12128
- },
12129
-
12130
- /**
12131
- * @private
12293
+ * @method _resetWidthHeight
12132
12294
  */
12133
12295
  _resetWidthHeight: function() {
12134
12296
  var element = this.getElement();
@@ -12140,6 +12302,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
12140
12302
  /**
12141
12303
  * The Image class's initialization method. This method is automatically
12142
12304
  * called by the constructor.
12305
+ * @private
12143
12306
  * @method _initElement
12144
12307
  * @param {HTMLImageElement|String} el The element representing the image
12145
12308
  */
@@ -12149,17 +12312,18 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
12149
12312
  },
12150
12313
 
12151
12314
  /**
12315
+ * @private
12152
12316
  * @method _initConfig
12153
12317
  * @param {Object} options Options object
12154
12318
  */
12155
12319
  _initConfig: function(options) {
12156
12320
  options || (options = { });
12157
12321
  this.setOptions(options);
12158
- this._setBorder();
12159
12322
  this._setWidthHeight(options);
12160
12323
  },
12161
12324
 
12162
12325
  /**
12326
+ * @private
12163
12327
  * @method _initFilters
12164
12328
  * @param {Object} object Object with filters property
12165
12329
  */
@@ -12173,29 +12337,17 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
12173
12337
 
12174
12338
  /**
12175
12339
  * @private
12176
- */
12177
- _setBorder: function() {
12178
- if (this.bordervisibility) {
12179
- this.currentBorder = this.borderwidth;
12180
- }
12181
- else {
12182
- this.currentBorder = 0;
12183
- }
12184
- },
12185
-
12186
- /**
12187
- * @private
12340
+ * @method _setWidthHeight
12341
+ * @param {Object} options Object with width/height properties
12188
12342
  */
12189
12343
  _setWidthHeight: function(options) {
12190
- var sidesBorderWidth = 2 * this.currentBorder;
12191
-
12192
12344
  this.width = 'width' in options
12193
12345
  ? options.width
12194
- : ((this.getElement().width || 0) + sidesBorderWidth);
12346
+ : (this.getElement().width || 0);
12195
12347
 
12196
12348
  this.height = 'height' in options
12197
12349
  ? options.height
12198
- : ((this.getElement().height || 0) + sidesBorderWidth);
12350
+ : (this.getElement().height || 0);
12199
12351
  },
12200
12352
 
12201
12353
  /**
@@ -12293,7 +12445,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
12293
12445
 
12294
12446
  fabric.Image.async = true;
12295
12447
 
12296
- })(typeof exports != 'undefined' ? exports : this);
12448
+ })(typeof exports !== 'undefined' ? exports : this);
12297
12449
 
12298
12450
  fabric.util.object.extend(fabric.Object.prototype, {
12299
12451
 
@@ -12855,29 +13007,29 @@ fabric.Image.filters.Tint = fabric.util.createClass( /** @scope fabric.Image.fil
12855
13007
  * @param {Object} canvasEl Canvas element to apply filter to
12856
13008
  */
12857
13009
  applyTo: function(canvasEl) {
12858
-
13010
+
12859
13011
  var context = canvasEl.getContext('2d'),
12860
13012
  imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
12861
13013
  data = imageData.data,
12862
- iLen = data.length, i,
12863
- r, g, b, a;
12864
-
12865
- var rgb = parseInt(this.color).toString(16);
12866
- var cr = parseInt('0x'+rgb.substr(0, 2));
12867
- var cg = parseInt('0x'+rgb.substr(2, 2));
12868
- var cb = parseInt('0x'+rgb.substr(4, 2));
12869
-
13014
+ iLen = data.length, i, a;
13015
+
13016
+ var rgb = parseInt(this.color, 10).toString(16);
13017
+
13018
+ var cr = parseInt('0x' + rgb.substr(0, 2), 16);
13019
+ var cg = parseInt('0x' + rgb.substr(2, 2), 16);
13020
+ var cb = parseInt('0x' + rgb.substr(4, 2), 16);
13021
+
12870
13022
  for (i = 0; i < iLen; i+=4) {
12871
13023
 
12872
13024
  a = data[i+3];
12873
-
12874
- if (a > 0){
13025
+
13026
+ if (a > 0){
12875
13027
  data[i] = cr;
12876
13028
  data[i+1] = cg;
12877
- data[i+2] = cb;
12878
- }
13029
+ data[i+2] = cb;
13030
+ }
12879
13031
  }
12880
-
13032
+
12881
13033
  context.putImageData(imageData, 0, 0);
12882
13034
  },
12883
13035
 
@@ -12909,10 +13061,6 @@ fabric.Image.filters.Tint.fromObject = function(object) {
12909
13061
  fabric.warn('fabric.Text is already defined');
12910
13062
  return;
12911
13063
  }
12912
- if (!fabric.Object) {
12913
- fabric.warn('fabric.Text requires fabric.Object');
12914
- return;
12915
- }
12916
13064
 
12917
13065
  /**
12918
13066
  * @class Text
@@ -13015,9 +13163,11 @@ fabric.Image.filters.Tint.fromObject = function(object) {
13015
13163
  * @return {fabric.Text} thisArg
13016
13164
  */
13017
13165
  initialize: function(text, options) {
13166
+ options = options || { };
13167
+
13018
13168
  this._initStateProperties();
13019
13169
  this.text = text;
13020
- this.setOptions(options || { });
13170
+ this.setOptions(options);
13021
13171
  this._theta = this.angle * Math.PI / 180;
13022
13172
  this._initDimensions();
13023
13173
  this.setCoords();
@@ -13031,7 +13181,7 @@ fabric.Image.filters.Tint.fromObject = function(object) {
13031
13181
  _initDimensions: function() {
13032
13182
  var canvasEl = fabric.document.createElement('canvas');
13033
13183
 
13034
- if (!canvasEl.getContext && typeof G_vmlCanvasManager != 'undefined') {
13184
+ if (!canvasEl.getContext && typeof G_vmlCanvasManager !== 'undefined') {
13035
13185
  G_vmlCanvasManager.initElement(canvasEl);
13036
13186
  }
13037
13187
 
@@ -13343,29 +13493,30 @@ fabric.Image.filters.Tint.fromObject = function(object) {
13343
13493
  _renderTextDecoration: function(ctx, textLines) {
13344
13494
 
13345
13495
  var halfOfVerticalBox = this._getTextHeight(ctx, textLines) / 2;
13496
+ var _this = this;
13346
13497
 
13347
13498
  function renderLinesAtOffset(offset) {
13348
13499
  for (var i = 0, len = textLines.length; i < len; i++) {
13349
13500
 
13350
13501
  var lineWidth = ctx.measureText(textLines[i]).width;
13351
- var lineLeftOffset = this._getLineLeftOffset(lineWidth);
13502
+ var lineLeftOffset = _this._getLineLeftOffset(lineWidth);
13352
13503
 
13353
13504
  ctx.fillRect(
13354
- (-this.width / 2) + lineLeftOffset,
13355
- (offset + (i * this.fontSize * this.lineHeight)) - halfOfVerticalBox,
13505
+ (-_this.width / 2) + lineLeftOffset,
13506
+ (offset + (i * _this.fontSize * _this.lineHeight)) - halfOfVerticalBox,
13356
13507
  lineWidth,
13357
13508
  1);
13358
13509
  }
13359
13510
  }
13360
13511
 
13361
13512
  if (this.textDecoration.indexOf('underline') > -1) {
13362
- renderLinesAtOffset.call(this, this.fontSize);
13513
+ renderLinesAtOffset(this.fontSize);
13363
13514
  }
13364
13515
  if (this.textDecoration.indexOf('line-through') > -1) {
13365
- renderLinesAtOffset.call(this, this.fontSize / 2);
13516
+ renderLinesAtOffset(this.fontSize / 2);
13366
13517
  }
13367
13518
  if (this.textDecoration.indexOf('overline') > -1) {
13368
- renderLinesAtOffset.call(this, 0);
13519
+ renderLinesAtOffset(0);
13369
13520
  }
13370
13521
  },
13371
13522
 
@@ -13393,7 +13544,7 @@ fabric.Image.filters.Tint.fromObject = function(object) {
13393
13544
  // Cufon doesn't play nice with textDecoration=underline if element doesn't have a parent
13394
13545
  container.appendChild(el);
13395
13546
 
13396
- if (typeof G_vmlCanvasManager == 'undefined') {
13547
+ if (typeof G_vmlCanvasManager === 'undefined') {
13397
13548
  el.innerHTML = this.text;
13398
13549
  }
13399
13550
  else {
@@ -13677,16 +13828,16 @@ fabric.Image.filters.Tint.fromObject = function(object) {
13677
13828
  }
13678
13829
 
13679
13830
  var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES);
13680
- var options = fabric.util.object.extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes);
13831
+ options = fabric.util.object.extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes);
13681
13832
  var text = new fabric.Text(element.textContent, options);
13682
13833
 
13683
13834
  return text;
13684
13835
  };
13685
13836
 
13686
- })(typeof exports != 'undefined' ? exports : this);
13837
+ })(typeof exports !== 'undefined' ? exports : this);
13687
13838
  (function() {
13688
13839
 
13689
- if (typeof document != 'undefined' && typeof window != 'undefined') {
13840
+ if (typeof document !== 'undefined' && typeof window !== 'undefined') {
13690
13841
  return;
13691
13842
  }
13692
13843
 
@@ -13700,7 +13851,7 @@ fabric.Image.filters.Tint.fromObject = function(object) {
13700
13851
  function request(url, encoding, callback) {
13701
13852
  var oURL = URL.parse(url),
13702
13853
  client = HTTP.createClient(oURL.port, oURL.hostname),
13703
- request = client.request('GET', oURL.pathname, { 'host': oURL.hostname });
13854
+ req = client.request('GET', oURL.pathname, { 'host': oURL.hostname });
13704
13855
 
13705
13856
  client.addListener('error', function(err) {
13706
13857
  if (err.errno === process.ECONNREFUSED) {
@@ -13711,8 +13862,8 @@ fabric.Image.filters.Tint.fromObject = function(object) {
13711
13862
  }
13712
13863
  });
13713
13864
 
13714
- request.end();
13715
- request.on('response', function (response) {
13865
+ req.end();
13866
+ req.on('response', function (response) {
13716
13867
  var body = "";
13717
13868
  if (encoding) {
13718
13869
  response.setEncoding(encoding);
@@ -13721,7 +13872,7 @@ fabric.Image.filters.Tint.fromObject = function(object) {
13721
13872
  callback(body);
13722
13873
  });
13723
13874
  response.on('data', function (chunk) {
13724
- if (response.statusCode == 200) {
13875
+ if (response.statusCode === 200) {
13725
13876
  body += chunk;
13726
13877
  }
13727
13878
  });
@@ -13787,8 +13938,8 @@ fabric.Image.filters.Tint.fromObject = function(object) {
13787
13938
  canvasEl.width = nodeCanvas.width;
13788
13939
  canvasEl.height = nodeCanvas.height;
13789
13940
 
13790
- var canvas = fabric.Canvas || fabric.StaticCanvas;
13791
- var fabricCanvas = new canvas(canvasEl);
13941
+ var FabricCanvas = fabric.Canvas || fabric.StaticCanvas;
13942
+ var fabricCanvas = new FabricCanvas(canvasEl);
13792
13943
  fabricCanvas.contextContainer = nodeCanvas.getContext('2d');
13793
13944
  fabricCanvas.nodeCanvas = nodeCanvas;
13794
13945
 
@@ -13798,9 +13949,6 @@ fabric.Image.filters.Tint.fromObject = function(object) {
13798
13949
  fabric.StaticCanvas.prototype.createPNGStream = function() {
13799
13950
  return this.nodeCanvas.createPNGStream();
13800
13951
  };
13801
- if (fabric.Canvas) {
13802
- fabric.Canvas.prototype.createPNGStream
13803
- }
13804
13952
 
13805
13953
  var origSetWidth = fabric.StaticCanvas.prototype.setWidth;
13806
13954
  fabric.StaticCanvas.prototype.setWidth = function(width) {
@@ -13822,4 +13970,4 @@ fabric.Image.filters.Tint.fromObject = function(object) {
13822
13970
  fabric.Canvas.prototype.setHeight = fabric.StaticCanvas.prototype.setHeight;
13823
13971
  }
13824
13972
 
13825
- })();
13973
+ })();