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.
- data/CHANGELOG.md +4 -0
- data/README.md +1 -1
- data/lib/fabric/rails/version.rb +2 -2
- data/vendor/assets/javascripts/cufon.js +1226 -0
- data/vendor/assets/javascripts/event.js +20 -20
- data/vendor/assets/javascripts/excanvas.js +1464 -0
- data/vendor/assets/javascripts/fabric.js +56 -33
- data/vendor/assets/javascripts/fabric/HEADER.js +2 -4
- data/vendor/assets/javascripts/fabric/brushes/base_brush.class.js +96 -0
- data/vendor/assets/javascripts/fabric/brushes/circle_brush.class.js +99 -0
- data/vendor/assets/javascripts/fabric/brushes/pattern_brush.class.js +55 -0
- data/vendor/assets/javascripts/fabric/{freedrawing.class.js → brushes/pencil_brush.class.js} +73 -65
- data/vendor/assets/javascripts/fabric/brushes/spray_brush.class.js +157 -0
- data/vendor/assets/javascripts/fabric/canvas.class.js +154 -135
- data/vendor/assets/javascripts/fabric/color.class.js +195 -29
- data/vendor/assets/javascripts/fabric/filters/brightness_filter.class.js +70 -0
- data/vendor/assets/javascripts/fabric/filters/convolute_filter.class.js +122 -0
- data/vendor/assets/javascripts/fabric/filters/gradienttransparency_filter.class.js +69 -0
- data/vendor/assets/javascripts/fabric/filters/grayscale_filter.class.js +61 -0
- data/vendor/assets/javascripts/fabric/filters/invert_filter.class.js +57 -0
- data/vendor/assets/javascripts/fabric/filters/noise_filter.class.js +73 -0
- data/vendor/assets/javascripts/fabric/filters/pixelate_filter.class.js +98 -0
- data/vendor/assets/javascripts/fabric/filters/removewhite_filter.class.js +86 -0
- data/vendor/assets/javascripts/fabric/filters/sepia2_filter.class.js +61 -0
- data/vendor/assets/javascripts/fabric/filters/sepia_filter.class.js +58 -0
- data/vendor/assets/javascripts/fabric/filters/tint_filter.class.js +80 -0
- data/vendor/assets/javascripts/fabric/gradient.class.js +232 -80
- data/vendor/assets/javascripts/fabric/intersection.class.js +10 -28
- data/vendor/assets/javascripts/fabric/log.js +0 -2
- data/vendor/assets/javascripts/fabric/{canvas_animation.mixin.js → mixins/canvas_animation.mixin.js} +3 -6
- data/vendor/assets/javascripts/fabric/mixins/canvas_dataurl_exporter.mixin.js +137 -0
- data/vendor/assets/javascripts/fabric/{canvas_events.mixin.js → mixins/canvas_events.mixin.js} +97 -144
- data/vendor/assets/javascripts/fabric/{canvas_gestures.mixin.js → mixins/canvas_gestures.mixin.js} +4 -8
- data/vendor/assets/javascripts/fabric/{canvas_serialization.mixin.js → mixins/canvas_serialization.mixin.js} +19 -14
- data/vendor/assets/javascripts/fabric/mixins/collection.mixin.js +137 -0
- data/vendor/assets/javascripts/fabric/{object_geometry.mixin.js → mixins/object_geometry.mixin.js} +130 -47
- data/vendor/assets/javascripts/fabric/{object_interactivity.mixin.js → mixins/object_interactivity.mixin.js} +21 -102
- data/vendor/assets/javascripts/fabric/{object_origin.mixin.js → mixins/object_origin.mixin.js} +36 -26
- data/vendor/assets/javascripts/fabric/{object_straightening.mixin.js → mixins/object_straightening.mixin.js} +4 -9
- data/vendor/assets/javascripts/fabric/{observable.mixin.js → mixins/observable.mixin.js} +27 -35
- data/vendor/assets/javascripts/fabric/mixins/stateful.mixin.js +45 -0
- data/vendor/assets/javascripts/fabric/node.js +62 -26
- data/vendor/assets/javascripts/fabric/parser.js +181 -58
- data/vendor/assets/javascripts/fabric/pattern.class.js +43 -14
- data/vendor/assets/javascripts/fabric/point.class.js +4 -43
- data/vendor/assets/javascripts/fabric/shadow.class.js +19 -19
- data/vendor/assets/javascripts/fabric/{circle.class.js → shapes/circle.class.js} +32 -29
- data/vendor/assets/javascripts/fabric/{ellipse.class.js → shapes/ellipse.class.js} +45 -27
- data/vendor/assets/javascripts/fabric/{group.class.js → shapes/group.class.js} +67 -169
- data/vendor/assets/javascripts/fabric/{image.class.js → shapes/image.class.js} +134 -72
- data/vendor/assets/javascripts/fabric/{line.class.js → shapes/line.class.js} +67 -36
- data/vendor/assets/javascripts/fabric/{object.class.js → shapes/object.class.js} +394 -252
- data/vendor/assets/javascripts/fabric/{path.class.js → shapes/path.class.js} +89 -174
- data/vendor/assets/javascripts/fabric/{path_group.class.js → shapes/path_group.class.js} +12 -18
- data/vendor/assets/javascripts/fabric/{polygon.class.js → shapes/polygon.class.js} +64 -38
- data/vendor/assets/javascripts/fabric/{polyline.class.js → shapes/polyline.class.js} +64 -39
- data/vendor/assets/javascripts/fabric/{rect.class.js → shapes/rect.class.js} +78 -112
- data/vendor/assets/javascripts/fabric/{text.class.js → shapes/text.class.js} +264 -270
- data/vendor/assets/javascripts/fabric/shapes/text.cufon.js +79 -0
- data/vendor/assets/javascripts/fabric/{triangle.class.js → shapes/triangle.class.js} +46 -26
- data/vendor/assets/javascripts/fabric/static_canvas.class.js +134 -358
- data/vendor/assets/javascripts/fabric/util/anim_ease.js +2 -31
- data/vendor/assets/javascripts/fabric/util/dom_event.js +21 -7
- data/vendor/assets/javascripts/fabric/util/dom_misc.js +49 -39
- data/vendor/assets/javascripts/fabric/util/dom_request.js +1 -2
- data/vendor/assets/javascripts/fabric/util/dom_style.js +1 -2
- data/vendor/assets/javascripts/fabric/util/lang_array.js +19 -13
- data/vendor/assets/javascripts/fabric/util/lang_class.js +1 -2
- data/vendor/assets/javascripts/fabric/util/lang_function.js +3 -1
- data/vendor/assets/javascripts/fabric/util/lang_object.js +5 -5
- data/vendor/assets/javascripts/fabric/util/lang_string.js +7 -5
- data/vendor/assets/javascripts/fabric/util/misc.js +207 -42
- metadata +47 -29
- data/vendor/assets/javascripts/fabric/image_filters.js +0 -809
- data/vendor/assets/javascripts/fabric/scout.js +0 -45
- data/vendor/assets/javascripts/fabric/stateful.js +0 -88
data/vendor/assets/javascripts/fabric/{canvas_gestures.mixin.js → mixins/canvas_gestures.mixin.js}
RENAMED
@@ -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, /** @
|
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, /** @
|
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
|
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
|
-
* @
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
* @
|
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
|
+
};
|
data/vendor/assets/javascripts/fabric/{object_geometry.mixin.js → mixins/object_geometry.mixin.js}
RENAMED
@@ -2,16 +2,15 @@
|
|
2
2
|
|
3
3
|
var degreesToRadians = fabric.util.degreesToRadians;
|
4
4
|
|
5
|
-
fabric.util.object.extend(fabric.Object.prototype, /** @
|
5
|
+
fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {
|
6
6
|
|
7
7
|
/**
|
8
|
-
*
|
9
|
-
* @
|
10
|
-
* @param {Object}
|
11
|
-
* @
|
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(
|
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
|
-
|
24
|
-
|
22
|
+
pointTL,
|
23
|
+
pointBR
|
25
24
|
);
|
26
25
|
return intersection.status === 'Intersection';
|
27
26
|
},
|
28
27
|
|
29
28
|
/**
|
30
|
-
*
|
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
|
-
*
|
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
|
-
|
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
|
-
*
|
68
|
-
* @
|
69
|
-
* @param {Object}
|
70
|
-
* @
|
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(
|
74
|
-
var
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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:
|
282
|
-
y:
|
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
|
-
|
300
|
-
|
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
|
+
})();
|