fabric-rails 1.0.12.1 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/CHANGELOG.md +4 -0
  2. data/README.md +1 -1
  3. data/lib/fabric/rails/version.rb +2 -2
  4. data/vendor/assets/javascripts/cufon.js +1226 -0
  5. data/vendor/assets/javascripts/event.js +20 -20
  6. data/vendor/assets/javascripts/excanvas.js +1464 -0
  7. data/vendor/assets/javascripts/fabric.js +56 -33
  8. data/vendor/assets/javascripts/fabric/HEADER.js +2 -4
  9. data/vendor/assets/javascripts/fabric/brushes/base_brush.class.js +96 -0
  10. data/vendor/assets/javascripts/fabric/brushes/circle_brush.class.js +99 -0
  11. data/vendor/assets/javascripts/fabric/brushes/pattern_brush.class.js +55 -0
  12. data/vendor/assets/javascripts/fabric/{freedrawing.class.js → brushes/pencil_brush.class.js} +73 -65
  13. data/vendor/assets/javascripts/fabric/brushes/spray_brush.class.js +157 -0
  14. data/vendor/assets/javascripts/fabric/canvas.class.js +154 -135
  15. data/vendor/assets/javascripts/fabric/color.class.js +195 -29
  16. data/vendor/assets/javascripts/fabric/filters/brightness_filter.class.js +70 -0
  17. data/vendor/assets/javascripts/fabric/filters/convolute_filter.class.js +122 -0
  18. data/vendor/assets/javascripts/fabric/filters/gradienttransparency_filter.class.js +69 -0
  19. data/vendor/assets/javascripts/fabric/filters/grayscale_filter.class.js +61 -0
  20. data/vendor/assets/javascripts/fabric/filters/invert_filter.class.js +57 -0
  21. data/vendor/assets/javascripts/fabric/filters/noise_filter.class.js +73 -0
  22. data/vendor/assets/javascripts/fabric/filters/pixelate_filter.class.js +98 -0
  23. data/vendor/assets/javascripts/fabric/filters/removewhite_filter.class.js +86 -0
  24. data/vendor/assets/javascripts/fabric/filters/sepia2_filter.class.js +61 -0
  25. data/vendor/assets/javascripts/fabric/filters/sepia_filter.class.js +58 -0
  26. data/vendor/assets/javascripts/fabric/filters/tint_filter.class.js +80 -0
  27. data/vendor/assets/javascripts/fabric/gradient.class.js +232 -80
  28. data/vendor/assets/javascripts/fabric/intersection.class.js +10 -28
  29. data/vendor/assets/javascripts/fabric/log.js +0 -2
  30. data/vendor/assets/javascripts/fabric/{canvas_animation.mixin.js → mixins/canvas_animation.mixin.js} +3 -6
  31. data/vendor/assets/javascripts/fabric/mixins/canvas_dataurl_exporter.mixin.js +137 -0
  32. data/vendor/assets/javascripts/fabric/{canvas_events.mixin.js → mixins/canvas_events.mixin.js} +97 -144
  33. data/vendor/assets/javascripts/fabric/{canvas_gestures.mixin.js → mixins/canvas_gestures.mixin.js} +4 -8
  34. data/vendor/assets/javascripts/fabric/{canvas_serialization.mixin.js → mixins/canvas_serialization.mixin.js} +19 -14
  35. data/vendor/assets/javascripts/fabric/mixins/collection.mixin.js +137 -0
  36. data/vendor/assets/javascripts/fabric/{object_geometry.mixin.js → mixins/object_geometry.mixin.js} +130 -47
  37. data/vendor/assets/javascripts/fabric/{object_interactivity.mixin.js → mixins/object_interactivity.mixin.js} +21 -102
  38. data/vendor/assets/javascripts/fabric/{object_origin.mixin.js → mixins/object_origin.mixin.js} +36 -26
  39. data/vendor/assets/javascripts/fabric/{object_straightening.mixin.js → mixins/object_straightening.mixin.js} +4 -9
  40. data/vendor/assets/javascripts/fabric/{observable.mixin.js → mixins/observable.mixin.js} +27 -35
  41. data/vendor/assets/javascripts/fabric/mixins/stateful.mixin.js +45 -0
  42. data/vendor/assets/javascripts/fabric/node.js +62 -26
  43. data/vendor/assets/javascripts/fabric/parser.js +181 -58
  44. data/vendor/assets/javascripts/fabric/pattern.class.js +43 -14
  45. data/vendor/assets/javascripts/fabric/point.class.js +4 -43
  46. data/vendor/assets/javascripts/fabric/shadow.class.js +19 -19
  47. data/vendor/assets/javascripts/fabric/{circle.class.js → shapes/circle.class.js} +32 -29
  48. data/vendor/assets/javascripts/fabric/{ellipse.class.js → shapes/ellipse.class.js} +45 -27
  49. data/vendor/assets/javascripts/fabric/{group.class.js → shapes/group.class.js} +67 -169
  50. data/vendor/assets/javascripts/fabric/{image.class.js → shapes/image.class.js} +134 -72
  51. data/vendor/assets/javascripts/fabric/{line.class.js → shapes/line.class.js} +67 -36
  52. data/vendor/assets/javascripts/fabric/{object.class.js → shapes/object.class.js} +394 -252
  53. data/vendor/assets/javascripts/fabric/{path.class.js → shapes/path.class.js} +89 -174
  54. data/vendor/assets/javascripts/fabric/{path_group.class.js → shapes/path_group.class.js} +12 -18
  55. data/vendor/assets/javascripts/fabric/{polygon.class.js → shapes/polygon.class.js} +64 -38
  56. data/vendor/assets/javascripts/fabric/{polyline.class.js → shapes/polyline.class.js} +64 -39
  57. data/vendor/assets/javascripts/fabric/{rect.class.js → shapes/rect.class.js} +78 -112
  58. data/vendor/assets/javascripts/fabric/{text.class.js → shapes/text.class.js} +264 -270
  59. data/vendor/assets/javascripts/fabric/shapes/text.cufon.js +79 -0
  60. data/vendor/assets/javascripts/fabric/{triangle.class.js → shapes/triangle.class.js} +46 -26
  61. data/vendor/assets/javascripts/fabric/static_canvas.class.js +134 -358
  62. data/vendor/assets/javascripts/fabric/util/anim_ease.js +2 -31
  63. data/vendor/assets/javascripts/fabric/util/dom_event.js +21 -7
  64. data/vendor/assets/javascripts/fabric/util/dom_misc.js +49 -39
  65. data/vendor/assets/javascripts/fabric/util/dom_request.js +1 -2
  66. data/vendor/assets/javascripts/fabric/util/dom_style.js +1 -2
  67. data/vendor/assets/javascripts/fabric/util/lang_array.js +19 -13
  68. data/vendor/assets/javascripts/fabric/util/lang_class.js +1 -2
  69. data/vendor/assets/javascripts/fabric/util/lang_function.js +3 -1
  70. data/vendor/assets/javascripts/fabric/util/lang_object.js +5 -5
  71. data/vendor/assets/javascripts/fabric/util/lang_string.js +7 -5
  72. data/vendor/assets/javascripts/fabric/util/misc.js +207 -42
  73. metadata +47 -29
  74. data/vendor/assets/javascripts/fabric/image_filters.js +0 -809
  75. data/vendor/assets/javascripts/fabric/scout.js +0 -45
  76. data/vendor/assets/javascripts/fabric/stateful.js +0 -88
