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
@@ -6,298 +6,366 @@
|
|
6
6
|
extend = fabric.util.object.extend,
|
7
7
|
toFixed = fabric.util.toFixed,
|
8
8
|
capitalize = fabric.util.string.capitalize,
|
9
|
-
degreesToRadians = fabric.util.degreesToRadians
|
9
|
+
degreesToRadians = fabric.util.degreesToRadians,
|
10
|
+
supportsLineDash = fabric.StaticCanvas.supports('setLineDash');
|
10
11
|
|
11
12
|
if (fabric.Object) {
|
12
13
|
return;
|
13
14
|
}
|
14
15
|
|
15
|
-
var Image = global.Image;
|
16
|
-
try {
|
17
|
-
var NodeImage = (typeof require !== 'undefined') && require('canvas').Image;
|
18
|
-
if (NodeImage) {
|
19
|
-
Image = NodeImage;
|
20
|
-
}
|
21
|
-
}
|
22
|
-
catch(err) {
|
23
|
-
fabric.log(err);
|
24
|
-
}
|
25
|
-
|
26
16
|
/**
|
27
17
|
* Root object class from which all 2d shape classes inherit from
|
28
|
-
* @class Object
|
29
|
-
* @memberOf fabric
|
18
|
+
* @class fabric.Object
|
30
19
|
*/
|
31
|
-
fabric.Object = fabric.util.createClass(/** @
|
20
|
+
fabric.Object = fabric.util.createClass(/** @lends fabric.Object.prototype */ {
|
32
21
|
|
33
22
|
/**
|
34
23
|
* Type of an object (rect, circle, path, etc.)
|
35
|
-
* @property
|
36
24
|
* @type String
|
25
|
+
* @default
|
37
26
|
*/
|
38
27
|
type: 'object',
|
39
28
|
|
40
29
|
/**
|
41
30
|
* Horizontal origin of transformation of an object (one of "left", "right", "center")
|
42
|
-
* @property
|
43
31
|
* @type String
|
32
|
+
* @default
|
44
33
|
*/
|
45
34
|
originX: 'center',
|
46
35
|
|
47
36
|
/**
|
48
37
|
* Vertical origin of transformation of an object (one of "top", "bottom", "center")
|
49
|
-
* @property
|
50
38
|
* @type String
|
39
|
+
* @default
|
51
40
|
*/
|
52
41
|
originY: 'center',
|
53
42
|
|
54
43
|
/**
|
55
|
-
* Top position of an object
|
56
|
-
* @property
|
44
|
+
* Top position of an object. Note that by default it's relative to object center. You can change this by setting originY={top/center/bottom}
|
57
45
|
* @type Number
|
46
|
+
* @default
|
58
47
|
*/
|
59
48
|
top: 0,
|
60
49
|
|
61
50
|
/**
|
62
|
-
* Left position of an object
|
63
|
-
* @property
|
51
|
+
* Left position of an object. Note that by default it's relative to object center. You can change this by setting originX={left/center/right}
|
64
52
|
* @type Number
|
53
|
+
* @default
|
65
54
|
*/
|
66
55
|
left: 0,
|
67
56
|
|
68
57
|
/**
|
69
58
|
* Object width
|
70
|
-
* @property
|
71
59
|
* @type Number
|
60
|
+
* @default
|
72
61
|
*/
|
73
62
|
width: 0,
|
74
63
|
|
75
64
|
/**
|
76
65
|
* Object height
|
77
|
-
* @property
|
78
66
|
* @type Number
|
67
|
+
* @default
|
79
68
|
*/
|
80
69
|
height: 0,
|
81
70
|
|
82
71
|
/**
|
83
72
|
* Object scale factor (horizontal)
|
84
|
-
* @property
|
85
73
|
* @type Number
|
74
|
+
* @default
|
86
75
|
*/
|
87
76
|
scaleX: 1,
|
88
77
|
|
89
78
|
/**
|
90
79
|
* Object scale factor (vertical)
|
91
|
-
* @property
|
92
80
|
* @type Number
|
81
|
+
* @default
|
93
82
|
*/
|
94
83
|
scaleY: 1,
|
95
84
|
|
96
85
|
/**
|
97
86
|
* When true, an object is rendered as flipped horizontally
|
98
|
-
* @property
|
99
87
|
* @type Boolean
|
88
|
+
* @default
|
100
89
|
*/
|
101
90
|
flipX: false,
|
102
91
|
|
103
92
|
/**
|
104
93
|
* When true, an object is rendered as flipped vertically
|
105
|
-
* @property
|
106
94
|
* @type Boolean
|
95
|
+
* @default
|
107
96
|
*/
|
108
97
|
flipY: false,
|
109
98
|
|
110
99
|
/**
|
111
100
|
* Opacity of an object
|
112
|
-
* @property
|
113
101
|
* @type Number
|
102
|
+
* @default
|
114
103
|
*/
|
115
104
|
opacity: 1,
|
116
105
|
|
117
106
|
/**
|
118
107
|
* Angle of rotation of an object (in degrees)
|
119
|
-
* @property
|
120
108
|
* @type Number
|
109
|
+
* @default
|
121
110
|
*/
|
122
111
|
angle: 0,
|
123
112
|
|
124
113
|
/**
|
125
|
-
* Size of object's corners (in pixels)
|
126
|
-
* @property
|
114
|
+
* Size of object's controlling corners (in pixels)
|
127
115
|
* @type Number
|
116
|
+
* @default
|
128
117
|
*/
|
129
118
|
cornerSize: 12,
|
130
119
|
|
131
120
|
/**
|
132
|
-
* When true, object's corners are rendered as transparent inside (i.e. stroke instead of fill)
|
133
|
-
* @property
|
121
|
+
* When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill)
|
134
122
|
* @type Boolean
|
123
|
+
* @default
|
135
124
|
*/
|
136
125
|
transparentCorners: true,
|
137
126
|
|
138
127
|
/**
|
139
|
-
* Padding between object and its borders (in pixels)
|
140
|
-
* @property
|
128
|
+
* Padding between object and its controlling borders (in pixels)
|
141
129
|
* @type Number
|
130
|
+
* @default
|
142
131
|
*/
|
143
132
|
padding: 0,
|
144
133
|
|
145
134
|
/**
|
146
|
-
*
|
147
|
-
* @property
|
135
|
+
* Color of controlling borders of an object (when it's active)
|
148
136
|
* @type String
|
137
|
+
* @default
|
149
138
|
*/
|
150
139
|
borderColor: 'rgba(102,153,255,0.75)',
|
151
140
|
|
152
141
|
/**
|
153
|
-
*
|
154
|
-
* @property
|
142
|
+
* Color of controlling corners of an object (when it's active)
|
155
143
|
* @type String
|
144
|
+
* @default
|
156
145
|
*/
|
157
146
|
cornerColor: 'rgba(102,153,255,0.5)',
|
158
147
|
|
148
|
+
/**
|
149
|
+
* When true, this object will use center point as the origin of transformation
|
150
|
+
* when being resized via the controls
|
151
|
+
* @type Boolean
|
152
|
+
*/
|
153
|
+
centerTransform: false,
|
154
|
+
|
159
155
|
/**
|
160
156
|
* Color of object's fill
|
161
|
-
* @property
|
162
157
|
* @type String
|
158
|
+
* @default
|
163
159
|
*/
|
164
160
|
fill: 'rgb(0,0,0)',
|
165
161
|
|
166
162
|
/**
|
167
163
|
* Fill rule used to fill an object
|
168
|
-
* @property
|
169
164
|
* @type String
|
165
|
+
* @default
|
170
166
|
*/
|
171
167
|
fillRule: 'source-over',
|
172
168
|
|
173
169
|
/**
|
174
170
|
* Overlay fill (takes precedence over fill value)
|
175
|
-
* @property
|
176
171
|
* @type String
|
172
|
+
* @default
|
177
173
|
*/
|
178
174
|
overlayFill: null,
|
179
175
|
|
180
176
|
/**
|
181
|
-
* When
|
182
|
-
* @property
|
177
|
+
* When defined, an object is rendered via stroke and this property specifies its color
|
183
178
|
* @type String
|
179
|
+
* @default
|
184
180
|
*/
|
185
181
|
stroke: null,
|
186
182
|
|
187
183
|
/**
|
188
184
|
* Width of a stroke used to render this object
|
189
|
-
* @property
|
190
185
|
* @type Number
|
186
|
+
* @default
|
191
187
|
*/
|
192
188
|
strokeWidth: 1,
|
193
189
|
|
194
190
|
/**
|
195
|
-
* Array specifying dash pattern of an object's stroke
|
196
|
-
* @property
|
191
|
+
* Array specifying dash pattern of an object's stroke (stroke must be defined)
|
197
192
|
* @type Array
|
198
193
|
*/
|
199
194
|
strokeDashArray: null,
|
200
195
|
|
196
|
+
/**
|
197
|
+
* Line endings style of an object's stroke (one of "butt", "round", "square")
|
198
|
+
* @type String
|
199
|
+
* @default
|
200
|
+
*/
|
201
|
+
strokeLineCap: 'butt',
|
202
|
+
|
203
|
+
/**
|
204
|
+
* Corner style of an object's stroke (one of "bevil", "round", "miter")
|
205
|
+
* @type String
|
206
|
+
* @default
|
207
|
+
*/
|
208
|
+
strokeLineJoin: 'miter',
|
209
|
+
|
210
|
+
/**
|
211
|
+
* Maximum miter length (used for strokeLineJoin = "miter") of an object's stroke
|
212
|
+
* @type Number
|
213
|
+
* @default
|
214
|
+
*/
|
215
|
+
strokeMiterLimit: 10,
|
216
|
+
|
201
217
|
/**
|
202
218
|
* Shadow object representing shadow of this shape
|
203
|
-
* @property
|
204
219
|
* @type fabric.Shadow
|
205
220
|
*/
|
206
221
|
shadow: null,
|
207
222
|
|
208
223
|
/**
|
209
|
-
*
|
210
|
-
* @property
|
224
|
+
* Opacity of object's controlling borders when object is active and moving
|
211
225
|
* @type Number
|
226
|
+
* @default
|
212
227
|
*/
|
213
228
|
borderOpacityWhenMoving: 0.4,
|
214
229
|
|
215
230
|
/**
|
216
|
-
*
|
217
|
-
* @property
|
231
|
+
* Scale factor of object's controlling borders
|
218
232
|
* @type Number
|
233
|
+
* @default
|
219
234
|
*/
|
220
235
|
borderScaleFactor: 1,
|
221
236
|
|
222
237
|
/**
|
223
238
|
* Transform matrix (similar to SVG's transform matrix)
|
224
|
-
* @property
|
225
239
|
* @type Array
|
226
240
|
*/
|
227
241
|
transformMatrix: null,
|
228
242
|
|
229
243
|
/**
|
230
244
|
* Minimum allowed scale value of an object
|
231
|
-
* @property
|
232
245
|
* @type Number
|
246
|
+
* @default
|
233
247
|
*/
|
234
248
|
minScaleLimit: 0.01,
|
235
249
|
|
236
250
|
/**
|
237
251
|
* When set to `false`, an object can not be selected for modification (using either point-click-based or group-based selection)
|
238
|
-
* @property
|
239
252
|
* @type Boolean
|
253
|
+
* @default
|
240
254
|
*/
|
241
255
|
selectable: true,
|
242
256
|
|
257
|
+
/**
|
258
|
+
* When set to `false`, an object is not rendered on canvas
|
259
|
+
* @type Boolean
|
260
|
+
* @default
|
261
|
+
*/
|
262
|
+
visible: true,
|
263
|
+
|
243
264
|
/**
|
244
265
|
* When set to `false`, object's controls are not displayed and can not be used to manipulate object
|
245
|
-
* @property
|
246
266
|
* @type Boolean
|
267
|
+
* @default
|
247
268
|
*/
|
248
269
|
hasControls: true,
|
249
270
|
|
250
271
|
/**
|
251
|
-
* When set to `false`, object's borders are not rendered
|
252
|
-
* @property
|
272
|
+
* When set to `false`, object's controlling borders are not rendered
|
253
273
|
* @type Boolean
|
274
|
+
* @default
|
254
275
|
*/
|
255
276
|
hasBorders: true,
|
256
277
|
|
257
278
|
/**
|
258
|
-
* When set to `false`, object's rotating point will not be visible or selectable
|
259
|
-
* @property
|
279
|
+
* When set to `false`, object's controlling rotating point will not be visible or selectable
|
260
280
|
* @type Boolean
|
281
|
+
* @default
|
261
282
|
*/
|
262
283
|
hasRotatingPoint: true,
|
263
284
|
|
264
285
|
/**
|
265
|
-
* Offset for object's rotating point (when enabled via `hasRotatingPoint`)
|
266
|
-
* @property
|
286
|
+
* Offset for object's controlling rotating point (when enabled via `hasRotatingPoint`)
|
267
287
|
* @type Number
|
288
|
+
* @default
|
268
289
|
*/
|
269
290
|
rotatingPointOffset: 40,
|
270
291
|
|
271
292
|
/**
|
272
293
|
* When set to `true`, objects are "found" on canvas on per-pixel basis rather than according to bounding box
|
273
|
-
* @property
|
274
294
|
* @type Boolean
|
295
|
+
* @default
|
275
296
|
*/
|
276
297
|
perPixelTargetFind: false,
|
277
298
|
|
278
299
|
/**
|
279
300
|
* When `false`, default object's values are not included in its serialization
|
280
|
-
* @property
|
281
301
|
* @type Boolean
|
302
|
+
* @default
|
282
303
|
*/
|
283
304
|
includeDefaultValues: true,
|
284
305
|
|
285
306
|
/**
|
286
|
-
*
|
307
|
+
* Function that determines clipping of an object (context is passed as a first argument)
|
308
|
+
* @type Function
|
309
|
+
*/
|
310
|
+
clipTo: null,
|
311
|
+
|
312
|
+
/**
|
313
|
+
* When `true`, object horizontal movement is locked
|
314
|
+
* @type Boolean
|
315
|
+
* @default
|
316
|
+
*/
|
317
|
+
lockMovementX: false,
|
318
|
+
|
319
|
+
/**
|
320
|
+
* When `true`, object vertical movement is locked
|
321
|
+
* @type Boolean
|
322
|
+
* @default
|
323
|
+
*/
|
324
|
+
lockMovementY: false,
|
325
|
+
|
326
|
+
/**
|
327
|
+
* When `true`, object rotation is locked
|
328
|
+
* @type Boolean
|
329
|
+
* @default
|
330
|
+
*/
|
331
|
+
lockRotation: false,
|
332
|
+
|
333
|
+
/**
|
334
|
+
* When `true`, object horizontal scaling is locked
|
335
|
+
* @type Boolean
|
336
|
+
* @default
|
337
|
+
*/
|
338
|
+
lockScalingX: false,
|
339
|
+
|
340
|
+
/**
|
341
|
+
* When `true`, object vertical scaling is locked
|
342
|
+
* @type Boolean
|
343
|
+
* @default
|
344
|
+
*/
|
345
|
+
lockScalingY: false,
|
346
|
+
|
347
|
+
/**
|
348
|
+
* When `true`, object non-uniform scaling is locked
|
349
|
+
* @type Boolean
|
350
|
+
* @default
|
351
|
+
*/
|
352
|
+
lockUniScaling: false,
|
353
|
+
|
354
|
+
/**
|
355
|
+
* List of properties to consider when checking if state
|
356
|
+
* of an object is changed (fabric.Object#hasStateChanged)
|
287
357
|
* as well as for history (undo/redo) purposes
|
288
|
-
* @property
|
289
358
|
* @type Array
|
290
359
|
*/
|
291
360
|
stateProperties: (
|
292
361
|
'top left width height scaleX scaleY flipX flipY ' +
|
293
362
|
'angle opacity cornerSize fill overlayFill originX originY ' +
|
294
363
|
'stroke strokeWidth strokeDashArray fillRule ' +
|
295
|
-
'borderScaleFactor transformMatrix selectable shadow'
|
364
|
+
'borderScaleFactor transformMatrix selectable shadow visible'
|
296
365
|
).split(' '),
|
297
366
|
|
298
367
|
/**
|
299
368
|
* Constructor
|
300
|
-
* @method initialize
|
301
369
|
* @param {Object} [options] Options object
|
302
370
|
*/
|
303
371
|
initialize: function(options) {
|
@@ -308,7 +376,6 @@
|
|
308
376
|
|
309
377
|
/**
|
310
378
|
* @private
|
311
|
-
* @method _initGradient
|
312
379
|
*/
|
313
380
|
_initGradient: function(options) {
|
314
381
|
if (options.fill && options.fill.colorStops && !(options.fill instanceof fabric.Gradient)) {
|
@@ -318,7 +385,6 @@
|
|
318
385
|
|
319
386
|
/**
|
320
387
|
* @private
|
321
|
-
* @method _initPattern
|
322
388
|
*/
|
323
389
|
_initPattern: function(options) {
|
324
390
|
if (options.fill && options.fill.source && !(options.fill instanceof fabric.Pattern)) {
|
@@ -331,7 +397,6 @@
|
|
331
397
|
|
332
398
|
/**
|
333
399
|
* @private
|
334
|
-
* @method _initShadow
|
335
400
|
*/
|
336
401
|
_initShadow: function(options) {
|
337
402
|
if (options.shadow && !(options.shadow instanceof fabric.Shadow)) {
|
@@ -339,9 +404,20 @@
|
|
339
404
|
}
|
340
405
|
},
|
341
406
|
|
407
|
+
/**
|
408
|
+
* @private
|
409
|
+
*/
|
410
|
+
_initClipping: function(options) {
|
411
|
+
if (!options.clipTo || typeof options.clipTo !== 'string') return;
|
412
|
+
|
413
|
+
var functionBody = fabric.util.getFunctionBody(options.clipTo);
|
414
|
+
if (typeof functionBody !== 'undefined') {
|
415
|
+
this.clipTo = new Function('ctx', functionBody);
|
416
|
+
}
|
417
|
+
},
|
418
|
+
|
342
419
|
/**
|
343
420
|
* Sets object's properties from options
|
344
|
-
* @method setOptions
|
345
421
|
* @param {Object} [options]
|
346
422
|
*/
|
347
423
|
setOptions: function(options) {
|
@@ -351,17 +427,18 @@
|
|
351
427
|
this._initGradient(options);
|
352
428
|
this._initPattern(options);
|
353
429
|
this._initShadow(options);
|
430
|
+
this._initClipping(options);
|
354
431
|
},
|
355
432
|
|
356
433
|
/**
|
357
434
|
* Transforms context when rendering an object
|
358
|
-
* @method transform
|
359
435
|
* @param {CanvasRenderingContext2D} ctx Context
|
436
|
+
* @param {Boolean} fromLeft When true, context is transformed to object's top/left corner. This is used when rendering text on Node
|
360
437
|
*/
|
361
|
-
transform: function(ctx) {
|
438
|
+
transform: function(ctx, fromLeft) {
|
362
439
|
ctx.globalAlpha = this.opacity;
|
363
440
|
|
364
|
-
var center = this.getCenterPoint();
|
441
|
+
var center = fromLeft ? this._getLeftTopCoords() : this.getCenterPoint();
|
365
442
|
ctx.translate(center.x, center.y);
|
366
443
|
ctx.rotate(degreesToRadians(this.angle));
|
367
444
|
ctx.scale(
|
@@ -372,9 +449,8 @@
|
|
372
449
|
|
373
450
|
/**
|
374
451
|
* Returns an object representation of an instance
|
375
|
-
* @
|
376
|
-
* @
|
377
|
-
* @return {Object} object representation of an instance
|
452
|
+
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
|
453
|
+
* @return {Object} Object representation of an instance
|
378
454
|
*/
|
379
455
|
toObject: function(propertiesToInclude) {
|
380
456
|
|
@@ -391,8 +467,11 @@
|
|
391
467
|
fill: (this.fill && this.fill.toObject) ? this.fill.toObject() : this.fill,
|
392
468
|
overlayFill: this.overlayFill,
|
393
469
|
stroke: (this.stroke && this.stroke.toObject) ? this.stroke.toObject() : this.stroke,
|
394
|
-
strokeWidth: this.strokeWidth,
|
470
|
+
strokeWidth: toFixed(this.strokeWidth, NUM_FRACTION_DIGITS),
|
395
471
|
strokeDashArray: this.strokeDashArray,
|
472
|
+
strokeLineCap: this.strokeLineCap,
|
473
|
+
strokeLineJoin: this.strokeLineJoin,
|
474
|
+
strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS),
|
396
475
|
scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS),
|
397
476
|
scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS),
|
398
477
|
angle: toFixed(this.getAngle(), NUM_FRACTION_DIGITS),
|
@@ -405,7 +484,9 @@
|
|
405
484
|
hasRotatingPoint: this.hasRotatingPoint,
|
406
485
|
transparentCorners: this.transparentCorners,
|
407
486
|
perPixelTargetFind: this.perPixelTargetFind,
|
408
|
-
shadow: (this.shadow && this.shadow.toObject) ? this.shadow.toObject() : this.shadow
|
487
|
+
shadow: (this.shadow && this.shadow.toObject) ? this.shadow.toObject() : this.shadow,
|
488
|
+
visible: this.visible,
|
489
|
+
clipTo: this.clipTo && String(this.clipTo)
|
409
490
|
};
|
410
491
|
|
411
492
|
if (!this.includeDefaultValues) {
|
@@ -418,33 +499,35 @@
|
|
418
499
|
|
419
500
|
/**
|
420
501
|
* Returns (dataless) object representation of an instance
|
421
|
-
* @
|
422
|
-
* @
|
423
|
-
* @return {Object} object representation of an instance
|
502
|
+
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
|
503
|
+
* @return {Object} Object representation of an instance
|
424
504
|
*/
|
425
505
|
toDatalessObject: function(propertiesToInclude) {
|
426
506
|
// will be overwritten by subclasses
|
427
507
|
return this.toObject(propertiesToInclude);
|
428
508
|
},
|
429
509
|
|
510
|
+
/* _TO_SVG_START_ */
|
430
511
|
/**
|
431
512
|
* Returns styles-string for svg-export
|
432
|
-
* @method getSvgStyles
|
433
513
|
* @return {String}
|
434
514
|
*/
|
435
515
|
getSvgStyles: function() {
|
436
516
|
return [
|
437
517
|
"stroke: ", (this.stroke ? this.stroke : 'none'), "; ",
|
438
518
|
"stroke-width: ", (this.strokeWidth ? this.strokeWidth : '0'), "; ",
|
439
|
-
"stroke-dasharray: ", (this.strokeDashArray ? this.strokeDashArray.join(' ') : "; "
|
440
|
-
"
|
441
|
-
"
|
519
|
+
"stroke-dasharray: ", (this.strokeDashArray ? this.strokeDashArray.join(' ') : ''), "; ",
|
520
|
+
"stroke-linecap: ", (this.strokeLineCap ? this.strokeLineCap : 'butt'), "; ",
|
521
|
+
"stroke-linejoin: ", (this.strokeLineJoin ? this.strokeLineJoin : 'miter'), "; ",
|
522
|
+
"stroke-miterlimit: ", (this.strokeMiterLimit ? this.strokeMiterLimit : '4'), "; ",
|
523
|
+
"fill: ", (this.fill ? (this.fill && this.fill.toLive ? 'url(#SVGID_' + this.fill.id + ')' : this.fill) : 'none'), "; ",
|
524
|
+
"opacity: ", (typeof this.opacity !== 'undefined' ? this.opacity : '1'), ";",
|
525
|
+
(this.visible ? '' : " visibility: hidden;")
|
442
526
|
].join("");
|
443
527
|
},
|
444
528
|
|
445
529
|
/**
|
446
530
|
* Returns transform-string for svg-export
|
447
|
-
* @method getSvgTransform
|
448
531
|
* @return {String}
|
449
532
|
*/
|
450
533
|
getSvgTransform: function() {
|
@@ -476,10 +559,11 @@
|
|
476
559
|
|
477
560
|
return [ translatePart, anglePart, scalePart, flipXPart, flipYPart ].join('');
|
478
561
|
},
|
562
|
+
/* _TO_SVG_END_ */
|
479
563
|
|
480
564
|
/**
|
481
565
|
* @private
|
482
|
-
* @
|
566
|
+
* @param {Object} object
|
483
567
|
*/
|
484
568
|
_removeDefaultValues: function(object) {
|
485
569
|
var defaultOptions = fabric.Object.prototype.options;
|
@@ -493,25 +577,6 @@
|
|
493
577
|
return object;
|
494
578
|
},
|
495
579
|
|
496
|
-
/**
|
497
|
-
* Returns true if an object is in its active state
|
498
|
-
* @return {Boolean} true if an object is in its active state
|
499
|
-
*/
|
500
|
-
isActive: function() {
|
501
|
-
return !!this.active;
|
502
|
-
},
|
503
|
-
|
504
|
-
/**
|
505
|
-
* Sets state of an object - `true` makes it active, `false` - inactive
|
506
|
-
* @param {Boolean} active
|
507
|
-
* @return {fabric.Object} thisArg
|
508
|
-
* @chainable
|
509
|
-
*/
|
510
|
-
setActive: function(active) {
|
511
|
-
this.active = !!active;
|
512
|
-
return this;
|
513
|
-
},
|
514
|
-
|
515
580
|
/**
|
516
581
|
* Returns a string representation of an instance
|
517
582
|
* @return {String}
|
@@ -522,7 +587,6 @@
|
|
522
587
|
|
523
588
|
/**
|
524
589
|
* Basic getter
|
525
|
-
* @method get
|
526
590
|
* @param {String} property
|
527
591
|
* @return {Any} value of a property
|
528
592
|
*/
|
@@ -531,11 +595,10 @@
|
|
531
595
|
},
|
532
596
|
|
533
597
|
/**
|
534
|
-
* Sets property to a given value
|
535
|
-
* @
|
536
|
-
* @param {
|
537
|
-
* @
|
538
|
-
* @return {fabric.Group} thisArg
|
598
|
+
* Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.
|
599
|
+
* @param {String|Object} key (if object, iterate over the object properties)
|
600
|
+
* @param {Object|Function} value (if function, the value is passed into it and its return value is used as a new one)
|
601
|
+
* @return {fabric.Object} thisArg
|
539
602
|
* @chainable
|
540
603
|
*/
|
541
604
|
set: function(key, value) {
|
@@ -545,7 +608,7 @@
|
|
545
608
|
}
|
546
609
|
}
|
547
610
|
else {
|
548
|
-
if (typeof value === 'function') {
|
611
|
+
if (typeof value === 'function' && key !== 'clipTo') {
|
549
612
|
this._set(key, value(this.get(key)));
|
550
613
|
}
|
551
614
|
else {
|
@@ -557,9 +620,9 @@
|
|
557
620
|
|
558
621
|
/**
|
559
622
|
* @private
|
560
|
-
* @
|
561
|
-
* @param
|
562
|
-
* @
|
623
|
+
* @param {String} key
|
624
|
+
* @param {Any} value
|
625
|
+
* @return {fabric.Object} thisArg
|
563
626
|
*/
|
564
627
|
_set: function(key, value) {
|
565
628
|
var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY');
|
@@ -586,7 +649,6 @@
|
|
586
649
|
|
587
650
|
/**
|
588
651
|
* Toggles specified property from `true` to `false` or from `false` to `true`
|
589
|
-
* @method toggle
|
590
652
|
* @param {String} property property to toggle
|
591
653
|
* @return {fabric.Object} thisArg
|
592
654
|
* @chainable
|
@@ -601,7 +663,6 @@
|
|
601
663
|
|
602
664
|
/**
|
603
665
|
* Sets sourcePath of an object
|
604
|
-
* @method setSourcePath
|
605
666
|
* @param {String} value
|
606
667
|
* @return {fabric.Object} thisArg
|
607
668
|
* @chainable
|
@@ -613,14 +674,12 @@
|
|
613
674
|
|
614
675
|
/**
|
615
676
|
* Renders an object on a specified context
|
616
|
-
* @method render
|
617
677
|
* @param {CanvasRenderingContext2D} ctx context to render on
|
618
|
-
* @param {Boolean} noTransform
|
678
|
+
* @param {Boolean} [noTransform] When true, context is not transformed
|
619
679
|
*/
|
620
680
|
render: function(ctx, noTransform) {
|
621
|
-
|
622
|
-
|
623
|
-
if (this.width === 0 || this.height === 0) return;
|
681
|
+
// do not render if width/height are zeros or object is not visible
|
682
|
+
if (this.width === 0 || this.height === 0 || !this.visible) return;
|
624
683
|
|
625
684
|
ctx.save();
|
626
685
|
|
@@ -633,14 +692,14 @@
|
|
633
692
|
this.transform(ctx);
|
634
693
|
}
|
635
694
|
|
636
|
-
if (this.stroke
|
695
|
+
if (this.stroke) {
|
637
696
|
ctx.lineWidth = this.strokeWidth;
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
697
|
+
ctx.lineCap = this.strokeLineCap;
|
698
|
+
ctx.lineJoin = this.strokeLineJoin;
|
699
|
+
ctx.miterLimit = this.strokeMiterLimit;
|
700
|
+
ctx.strokeStyle = this.stroke.toLive
|
701
|
+
? this.stroke.toLive(ctx)
|
702
|
+
: this.stroke;
|
644
703
|
}
|
645
704
|
|
646
705
|
if (this.overlayFill) {
|
@@ -658,7 +717,9 @@
|
|
658
717
|
}
|
659
718
|
|
660
719
|
this._setShadow(ctx);
|
720
|
+
this.clipTo && fabric.util.clipContext(this, ctx);
|
661
721
|
this._render(ctx, noTransform);
|
722
|
+
this.clipTo && ctx.restore();
|
662
723
|
this._removeShadow(ctx);
|
663
724
|
|
664
725
|
if (this.active && !noTransform) {
|
@@ -670,7 +731,7 @@
|
|
670
731
|
|
671
732
|
/**
|
672
733
|
* @private
|
673
|
-
* @
|
734
|
+
* @param {CanvasRenderingContext2D} ctx Context to render on
|
674
735
|
*/
|
675
736
|
_setShadow: function(ctx) {
|
676
737
|
if (!this.shadow) return;
|
@@ -683,18 +744,69 @@
|
|
683
744
|
|
684
745
|
/**
|
685
746
|
* @private
|
686
|
-
* @
|
747
|
+
* @param {CanvasRenderingContext2D} ctx Context to render on
|
687
748
|
*/
|
688
749
|
_removeShadow: function(ctx) {
|
689
750
|
ctx.shadowColor = '';
|
690
751
|
ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;
|
691
752
|
},
|
692
753
|
|
754
|
+
/**
|
755
|
+
* @private
|
756
|
+
* @param {CanvasRenderingContext2D} ctx Context to render on
|
757
|
+
*/
|
758
|
+
_renderFill: function(ctx) {
|
759
|
+
if (!this.fill) return;
|
760
|
+
|
761
|
+
if (this.fill.toLive) {
|
762
|
+
ctx.save();
|
763
|
+
ctx.translate(
|
764
|
+
-this.width / 2 + this.fill.offsetX || 0,
|
765
|
+
-this.height / 2 + this.fill.offsetY || 0);
|
766
|
+
}
|
767
|
+
ctx.fill();
|
768
|
+
if (this.fill.toLive) {
|
769
|
+
ctx.restore();
|
770
|
+
}
|
771
|
+
if (this.shadow && !this.shadow.affectStroke) {
|
772
|
+
this._removeShadow(ctx);
|
773
|
+
}
|
774
|
+
},
|
775
|
+
|
776
|
+
/**
|
777
|
+
* @private
|
778
|
+
* @param {CanvasRenderingContext2D} ctx Context to render on
|
779
|
+
*/
|
780
|
+
_renderStroke: function(ctx) {
|
781
|
+
if (!this.stroke) return;
|
782
|
+
|
783
|
+
ctx.save();
|
784
|
+
if (this.strokeDashArray) {
|
785
|
+
// Spec requires the concatenation of two copies the dash list when the number of elements is odd
|
786
|
+
if (1 & this.strokeDashArray.length) {
|
787
|
+
this.strokeDashArray.push.apply(this.strokeDashArray, this.strokeDashArray);
|
788
|
+
}
|
789
|
+
|
790
|
+
if (supportsLineDash) {
|
791
|
+
ctx.setLineDash(this.strokeDashArray);
|
792
|
+
this._stroke && this._stroke(ctx);
|
793
|
+
}
|
794
|
+
else {
|
795
|
+
this._renderDashedStroke && this._renderDashedStroke(ctx);
|
796
|
+
}
|
797
|
+
ctx.stroke();
|
798
|
+
}
|
799
|
+
else {
|
800
|
+
this._stroke ? this._stroke(ctx) : ctx.stroke();
|
801
|
+
}
|
802
|
+
this._removeShadow(ctx);
|
803
|
+
ctx.restore();
|
804
|
+
},
|
805
|
+
|
693
806
|
/**
|
694
807
|
* Clones an instance
|
695
|
-
* @method clone
|
696
808
|
* @param {Function} callback Callback is invoked with a clone as a first argument
|
697
|
-
* @param {Array} propertiesToInclude
|
809
|
+
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the outpu
|
698
810
|
* @return {fabric.Object} clone of an instance
|
699
811
|
*/
|
700
812
|
clone: function(callback, propertiesToInclude) {
|
@@ -706,114 +818,68 @@
|
|
706
818
|
|
707
819
|
/**
|
708
820
|
* Creates an instance of fabric.Image out of an object
|
709
|
-
* @method cloneAsImage
|
710
821
|
* @param callback {Function} callback, invoked with an instance as a first argument
|
711
822
|
* @return {fabric.Object} thisArg
|
712
|
-
* @chainable
|
713
823
|
*/
|
714
824
|
cloneAsImage: function(callback) {
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
callback(new fabric.Image(i), orig);
|
722
|
-
}
|
723
|
-
i = i.onload = null;
|
724
|
-
};
|
725
|
-
|
726
|
-
var orig = {
|
727
|
-
angle: this.get('angle'),
|
728
|
-
flipX: this.get('flipX'),
|
729
|
-
flipY: this.get('flipY')
|
730
|
-
};
|
731
|
-
|
732
|
-
// normalize angle
|
733
|
-
this.set('angle', 0).set('flipX', false).set('flipY', false);
|
734
|
-
this.toDataURL(function(dataURL) {
|
735
|
-
i.src = dataURL;
|
736
|
-
});
|
737
|
-
}
|
825
|
+
var dataUrl = this.toDataURL();
|
826
|
+
fabric.util.loadImage(dataUrl, function(img) {
|
827
|
+
if (callback) {
|
828
|
+
callback(new fabric.Image(img));
|
829
|
+
}
|
830
|
+
});
|
738
831
|
return this;
|
739
832
|
},
|
740
833
|
|
741
834
|
/**
|
742
835
|
* Converts an object into a data-url-like string
|
743
|
-
* @
|
744
|
-
*
|
836
|
+
* @param {Object} options Options object
|
837
|
+
*
|
838
|
+
* `format` the format of the output image. Either "jpeg" or "png".
|
839
|
+
* `quality` quality level (0..1)
|
840
|
+
* `multiplier` multiplier to scale by {Number}
|
841
|
+
*
|
842
|
+
* @return {String} data url representing an image of this object
|
745
843
|
*/
|
746
|
-
toDataURL: function(
|
747
|
-
|
844
|
+
toDataURL: function(options) {
|
845
|
+
options || (options = { });
|
748
846
|
|
847
|
+
var el = fabric.util.createCanvasElement();
|
749
848
|
el.width = this.getBoundingRectWidth();
|
750
849
|
el.height = this.getBoundingRectHeight();
|
751
850
|
|
752
851
|
fabric.util.wrapElement(el, 'div');
|
753
852
|
|
754
853
|
var canvas = new fabric.Canvas(el);
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
if (this.constructor.async) {
|
759
|
-
this.clone(proceed);
|
854
|
+
if (options.format === 'jpeg') {
|
855
|
+
canvas.backgroundColor = '#fff';
|
760
856
|
}
|
761
|
-
else {
|
762
|
-
proceed(this.clone());
|
763
|
-
}
|
764
|
-
|
765
|
-
function proceed(clone) {
|
766
|
-
clone.left = el.width / 2;
|
767
|
-
clone.top = el.height / 2;
|
768
857
|
|
769
|
-
|
858
|
+
var origParams = {
|
859
|
+
active: this.get('active'),
|
860
|
+
left: this.getLeft(),
|
861
|
+
top: this.getTop()
|
862
|
+
};
|
770
863
|
|
771
|
-
|
772
|
-
|
864
|
+
this.set({
|
865
|
+
'active': false,
|
866
|
+
left: el.width / 2,
|
867
|
+
top: el.height / 2
|
868
|
+
});
|
773
869
|
|
774
|
-
|
775
|
-
|
870
|
+
canvas.add(this);
|
871
|
+
var data = canvas.toDataURL(options);
|
776
872
|
|
777
|
-
|
778
|
-
}
|
779
|
-
},
|
780
|
-
|
781
|
-
/**
|
782
|
-
* Returns true if object state (one of its state properties) was changed
|
783
|
-
* @method hasStateChanged
|
784
|
-
* @return {Boolean} true if instance' state has changed
|
785
|
-
*/
|
786
|
-
hasStateChanged: function() {
|
787
|
-
return this.stateProperties.some(function(prop) {
|
788
|
-
return this[prop] !== this.originalState[prop];
|
789
|
-
}, this);
|
790
|
-
},
|
873
|
+
this.set(origParams).setCoords();
|
791
874
|
|
792
|
-
|
793
|
-
|
794
|
-
* @method saveState
|
795
|
-
* @return {fabric.Object} thisArg
|
796
|
-
* @chainable
|
797
|
-
*/
|
798
|
-
saveState: function() {
|
799
|
-
this.stateProperties.forEach(function(prop) {
|
800
|
-
this.originalState[prop] = this.get(prop);
|
801
|
-
}, this);
|
802
|
-
return this;
|
803
|
-
},
|
875
|
+
canvas.dispose();
|
876
|
+
canvas = null;
|
804
877
|
|
805
|
-
|
806
|
-
* Setups state of an object
|
807
|
-
* @method setupState
|
808
|
-
*/
|
809
|
-
setupState: function() {
|
810
|
-
this.originalState = { };
|
811
|
-
this.saveState();
|
878
|
+
return data;
|
812
879
|
},
|
813
880
|
|
814
881
|
/**
|
815
882
|
* Returns true if specified type is identical to the type of an instance
|
816
|
-
* @method isType
|
817
883
|
* @param type {String} type to check against
|
818
884
|
* @return {Boolean}
|
819
885
|
*/
|
@@ -823,7 +889,6 @@
|
|
823
889
|
|
824
890
|
/**
|
825
891
|
* Makes object's color grayscale
|
826
|
-
* @method toGrayscale
|
827
892
|
* @return {fabric.Object} thisArg
|
828
893
|
*/
|
829
894
|
toGrayscale: function() {
|
@@ -836,8 +901,7 @@
|
|
836
901
|
|
837
902
|
/**
|
838
903
|
* Returns complexity of an instance
|
839
|
-
* @
|
840
|
-
* @return {Number} complexity
|
904
|
+
* @return {Number} complexity of this instance
|
841
905
|
*/
|
842
906
|
complexity: function() {
|
843
907
|
return 0;
|
@@ -845,9 +909,8 @@
|
|
845
909
|
|
846
910
|
/**
|
847
911
|
* Returns a JSON representation of an instance
|
848
|
-
* @
|
849
|
-
* @
|
850
|
-
* @return {String} json
|
912
|
+
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
|
913
|
+
* @return {Object} JSON
|
851
914
|
*/
|
852
915
|
toJSON: function(propertiesToInclude) {
|
853
916
|
// delegate, not alias
|
@@ -855,32 +918,62 @@
|
|
855
918
|
},
|
856
919
|
|
857
920
|
/**
|
858
|
-
* Sets gradient fill of an object
|
859
|
-
* @
|
921
|
+
* Sets gradient (fill or stroke) of an object
|
922
|
+
* @param {String} property Property name 'stroke' or 'fill'
|
923
|
+
* @param {Object} [options] Options object
|
860
924
|
*/
|
861
|
-
|
862
|
-
|
925
|
+
setGradient: function(property, options) {
|
926
|
+
options || (options = { });
|
927
|
+
|
928
|
+
var gradient = {colorStops: []};
|
929
|
+
|
930
|
+
gradient.type = options.type || (options.r1 || options.r2 ? 'radial' : 'linear');
|
931
|
+
gradient.coords = {
|
932
|
+
x1: options.x1,
|
933
|
+
y1: options.y1,
|
934
|
+
x2: options.x2,
|
935
|
+
y2: options.y2
|
936
|
+
};
|
937
|
+
|
938
|
+
if (options.r1 || options.r2) {
|
939
|
+
gradient.coords.r1 = options.r1;
|
940
|
+
gradient.coords.r2 = options.r2;
|
941
|
+
}
|
942
|
+
|
943
|
+
for (var position in options.colorStops) {
|
944
|
+
var color = new fabric.Color(options.colorStops[position]);
|
945
|
+
gradient.colorStops.push({offset: position, color: color.toRgb(), opacity: color.getAlpha()});
|
946
|
+
}
|
947
|
+
|
948
|
+
this.set(property, fabric.Gradient.forObject(this, gradient));
|
863
949
|
},
|
864
950
|
|
865
951
|
/**
|
866
952
|
* Sets pattern fill of an object
|
867
|
-
* @
|
953
|
+
* @param {Object} [options] Options object
|
954
|
+
* @return {fabric.Object} thisArg
|
955
|
+
* @chainable
|
868
956
|
*/
|
869
957
|
setPatternFill: function(options) {
|
870
|
-
this.set('fill', new fabric.Pattern(options));
|
958
|
+
return this.set('fill', new fabric.Pattern(options));
|
871
959
|
},
|
872
960
|
|
873
961
|
/**
|
874
962
|
* Sets shadow of an object
|
875
|
-
* @
|
963
|
+
* @param {Object} [options] Options object
|
964
|
+
* @return {fabric.Object} thisArg
|
965
|
+
* @chainable
|
876
966
|
*/
|
877
967
|
setShadow: function(options) {
|
878
|
-
this.set('shadow', new fabric.Shadow(options));
|
968
|
+
return this.set('shadow', new fabric.Shadow(options));
|
879
969
|
},
|
880
970
|
|
881
971
|
/**
|
882
972
|
* Animates object's properties
|
883
|
-
* @
|
973
|
+
* @param {String|Object} property to animate (if string) or properties to animate (if object)
|
974
|
+
* @param {Number|Object} value to animate property to (if string was given first) or options object
|
975
|
+
* @return {fabric.Object} thisArg
|
976
|
+
* @chainable
|
884
977
|
*
|
885
978
|
* As object — multiple properties
|
886
979
|
*
|
@@ -895,8 +988,14 @@
|
|
895
988
|
*/
|
896
989
|
animate: function() {
|
897
990
|
if (arguments[0] && typeof arguments[0] === 'object') {
|
898
|
-
|
899
|
-
|
991
|
+
var propsToAnimate = [ ], prop, skipCallbacks;
|
992
|
+
for (prop in arguments[0]) {
|
993
|
+
propsToAnimate.push(prop);
|
994
|
+
}
|
995
|
+
for (var i = 0, len = propsToAnimate.length; i<len; i++) {
|
996
|
+
prop = propsToAnimate[i];
|
997
|
+
skipCallbacks = i !== len - 1;
|
998
|
+
this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks);
|
900
999
|
}
|
901
1000
|
}
|
902
1001
|
else {
|
@@ -907,9 +1006,12 @@
|
|
907
1006
|
|
908
1007
|
/**
|
909
1008
|
* @private
|
910
|
-
* @
|
1009
|
+
* @param {String} property
|
1010
|
+
* @param {String} to
|
1011
|
+
* @param {Object} [options]
|
1012
|
+
* @param {Boolean} [skipCallbacks]
|
911
1013
|
*/
|
912
|
-
_animate: function(property, to, options) {
|
1014
|
+
_animate: function(property, to, options, skipCallbacks) {
|
913
1015
|
var obj = this, propPair;
|
914
1016
|
|
915
1017
|
to = to.toString();
|
@@ -953,9 +1055,12 @@
|
|
953
1055
|
else {
|
954
1056
|
obj.set(property, value);
|
955
1057
|
}
|
1058
|
+
if (skipCallbacks) return;
|
956
1059
|
options.onChange && options.onChange();
|
957
1060
|
},
|
958
1061
|
onComplete: function() {
|
1062
|
+
if (skipCallbacks) return;
|
1063
|
+
|
959
1064
|
obj.setCoords();
|
960
1065
|
options.onComplete && options.onComplete();
|
961
1066
|
}
|
@@ -964,7 +1069,6 @@
|
|
964
1069
|
|
965
1070
|
/**
|
966
1071
|
* Centers object horizontally on canvas to which it was added last
|
967
|
-
* @method centerH
|
968
1072
|
* @return {fabric.Object} thisArg
|
969
1073
|
*/
|
970
1074
|
centerH: function () {
|
@@ -974,7 +1078,6 @@
|
|
974
1078
|
|
975
1079
|
/**
|
976
1080
|
* Centers object vertically on canvas to which it was added last
|
977
|
-
* @method centerV
|
978
1081
|
* @return {fabric.Object} thisArg
|
979
1082
|
* @chainable
|
980
1083
|
*/
|
@@ -985,7 +1088,6 @@
|
|
985
1088
|
|
986
1089
|
/**
|
987
1090
|
* Centers object vertically and horizontally on canvas to which is was added last
|
988
|
-
* @method center
|
989
1091
|
* @return {fabric.Object} thisArg
|
990
1092
|
* @chainable
|
991
1093
|
*/
|
@@ -995,7 +1097,6 @@
|
|
995
1097
|
|
996
1098
|
/**
|
997
1099
|
* Removes object from canvas to which it was added last
|
998
|
-
* @method remove
|
999
1100
|
* @return {fabric.Object} thisArg
|
1000
1101
|
* @chainable
|
1001
1102
|
*/
|
@@ -1005,45 +1106,79 @@
|
|
1005
1106
|
|
1006
1107
|
/**
|
1007
1108
|
* Moves an object to the bottom of the stack of drawn objects
|
1008
|
-
* @method sendToBack
|
1009
1109
|
* @return {fabric.Object} thisArg
|
1010
1110
|
* @chainable
|
1011
1111
|
*/
|
1012
1112
|
sendToBack: function() {
|
1013
|
-
this.
|
1113
|
+
if (this.group) {
|
1114
|
+
fabric.StaticCanvas.prototype.sendToBack.call(this.group, this);
|
1115
|
+
}
|
1116
|
+
else {
|
1117
|
+
this.canvas.sendToBack(this);
|
1118
|
+
}
|
1014
1119
|
return this;
|
1015
1120
|
},
|
1016
1121
|
|
1017
1122
|
/**
|
1018
1123
|
* Moves an object to the top of the stack of drawn objects
|
1019
|
-
* @method bringToFront
|
1020
1124
|
* @return {fabric.Object} thisArg
|
1021
1125
|
* @chainable
|
1022
1126
|
*/
|
1023
1127
|
bringToFront: function() {
|
1024
|
-
this.
|
1128
|
+
if (this.group) {
|
1129
|
+
fabric.StaticCanvas.prototype.bringToFront.call(this.group, this);
|
1130
|
+
}
|
1131
|
+
else {
|
1132
|
+
this.canvas.bringToFront(this);
|
1133
|
+
}
|
1134
|
+
return this;
|
1135
|
+
},
|
1136
|
+
|
1137
|
+
/**
|
1138
|
+
* Moves an object down in stack of drawn objects
|
1139
|
+
* @param intersecting {Boolean} If `true`, send object behind next lower intersecting object
|
1140
|
+
* @return {fabric.Object} thisArg
|
1141
|
+
* @chainable
|
1142
|
+
*/
|
1143
|
+
sendBackwards: function(intersecting) {
|
1144
|
+
if (this.group) {
|
1145
|
+
fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting);
|
1146
|
+
}
|
1147
|
+
else {
|
1148
|
+
this.canvas.sendBackwards(this, intersecting);
|
1149
|
+
}
|
1025
1150
|
return this;
|
1026
1151
|
},
|
1027
1152
|
|
1028
1153
|
/**
|
1029
|
-
* Moves an object
|
1030
|
-
* @
|
1154
|
+
* Moves an object up in stack of drawn objects
|
1155
|
+
* @param intersecting {Boolean} If `true`, send object in front of next upper intersecting object
|
1031
1156
|
* @return {fabric.Object} thisArg
|
1032
1157
|
* @chainable
|
1033
1158
|
*/
|
1034
|
-
|
1035
|
-
this.
|
1159
|
+
bringForward: function(intersecting) {
|
1160
|
+
if (this.group) {
|
1161
|
+
fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting);
|
1162
|
+
}
|
1163
|
+
else {
|
1164
|
+
this.canvas.bringForward(this, intersecting);
|
1165
|
+
}
|
1036
1166
|
return this;
|
1037
1167
|
},
|
1038
1168
|
|
1039
1169
|
/**
|
1040
|
-
* Moves an object
|
1041
|
-
* @
|
1170
|
+
* Moves an object to specified level in stack of drawn objects
|
1171
|
+
* @param {Number} index New position of object
|
1042
1172
|
* @return {fabric.Object} thisArg
|
1043
1173
|
* @chainable
|
1044
1174
|
*/
|
1045
|
-
|
1046
|
-
this.
|
1175
|
+
moveTo: function(index) {
|
1176
|
+
if (this.group) {
|
1177
|
+
fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index);
|
1178
|
+
}
|
1179
|
+
else {
|
1180
|
+
this.canvas.moveTo(this, index);
|
1181
|
+
}
|
1047
1182
|
return this;
|
1048
1183
|
}
|
1049
1184
|
});
|
@@ -1059,10 +1194,17 @@
|
|
1059
1194
|
extend(fabric.Object.prototype, fabric.Observable);
|
1060
1195
|
|
1061
1196
|
/**
|
1197
|
+
* Defines the number of fraction digits when serializing object values. You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc.
|
1062
1198
|
* @static
|
1063
1199
|
* @constant
|
1064
1200
|
* @type Number
|
1065
1201
|
*/
|
1066
1202
|
fabric.Object.NUM_FRACTION_DIGITS = 2;
|
1067
1203
|
|
1204
|
+
/**
|
1205
|
+
* @static
|
1206
|
+
* @type Number
|
1207
|
+
*/
|
1208
|
+
fabric.Object.__uid = 0;
|
1209
|
+
|
1068
1210
|
})(typeof exports !== 'undefined' ? exports : this);
|