@@ -3,13 +3,12 @@
3
3
  var degreesToRadians = fabric.util.degreesToRadians,
4
4
  radiansToDegrees = fabric.util.radiansToDegrees;
5
5
 
6
- fabric.util.object.extend(fabric.Canvas.prototype, /** @scope fabric.Canvas.prototype */ {
6
+ fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {
7
7
 
8
8
  /**
9
9
  * Method that defines actions when an Event.js gesture is detected on an object. Currently only supports
10
10
  * 2 finger gestures.
11
11
  *
12
- * @method __onTransformGesture
13
12
  * @param e Event object by Event.js
14
13
  * @param self Event proxy object by Event.js
15
14
  */
@@ -42,8 +41,7 @@
42
41
  var lockScalingX = target.get('lockScalingX'),
43
42
  lockScalingY = target.get('lockScalingY');
44
43
 
45
- if (lockScalingX && lockScalingY)
46
- return;
44
+ if (lockScalingX && lockScalingY) return;
47
45
 
48
46
  target._scaling = true;
49
47
 
@@ -70,10 +68,8 @@
70
68
  _rotateObjectByAngle: function(curAngle) {
71
69
  var t = this._currentTransform;
72
70
 
73
- if (t.target.get('lockRotation'))
74
- return;
75
-
71
+ if (t.target.get('lockRotation')) return;
76
72
  t.target.angle = radiansToDegrees(degreesToRadians(curAngle) + t.theta);
77
73
  }
78
74
  });
79
- })();
75
+ })();
@@ -1,9 +1,8 @@
1
- fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.StaticCanvas.prototype */ {
1
+ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {
2
2
 
3
3
  /**
4
4
  * Populates canvas with data from the specified dataless JSON
5
5
  * JSON format must conform to the one of `fabric.Canvas#toDatalessJSON`
6
- * @method loadFromDatalessJSON
7
6
  * @param {String|Object} json JSON string or object
8
7
  * @param {Function} callback Callback, invoked when json is parsed
9
8
  * and corresponding objects (e.g: fabric.Image)
@@ -20,7 +19,11 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.Stati
20
19
  ? JSON.parse(json)
21
20
  : json;
22
21
 
23
- if (!serialized || (serialized && !serialized.objects)) return;
22
+ if (!serialized) return;
23
+
24
+ if (!serialized.objects) {
25
+ serialized.objects = [];
26
+ }
24
27
 
25
28
  this.clear();
26
29
 
@@ -31,7 +34,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.Stati
31
34
  },
32
35
 
33
36
  /**
34
- * @method _enlivenDatalessObjects
37
+ * @private
35
38
  * @param {Array} objects
36
39
  * @param {Function} callback
37
40
  */
@@ -145,7 +148,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.Stati
145
148
  /**
146
149
  * Populates canvas with data from the specified JSON
147
150
  * JSON format must conform to the one of `fabric.Canvas#toJSON`
148
- * @method loadFromJSON
149
151
  * @param {String|Object} json JSON string or object
150
152
  * @param {Function} callback Callback, invoked when json is parsed
151
153
  * and corresponding objects (e.g: fabric.Image)
@@ -176,6 +178,10 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.Stati
176
178
  backgroundImageLoaded,
177
179
  overlayImageLoaded;
178
180
 
181
+ var cbIfLoaded = function () {
182
+ callback && backgroundImageLoaded && overlayImageLoaded && backgroundPatternLoaded && callback();
183
+ };
184
+
179
185
  if (serialized.backgroundImage) {
180
186
  this.setBackgroundImage(serialized.backgroundImage, function() {
181
187
 
@@ -186,7 +192,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.Stati
186
192
 
187
193
  backgroundImageLoaded = true;
188
194
 
189
- callback && overlayImageLoaded && backgroundPatternLoaded && callback();
195
+ cbIfLoaded();
190
196
  });
191
197
  }
192
198
  else {
@@ -202,7 +208,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.Stati
202
208
  _this.renderAll();
203
209
  overlayImageLoaded = true;
204
210
 
205
- callback && backgroundImageLoaded && backgroundPatternLoaded && callback();
211
+ cbIfLoaded();
206
212
  });
207
213
  }
208
214
  else {
@@ -215,7 +221,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.Stati
215
221
  _this.renderAll();
216
222
  backgroundPatternLoaded = true;
217
223
 
218
- callback && overlayImageLoaded && backgroundImageLoaded && callback();
224
+ cbIfLoaded();
219
225
  });
220
226
  }
221
227
  else {
@@ -228,12 +234,15 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.Stati
228
234
  },
229
235
 
230
236
  /**
231
- * @method _enlivenObjects
237
+ * @private
232
238
  * @param {Array} objects
233
239
  * @param {Function} callback
234
240
  */
235
241
  _enlivenObjects: function (objects, callback) {
236
242
  var _this = this;
243
+ if (objects.length === 0) {
244
+ callback && callback();
245
+ }
237
246
  fabric.util.enlivenObjects(objects, function(enlivenedObjects) {
238
247
  enlivenedObjects.forEach(function(obj, index) {
239
248
  _this.insertAt(obj, index, true);
@@ -244,7 +253,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.Stati
244
253
 
245
254
  /**
246
255
  * @private
247
- * @method _toDataURL
248
256
  * @param {String} format
249
257
  * @param {Function} callback
250
258
  */
@@ -256,7 +264,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.Stati
256
264
 
257
265
  /**
258
266
  * @private
259
- * @method _toDataURLWithMultiplier
260
267
  * @param {String} format
261
268
  * @param {Number} multiplier
262
269
  * @param {Function} callback
@@ -269,7 +276,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.Stati
269
276
 
270
277
  /**
271
278
  * Clones canvas instance
272
- * @method clone
273
279
  * @param {Object} [callback] Receives cloned instance as a first argument
274
280
  */
275
281
  clone: function (callback) {
@@ -285,7 +291,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.Stati
285
291
  * Clones canvas instance without cloning existing data.
286
292
  * This essentially copies canvas dimensions, clipping properties, etc.
287
293
  * but leaves data empty (so that you can populate it with your own)
288
- * @method cloneWithoutData
289
294
  * @param {Object} [callback] Receives cloned instance as a first argument
290
295
  */
291
296
  cloneWithoutData: function(callback) {
@@ -308,4 +313,4 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.Stati
308
313
  callback && callback(clone);
309
314
  }
310
315
  }
311
- });
316
+ });
@@ -0,0 +1,137 @@
1
+ /**
2
+ * @namespace fabric.Collection
3
+ */
4
+ fabric.Collection = {
5
+
6
+ /**
7
+ * Adds objects to collection, then renders canvas (if `renderOnAddition` is not `false`)
8
+ * Objects should be instances of (or inherit from) fabric.Object
9
+ * @param [...] Zero or more fabric instances
10
+ * @return {Self} thisArg
11
+ */
12
+ add: function () {
13
+ this._objects.push.apply(this._objects, arguments);
14
+ for (var i = arguments.length; i--; ) {
15
+ this._onObjectAdded(arguments[i]);
16
+ }
17
+ this.renderOnAddition && this.renderAll();
18
+ return this;
19
+ },
20
+
21
+ /**
22
+ * Inserts an object into collection at specified index and renders canvas
23
+ * An object should be an instance of (or inherit from) fabric.Object
24
+ * @param object {Object} Object to insert
25
+ * @param index {Number} index to insert object at
26
+ * @param nonSplicing {Boolean} when `true`, no splicing (shifting) of objects occurs
27
+ * @return {Self} thisArg
28
+ */
29
+ insertAt: function (object, index, nonSplicing) {
30
+ var objects = this.getObjects();
31
+ if (nonSplicing) {
32
+ objects[index] = object;
33
+ }
34
+ else {
35
+ objects.splice(index, 0, object);
36
+ }
37
+ this._onObjectAdded(object);
38
+ this.renderOnAddition && this.renderAll();
39
+ return this;
40
+ },
41
+
42
+ /**
43
+ * Removes an object from a group
44
+ * @param {Object} object
45
+ * @return {Self} thisArg
46
+ */
47
+ remove: function(object) {
48
+
49
+ var objects = this.getObjects();
50
+ var index = objects.indexOf(object);
51
+
52
+ // only call onObjectRemoved if an object was actually removed
53
+ if (index !== -1) {
54
+ objects.splice(index, 1);
55
+ this._onObjectRemoved(object);
56
+ }
57
+
58
+ this.renderAll && this.renderAll();
59
+ return object;
60
+ },
61
+
62
+ /**
63
+ * Executes given function for each object in this group
64
+ * @param {Function} callback
65
+ * Callback invoked with current object as first argument,
66
+ * index - as second and an array of all objects - as third.
67
+ * Iteration happens in reverse order (for performance reasons).
68
+ * Callback is invoked in a context of Global Object (e.g. `window`)
69
+ * when no `context` argument is given
70
+ *
71
+ * @param {Object} context Context (aka thisObject)
72
+ * @return {Self} thisArg
73
+ */
74
+ forEachObject: function(callback, context) {
75
+ var objects = this.getObjects(),
76
+ i = objects.length;
77
+ while (i--) {
78
+ callback.call(context, objects[i], i, objects);
79
+ }
80
+ return this;
81
+ },
82
+
83
+ /**
84
+ * Returns object at specified index
85
+ * @param {Number} index
86
+ * @return {Self} thisArg
87
+ */
88
+ item: function (index) {
89
+ return this.getObjects()[index];
90
+ },
91
+
92
+ /**
93
+ * Returns true if collection contains no objects
94
+ * @return {Boolean} true if collection is empty
95
+ */
96
+ isEmpty: function () {
97
+ return this.getObjects().length === 0;
98
+ },
99
+
100
+ /**
101
+ * Returns a size of a collection (i.e: length of an array containing its objects)
102
+ * @return {Number} Collection size
103
+ */
104
+ size: function() {
105
+ return this.getObjects().length;
106
+ },
107
+
108
+ /**
109
+ * Returns true if collection contains an object
110
+ * @param {Object} object Object to check against
111
+ * @return {Boolean} `true` if collection contains an object
112
+ */
113
+ contains: function(object) {
114
+ return this.getObjects().indexOf(object) > -1;
115
+ },
116
+
117
+ /**
118
+ * Returns number representation of a collection complexity
119
+ * @return {Number} complexity
120
+ */
121
+ complexity: function () {
122
+ return this.getObjects().reduce(function (memo, current) {
123
+ memo += current.complexity ? current.complexity() : 0;
124
+ return memo;
125
+ }, 0);
126
+ },
127
+
128
+ /**
129
+ * Makes all of the collection objects grayscale (i.e. calling `toGrayscale` on them)
130
+ * @return {Self} thisArg
131
+ */
132
+ toGrayscale: function() {
133
+ return this.forEachObject(function(obj) {
134
+ obj.toGrayscale();
135
+ });
136
+ }
137
+ };
@@ -2,16 +2,15 @@
2
2
 
3
3
  var degreesToRadians = fabric.util.degreesToRadians;
4
4
 
5
- fabric.util.object.extend(fabric.Object.prototype, /** @scope fabric.Object.prototype */ {
5
+ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {
6
6
 
7
7
  /**
8
- * Returns true if object intersects with an area formed by 2 points
9
- * @method intersectsWithRect
10
- * @param {Object} selectionTL
11
- * @param {Object} selectionBR
12
- * @return {Boolean}
8
+ * Checks if object intersects with an area formed by 2 points
9
+ * @param {Object} pointTL top-left point of area
10
+ * @param {Object} pointBR bottom-right point of area
11
+ * @return {Boolean} true if object intersects with an area formed by 2 points
13
12
  */
14
- intersectsWithRect: function(selectionTL, selectionBR) {
13
+ intersectsWithRect: function(pointTL, pointBR) {
15
14
  var oCoords = this.oCoords,
16
15
  tl = new fabric.Point(oCoords.tl.x, oCoords.tl.y),
17
16
  tr = new fabric.Point(oCoords.tr.x, oCoords.tr.y),
@@ -20,17 +19,16 @@
20
19
 
21
20
  var intersection = fabric.Intersection.intersectPolygonRectangle(
22
21
  [tl, tr, br, bl],
23
- selectionTL,
24
- selectionBR
22
+ pointTL,
23
+ pointBR
25
24
  );
26
25
  return intersection.status === 'Intersection';
27
26
  },
28
27
 
29
28
  /**
30
- * Returns true if object intersects with another object
31
- * @method intersectsWithObject
29
+ * Checks if object intersects with another object
32
30
  * @param {Object} other Object to test
33
- * @return {Boolean}
31
+ * @return {Boolean} true if object intersects with another object
34
32
  */
35
33
  intersectsWithObject: function(other) {
36
34
  // extracts coords
@@ -54,38 +52,126 @@
54
52
  },
55
53
 
56
54
  /**
57
- * Returns true if object is fully contained within area of another object
58
- * @method isContainedWithinObject
55
+ * Checks if object is fully contained within area of another object
59
56
  * @param {Object} other Object to test
60
- * @return {Boolean}
57
+ * @return {Boolean} true if object is fully contained within area of another object
61
58
  */
62
59
  isContainedWithinObject: function(other) {
63
- return this.isContainedWithinRect(other.oCoords.tl, other.oCoords.br);
60
+ var boundingRect = other.getBoundingRect(),
61
+ point1 = new fabric.Point(boundingRect.left, boundingRect.top),
62
+ point2 = new fabric.Point(boundingRect.left + boundingRect.width, boundingRect.top + boundingRect.height);
63
+
64
+ return this.isContainedWithinRect(point1, point2);
64
65
  },
65
66
 
66
67
  /**
67
- * Returns true if object is fully contained within area formed by 2 points
68
- * @method isContainedWithinRect
69
- * @param {Object} selectionTL
70
- * @param {Object} selectionBR
71
- * @return {Boolean}
68
+ * Checks if object is fully contained within area formed by 2 points
69
+ * @param {Object} pointTL top-left point of area
70
+ * @param {Object} pointBR bottom-right point of area
71
+ * @return {Boolean} true if object is fully contained within area formed by 2 points
72
72
  */
73
- isContainedWithinRect: function(selectionTL, selectionBR) {
74
- var oCoords = this.oCoords,
75
- tl = new fabric.Point(oCoords.tl.x, oCoords.tl.y),
76
- tr = new fabric.Point(oCoords.tr.x, oCoords.tr.y),
77
- bl = new fabric.Point(oCoords.bl.x, oCoords.bl.y);
73
+ isContainedWithinRect: function(pointTL, pointBR) {
74
+ var boundingRect = this.getBoundingRect();
75
+
76
+ return (
77
+ boundingRect.left > pointTL.x &&
78
+ boundingRect.left + boundingRect.width < pointBR.x &&
79
+ boundingRect.top > pointTL.y &&
80
+ boundingRect.top + boundingRect.height < pointBR.y
81
+ );
82
+ },
78
83
 
79
- return tl.x > selectionTL.x
80
- && tr.x < selectionBR.x
81
- && tl.y > selectionTL.y
82
- && bl.y < selectionBR.y;
84
+ /**
85
+ * Checks if point is inside the object
86
+ * @param {Object} point
87
+ * @return {Boolean} true if point is inside the object
88
+ */
89
+ containsPoint: function(point) {
90
+ var lines = this._getImageLines(this.oCoords),
91
+ xPoints = this._findCrossPoints(point, lines);
92
+
93
+ // if xPoints is odd then point is inside the object
94
+ return (xPoints !== 0 && xPoints % 2 === 1);
95
+ },
96
+
97
+ /**
98
+ * Method that returns an object with the object edges in it, given the coordinates of the corners
99
+ * @private
100
+ * @param {Object} oCoords Coordinates of the object corners
101
+ */
102
+ _getImageLines: function(oCoords) {
103
+ return {
104
+ topline: {
105
+ o: oCoords.tl,
106
+ d: oCoords.tr
107
+ },
108
+ rightline: {
109
+ o: oCoords.tr,
110
+ d: oCoords.br
111
+ },
112
+ bottomline: {
113
+ o: oCoords.br,
114
+ d: oCoords.bl
115
+ },
116
+ leftline: {
117
+ o: oCoords.bl,
118
+ d: oCoords.tl
119
+ }
120
+ };
121
+ },
122
+
123
+ /**
124
+ * Helper method to determine how many cross points are between the 4 object edges
125
+ * and the horizontal line determined by a point on canvas
126
+ * @private
127
+ * @param {Object} point
128
+ * @param {Object} oCoords Coordinates of the image being evaluated
129
+ */
130
+ _findCrossPoints: function(point, oCoords) {
131
+ var b1, b2, a1, a2, xi, yi,
132
+ xcount = 0,
133
+ iLine;
134
+
135
+ for (var lineKey in oCoords) {
136
+ iLine = oCoords[lineKey];
137
+ // optimisation 1: line below point. no cross
138
+ if ((iLine.o.y < point.y) && (iLine.d.y < point.y)) {
139
+ continue;
140
+ }
141
+ // optimisation 2: line above point. no cross
142
+ if ((iLine.o.y >= point.y) && (iLine.d.y >= point.y)) {
143
+ continue;
144
+ }
145
+ // optimisation 3: vertical line case
146
+ if ((iLine.o.x === iLine.d.x) && (iLine.o.x >= point.x)) {
147
+ xi = iLine.o.x;
148
+ yi = point.y;
149
+ }
150
+ // calculate the intersection point
151
+ else {
152
+ b1 = 0;
153
+ b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x);
154
+ a1 = point.y- b1 * point.x;
155
+ a2 = iLine.o.y - b2 * iLine.o.x;
156
+
157
+ xi = - (a1 - a2) / (b1 - b2);
158
+ yi = a1 + b1 * xi;
159
+ }
160
+ // dont count xi < point.x cases
161
+ if (xi >= point.x) {
162
+ xcount += 1;
163
+ }
164
+ // optimisation 4: specific for square images
165
+ if (xcount === 2) {
166
+ break;
167
+ }
168
+ }
169
+ return xcount;
83
170
  },
84
171
 
85
172
  /**
86
173
  * Returns width of an object's bounding rectangle
87
174
  * @deprecated since 1.0.4
88
- * @method getBoundingRectWidth
89
175
  * @return {Number} width value
90
176
  */
91
177
  getBoundingRectWidth: function() {
@@ -95,7 +181,6 @@
95
181
  /**
96
182
  * Returns height of an object's bounding rectangle
97
183
  * @deprecated since 1.0.4
98
- * @method getBoundingRectHeight
99
184
  * @return {Number} height value
100
185
  */
101
186
  getBoundingRectHeight: function() {
@@ -104,7 +189,6 @@
104
189
 
105
190
  /**
106
191
  * Returns coordinates of object's bounding rectangle (left, top, width, height)
107
- * @method getBoundingRect
108
192
  * @return {Object} Object with left, top, width, height properties
109
193
  */
110
194
  getBoundingRect: function() {
@@ -130,7 +214,6 @@
130
214
 
131
215
  /**
132
216
  * Returns width of an object
133
- * @method getWidth
134
217
  * @return {Number} width value
135
218
  */
136
219
  getWidth: function() {
@@ -139,7 +222,6 @@
139
222
 
140
223
  /**
141
224
  * Returns height of an object
142
- * @method getHeight
143
225
  * @return {Number} height value
144
226
  */
145
227
  getHeight: function() {
@@ -149,7 +231,6 @@
149
231
  /**
150
232
  * Makes sure the scale is valid and modifies it if necessary
151
233
  * @private
152
- * @method _constrainScale
153
234
  * @param {Number} value
154
235
  * @return {Number}
155
236
  */
@@ -166,7 +247,6 @@
166
247
 
167
248
  /**
168
249
  * Scales an object (equally by x and y)
169
- * @method scale
170
250
  * @param value {Number} scale factor
171
251
  * @return {fabric.Object} thisArg
172
252
  * @chainable
@@ -188,7 +268,6 @@
188
268
 
189
269
  /**
190
270
  * Scales an object to a given width, with respect to bounding box (scaling by x/y equally)
191
- * @method scaleToWidth
192
271
  * @param value {Number} new width value
193
272
  * @return {fabric.Object} thisArg
194
273
  * @chainable
@@ -201,7 +280,6 @@
201
280
 
202
281
  /**
203
282
  * Scales an object to a given height, with respect to bounding box (scaling by x/y equally)
204
- * @method scaleToHeight
205
283
  * @param value {Number} new height value
206
284
  * @return {fabric.Object} thisArg
207
285
  * @chainable
@@ -214,7 +292,6 @@
214
292
 
215
293
  /**
216
294
  * Sets corner position coordinates based on current angle, width and height
217
- * @method setCoords
218
295
  * @return {fabric.Object} thisArg
219
296
  * @chainable
220
297
  */
@@ -236,7 +313,7 @@
236
313
  Math.pow(this.currentWidth / 2, 2) +
237
314
  Math.pow(this.currentHeight / 2, 2));
238
315
 
239
- var _angle = Math.atan(this.currentHeight / this.currentWidth);
316
+ var _angle = Math.atan(isFinite(this.currentHeight / this.currentWidth) ? this.currentHeight / this.currentWidth : 0);
240
317
 
241
318
  // offset added for rotate and scale actions
242
319
  var offsetX = Math.cos(_angle + theta) * _hypotenuse,
@@ -278,8 +355,8 @@
278
355
  y: bl.y + (this.currentWidth/2 * sinTh)
279
356
  };
280
357
  var mtr = {
281
- x: tl.x + (this.currentWidth/2 * cosTh),
282
- y: tl.y + (this.currentWidth/2 * sinTh)
358
+ x: mt.x,
359
+ y: mt.y
283
360
  };
284
361
 
285
362
  // debugging
@@ -296,13 +373,19 @@
296
373
  // canvas.contextTop.fillRect(mt.x, mt.y, 3, 3);
297
374
  // }, 50);
298
375
 
299
- // clockwise
300
- this.oCoords = { tl: tl, tr: tr, br: br, bl: bl, ml: ml, mt: mt, mr: mr, mb: mb, mtr: mtr };
376
+ this.oCoords = {
377
+ // corners
378
+ tl: tl, tr: tr, br: br, bl: bl,
379
+ // middle
380
+ ml: ml, mt: mt, mr: mr, mb: mb,
381
+ // rotating point
382
+ mtr: mtr
383
+ };
301
384
 
302
385
  // set coordinates of the draggable boxes in the corners used to scale/rotate the image
303
- this._setCornerCoords();
386
+ this._setCornerCoords && this._setCornerCoords();
304
387
 
305
388
  return this;
306
389
  }
307
390
  });
308
- })();
391
+ })();