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
@@ -15,15 +15,15 @@
|
|
15
15
|
|
16
16
|
/**
|
17
17
|
* Image class
|
18
|
-
* @class Image
|
18
|
+
* @class fabric.Image
|
19
19
|
* @extends fabric.Object
|
20
20
|
*/
|
21
|
-
fabric.Image = fabric.util.createClass(fabric.Object, /** @
|
21
|
+
fabric.Image = fabric.util.createClass(fabric.Object, /** @lends fabric.Image.prototype */ {
|
22
22
|
|
23
23
|
/**
|
24
24
|
* Type of an object
|
25
|
-
* @property
|
26
25
|
* @type String
|
26
|
+
* @default
|
27
27
|
*/
|
28
28
|
type: 'image',
|
29
29
|
|
@@ -31,7 +31,7 @@
|
|
31
31
|
* Constructor
|
32
32
|
* @param {HTMLImageElement | String} element Image element
|
33
33
|
* @param {Object} [options] Options object
|
34
|
-
* @return {fabric.Image}
|
34
|
+
* @return {fabric.Image} thisArg
|
35
35
|
*/
|
36
36
|
initialize: function(element, options) {
|
37
37
|
options || (options = { });
|
@@ -51,8 +51,7 @@
|
|
51
51
|
|
52
52
|
/**
|
53
53
|
* Returns image element which this instance if based on
|
54
|
-
* @
|
55
|
-
* @return {HTMLImageElement} image element
|
54
|
+
* @return {HTMLImageElement} Image element
|
56
55
|
*/
|
57
56
|
getElement: function() {
|
58
57
|
return this._element;
|
@@ -60,7 +59,6 @@
|
|
60
59
|
|
61
60
|
/**
|
62
61
|
* Sets image element for this instance to a specified one
|
63
|
-
* @method setElement
|
64
62
|
* @param {HTMLImageElement} element
|
65
63
|
* @return {fabric.Image} thisArg
|
66
64
|
* @chainable
|
@@ -73,7 +71,6 @@
|
|
73
71
|
|
74
72
|
/**
|
75
73
|
* Returns original size of an image
|
76
|
-
* @method getOriginalSize
|
77
74
|
* @return {Object} object with "width" and "height" properties
|
78
75
|
*/
|
79
76
|
getOriginalSize: function() {
|
@@ -86,14 +83,19 @@
|
|
86
83
|
|
87
84
|
/**
|
88
85
|
* Renders image on a specified context
|
89
|
-
* @method render
|
90
86
|
* @param {CanvasRenderingContext2D} ctx Context to render on
|
87
|
+
* @param {Boolean} [noTransform] When true, context is not transformed
|
91
88
|
*/
|
92
89
|
render: function(ctx, noTransform) {
|
90
|
+
// do not render if object is not visible
|
91
|
+
if (!this.visible) return;
|
92
|
+
|
93
93
|
ctx.save();
|
94
94
|
var m = this.transformMatrix;
|
95
|
+
var isInPathGroup = this.group && this.group.type !== 'group';
|
96
|
+
|
95
97
|
// this._resetWidthHeight();
|
96
|
-
if (
|
98
|
+
if (isInPathGroup) {
|
97
99
|
ctx.translate(-this.group.width/2 + this.width/2, -this.group.height/2 + this.height/2);
|
98
100
|
}
|
99
101
|
if (m) {
|
@@ -103,9 +105,16 @@
|
|
103
105
|
this.transform(ctx);
|
104
106
|
}
|
105
107
|
|
108
|
+
ctx.save();
|
106
109
|
this._setShadow(ctx);
|
110
|
+
this.clipTo && fabric.util.clipContext(this, ctx);
|
107
111
|
this._render(ctx);
|
108
|
-
this.
|
112
|
+
if (this.shadow && !this.shadow.affectStroke) {
|
113
|
+
this._removeShadow(ctx);
|
114
|
+
}
|
115
|
+
this._renderStroke(ctx);
|
116
|
+
this.clipTo && ctx.restore();
|
117
|
+
ctx.restore();
|
109
118
|
|
110
119
|
if (this.active && !noTransform) {
|
111
120
|
this.drawBorders(ctx);
|
@@ -114,11 +123,58 @@
|
|
114
123
|
ctx.restore();
|
115
124
|
},
|
116
125
|
|
126
|
+
/**
|
127
|
+
* @private
|
128
|
+
* @param {CanvasRenderingContext2D} ctx Context to render on
|
129
|
+
*/
|
130
|
+
_stroke: function(ctx) {
|
131
|
+
ctx.save();
|
132
|
+
ctx.lineWidth = this.strokeWidth;
|
133
|
+
ctx.lineCap = this.strokeLineCap;
|
134
|
+
ctx.lineJoin = this.strokeLineJoin;
|
135
|
+
ctx.miterLimit = this.strokeMiterLimit;
|
136
|
+
ctx.strokeStyle = this.stroke.toLive
|
137
|
+
? this.stroke.toLive(ctx)
|
138
|
+
: this.stroke;
|
139
|
+
|
140
|
+
ctx.beginPath();
|
141
|
+
ctx.strokeRect(-this.width / 2, -this.height / 2, this.width, this.height);
|
142
|
+
ctx.closePath();
|
143
|
+
ctx.restore();
|
144
|
+
},
|
145
|
+
|
146
|
+
/**
|
147
|
+
* @private
|
148
|
+
* @param {CanvasRenderingContext2D} ctx Context to render on
|
149
|
+
*/
|
150
|
+
_renderDashedStroke: function(ctx) {
|
151
|
+
var x = -this.width/2,
|
152
|
+
y = -this.height/2,
|
153
|
+
w = this.width,
|
154
|
+
h = this.height;
|
155
|
+
|
156
|
+
ctx.save();
|
157
|
+
ctx.lineWidth = this.strokeWidth;
|
158
|
+
ctx.lineCap = this.strokeLineCap;
|
159
|
+
ctx.lineJoin = this.strokeLineJoin;
|
160
|
+
ctx.miterLimit = this.strokeMiterLimit;
|
161
|
+
ctx.strokeStyle = this.stroke.toLive
|
162
|
+
? this.stroke.toLive(ctx)
|
163
|
+
: this.stroke;
|
164
|
+
|
165
|
+
ctx.beginPath();
|
166
|
+
fabric.util.drawDashedLine(ctx, x, y, x+w, y, this.strokeDashArray);
|
167
|
+
fabric.util.drawDashedLine(ctx, x+w, y, x+w, y+h, this.strokeDashArray);
|
168
|
+
fabric.util.drawDashedLine(ctx, x+w, y+h, x, y+h, this.strokeDashArray);
|
169
|
+
fabric.util.drawDashedLine(ctx, x, y+h, x, y, this.strokeDashArray);
|
170
|
+
ctx.closePath();
|
171
|
+
ctx.restore();
|
172
|
+
},
|
173
|
+
|
117
174
|
/**
|
118
175
|
* Returns object representation of an instance
|
119
|
-
* @method toObject
|
120
176
|
* @param {Array} propertiesToInclude
|
121
|
-
* @return {Object}
|
177
|
+
* @return {Object} propertiesToInclude Object representation of an instance
|
122
178
|
*/
|
123
179
|
toObject: function(propertiesToInclude) {
|
124
180
|
return extend(this.callSuper('toObject', propertiesToInclude), {
|
@@ -127,27 +183,48 @@
|
|
127
183
|
});
|
128
184
|
},
|
129
185
|
|
186
|
+
/* _TO_SVG_START_ */
|
130
187
|
/**
|
131
188
|
* Returns SVG representation of an instance
|
132
|
-
* @method toSVG
|
133
189
|
* @return {String} svg representation of an instance
|
134
190
|
*/
|
135
191
|
toSVG: function() {
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
192
|
+
var markup = [];
|
193
|
+
|
194
|
+
markup.push(
|
195
|
+
'<g transform="', this.getSvgTransform(), '">',
|
196
|
+
'<image xlink:href="', this.getSvgSrc(),
|
197
|
+
'" style="', this.getSvgStyles(),
|
198
|
+
// we're essentially moving origin of transformation from top/left corner to the center of the shape
|
199
|
+
// by wrapping it in container <g> element with actual transformation, then offsetting object to the top/left
|
200
|
+
// so that object's center aligns with container's left/top
|
201
|
+
'" transform="translate(' + (-this.width/2) + ' ' + (-this.height/2) + ')',
|
202
|
+
'" width="', this.width,
|
203
|
+
'" height="', this.height,
|
204
|
+
'"></image>'
|
205
|
+
);
|
206
|
+
|
207
|
+
if (this.stroke || this.strokeDashArray) {
|
208
|
+
var origFill = this.fill;
|
209
|
+
this.fill = null;
|
210
|
+
markup.push(
|
211
|
+
'<rect ',
|
212
|
+
'x="', (-1 * this.width / 2), '" y="', (-1 * this.height / 2),
|
213
|
+
'" width="', this.width, '" height="', this.height,
|
214
|
+
'" style="', this.getSvgStyles(),
|
215
|
+
'"/>'
|
216
|
+
);
|
217
|
+
this.fill = origFill;
|
218
|
+
}
|
219
|
+
|
220
|
+
markup.push('</g>');
|
221
|
+
|
222
|
+
return markup.join('');
|
146
223
|
},
|
224
|
+
/* _TO_SVG_END_ */
|
147
225
|
|
148
226
|
/**
|
149
227
|
* Returns source of an image
|
150
|
-
* @method getSrc
|
151
228
|
* @return {String} Source of an image
|
152
229
|
*/
|
153
230
|
getSrc: function() {
|
@@ -156,7 +233,6 @@
|
|
156
233
|
|
157
234
|
/**
|
158
235
|
* Returns string representation of an instance
|
159
|
-
* @method toString
|
160
236
|
* @return {String} String representation of an instance
|
161
237
|
*/
|
162
238
|
toString: function() {
|
@@ -165,9 +241,8 @@
|
|
165
241
|
|
166
242
|
/**
|
167
243
|
* Returns a clone of an instance
|
168
|
-
* @method clone
|
169
|
-
* @param {Array} propertiesToInclude
|
170
244
|
* @param {Function} callback Callback is invoked with a clone as a first argument
|
245
|
+
* @param {Array} propertiesToInclude
|
171
246
|
*/
|
172
247
|
clone: function(callback, propertiesToInclude) {
|
173
248
|
this.constructor.fromObject(this.toObject(propertiesToInclude), callback);
|
@@ -188,10 +263,9 @@
|
|
188
263
|
return;
|
189
264
|
}
|
190
265
|
|
191
|
-
var
|
192
|
-
imgEl = this._originalImage,
|
266
|
+
var imgEl = this._originalImage,
|
193
267
|
canvasEl = fabric.util.createCanvasElement(),
|
194
|
-
replacement =
|
268
|
+
replacement = fabric.util.createImage(),
|
195
269
|
_this = this;
|
196
270
|
|
197
271
|
canvasEl.width = imgEl.width;
|
@@ -204,24 +278,25 @@
|
|
204
278
|
});
|
205
279
|
|
206
280
|
/** @ignore */
|
207
|
-
|
208
|
-
_this._element = replacement;
|
209
|
-
callback && callback();
|
210
|
-
replacement.onload = canvasEl = imgEl = null;
|
211
|
-
};
|
281
|
+
|
212
282
|
replacement.width = imgEl.width;
|
213
283
|
replacement.height = imgEl.height;
|
214
284
|
|
215
|
-
if (isLikelyNode) {
|
285
|
+
if (fabric.isLikelyNode) {
|
216
286
|
// cut off data:image/png;base64, part in the beginning
|
217
287
|
var base64str = canvasEl.toDataURL('image/png').substring(22);
|
218
288
|
replacement.src = new Buffer(base64str, 'base64');
|
219
|
-
_this._element = replacement;
|
220
289
|
|
221
|
-
// onload doesn't fire in node, so we invoke callback manually
|
290
|
+
// onload doesn't fire in some node versions, so we invoke callback manually
|
291
|
+
_this._element = replacement;
|
222
292
|
callback && callback();
|
223
293
|
}
|
224
294
|
else {
|
295
|
+
replacement.onload = function() {
|
296
|
+
_this._element = replacement;
|
297
|
+
callback && callback();
|
298
|
+
replacement.onload = canvasEl = imgEl = null;
|
299
|
+
};
|
225
300
|
replacement.src = canvasEl.toDataURL('image/png');
|
226
301
|
}
|
227
302
|
|
@@ -230,7 +305,6 @@
|
|
230
305
|
|
231
306
|
/**
|
232
307
|
* @private
|
233
|
-
* @method _render
|
234
308
|
* @param ctx
|
235
309
|
*/
|
236
310
|
_render: function(ctx) {
|
@@ -245,7 +319,6 @@
|
|
245
319
|
|
246
320
|
/**
|
247
321
|
* @private
|
248
|
-
* @method _resetWidthHeight
|
249
322
|
*/
|
250
323
|
_resetWidthHeight: function() {
|
251
324
|
var element = this.getElement();
|
@@ -258,7 +331,6 @@
|
|
258
331
|
* The Image class's initialization method. This method is automatically
|
259
332
|
* called by the constructor.
|
260
333
|
* @private
|
261
|
-
* @method _initElement
|
262
334
|
* @param {HTMLImageElement|String} el The element representing the image
|
263
335
|
*/
|
264
336
|
_initElement: function(element) {
|
@@ -268,7 +340,6 @@
|
|
268
340
|
|
269
341
|
/**
|
270
342
|
* @private
|
271
|
-
* @method _initConfig
|
272
343
|
* @param {Object} [options] Options object
|
273
344
|
*/
|
274
345
|
_initConfig: function(options) {
|
@@ -279,7 +350,6 @@
|
|
279
350
|
|
280
351
|
/**
|
281
352
|
* @private
|
282
|
-
* @method _initFilters
|
283
353
|
* @param {Object} object Object with filters property
|
284
354
|
*/
|
285
355
|
_initFilters: function(object) {
|
@@ -292,7 +362,6 @@
|
|
292
362
|
|
293
363
|
/**
|
294
364
|
* @private
|
295
|
-
* @method _setWidthHeight
|
296
365
|
* @param {Object} [options] Object with width/height properties
|
297
366
|
*/
|
298
367
|
_setWidthHeight: function(options) {
|
@@ -307,8 +376,7 @@
|
|
307
376
|
|
308
377
|
/**
|
309
378
|
* Returns complexity of an instance
|
310
|
-
* @
|
311
|
-
* @return {Number} complexity
|
379
|
+
* @return {Number} complexity of this instance
|
312
380
|
*/
|
313
381
|
complexity: function() {
|
314
382
|
return 1;
|
@@ -325,14 +393,12 @@
|
|
325
393
|
/**
|
326
394
|
* Alias for getSrc
|
327
395
|
* @static
|
328
|
-
* @method getSvgSrc
|
329
396
|
*/
|
330
397
|
fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc;
|
331
398
|
|
332
399
|
/**
|
333
400
|
* Creates an instance of fabric.Image from its object representation
|
334
401
|
* @static
|
335
|
-
* @method fromObject
|
336
402
|
* @param {Object} object
|
337
403
|
* @param {Function} [callback] Callback to invoke when an image instance is created
|
338
404
|
*/
|
@@ -343,6 +409,7 @@
|
|
343
409
|
if (object.width) {
|
344
410
|
img.width = object.width;
|
345
411
|
}
|
412
|
+
|
346
413
|
if (object.height) {
|
347
414
|
img.height = object.height;
|
348
415
|
}
|
@@ -353,60 +420,55 @@
|
|
353
420
|
|
354
421
|
var instance = new fabric.Image(img, object);
|
355
422
|
callback && callback(instance);
|
356
|
-
|
357
|
-
|
423
|
+
img = img.onload = img.onerror = null;
|
424
|
+
};
|
425
|
+
|
426
|
+
/** @ignore */
|
427
|
+
img.onerror = function() {
|
428
|
+
fabric.log('Error loading ' + img.src);
|
429
|
+
callback && callback(null, true);
|
430
|
+
img = img.onload = img.onerror = null;
|
431
|
+
};
|
358
432
|
|
359
|
-
/** @ignore */
|
360
|
-
img.onerror = function() {
|
361
|
-
fabric.log('Error loading ' + img.src);
|
362
|
-
callback && callback(null, true);
|
363
|
-
img = img.onload = img.onerror = null;
|
364
|
-
};
|
365
433
|
img.src = src;
|
366
434
|
};
|
367
435
|
|
368
436
|
/**
|
369
437
|
* Creates an instance of fabric.Image from an URL string
|
370
438
|
* @static
|
371
|
-
* @method fromURL
|
372
439
|
* @param {String} url URL to create an image from
|
373
440
|
* @param {Function} [callback] Callback to invoke when image is created (newly created image is passed as a first argument)
|
374
441
|
* @param {Object} [imgOptions] Options object
|
375
442
|
*/
|
376
443
|
fabric.Image.fromURL = function(url, callback, imgOptions) {
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
img.onload = function() {
|
381
|
-
if (callback) {
|
382
|
-
callback(new fabric.Image(img, imgOptions));
|
383
|
-
}
|
384
|
-
img = img.onload = null;
|
385
|
-
};
|
386
|
-
img.src = url;
|
444
|
+
fabric.util.loadImage(url, function(img) {
|
445
|
+
callback(new fabric.Image(img, imgOptions));
|
446
|
+
});
|
387
447
|
};
|
388
448
|
|
449
|
+
/* _FROM_SVG_START_ */
|
389
450
|
/**
|
390
451
|
* List of attribute names to account for when parsing SVG element (used by {@link fabric.Image.fromElement})
|
391
452
|
* @static
|
392
453
|
* @see http://www.w3.org/TR/SVG/struct.html#ImageElement
|
393
454
|
*/
|
394
|
-
fabric.Image.ATTRIBUTE_NAMES = 'x y width height
|
455
|
+
fabric.Image.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y width height xlink:href'.split(' '));
|
395
456
|
|
396
457
|
/**
|
397
458
|
* Returns {@link fabric.Image} instance from an SVG element
|
398
459
|
* @static
|
399
|
-
* @method fabric.Image.fromElement
|
400
460
|
* @param {SVGElement} element Element to parse
|
401
461
|
* @param {Function} callback Callback to execute when fabric.Image object is created
|
402
462
|
* @param {Object} [options] Options object
|
403
|
-
* @return {fabric.Image}
|
463
|
+
* @return {fabric.Image} Instance of fabric.Image
|
404
464
|
*/
|
405
465
|
fabric.Image.fromElement = function(element, callback, options) {
|
406
466
|
var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES);
|
407
467
|
|
408
|
-
fabric.Image.fromURL(parsedAttributes['xlink:href'], callback,
|
468
|
+
fabric.Image.fromURL(parsedAttributes['xlink:href'], callback,
|
469
|
+
extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));
|
409
470
|
};
|
471
|
+
/* _FROM_SVG_END_ */
|
410
472
|
|
411
473
|
/**
|
412
474
|
* Indicates that instances of this type are async
|
@@ -4,7 +4,8 @@
|
|
4
4
|
|
5
5
|
var fabric = global.fabric || (global.fabric = { }),
|
6
6
|
extend = fabric.util.object.extend,
|
7
|
-
coordProps = { 'x1': 1, 'x2': 1, 'y1': 1, 'y2': 1 }
|
7
|
+
coordProps = { 'x1': 1, 'x2': 1, 'y1': 1, 'y2': 1 },
|
8
|
+
supportsLineDash = fabric.StaticCanvas.supports('setLineDash');
|
8
9
|
|
9
10
|
if (fabric.Line) {
|
10
11
|
fabric.warn('fabric.Line is already defined');
|
@@ -13,21 +14,20 @@
|
|
13
14
|
|
14
15
|
/**
|
15
16
|
* Line class
|
16
|
-
* @class Line
|
17
|
+
* @class fabric.Line
|
17
18
|
* @extends fabric.Object
|
18
19
|
*/
|
19
|
-
fabric.Line = fabric.util.createClass(fabric.Object, /** @
|
20
|
+
fabric.Line = fabric.util.createClass(fabric.Object, /** @lends fabric.Line.prototype */ {
|
20
21
|
|
21
22
|
/**
|
22
23
|
* Type of an object
|
23
|
-
* @property
|
24
24
|
* @type String
|
25
|
+
* @default
|
25
26
|
*/
|
26
27
|
type: 'line',
|
27
28
|
|
28
29
|
/**
|
29
30
|
* Constructor
|
30
|
-
* @method initialize
|
31
31
|
* @param {Array} [points] Array of points
|
32
32
|
* @param {Object} [options] Options object
|
33
33
|
* @return {fabric.Line} thisArg
|
@@ -51,22 +51,20 @@
|
|
51
51
|
|
52
52
|
/**
|
53
53
|
* @private
|
54
|
-
* @method _setWidthHeight
|
55
54
|
* @param {Object} [options] Options
|
56
55
|
*/
|
57
56
|
_setWidthHeight: function(options) {
|
58
57
|
options || (options = { });
|
59
58
|
|
60
|
-
this.set('width', (this.x2 - this.x1) || 1);
|
61
|
-
this.set('height', (this.y2 - this.y1) || 1);
|
59
|
+
this.set('width', Math.abs(this.x2 - this.x1) || 1);
|
60
|
+
this.set('height', Math.abs(this.y2 - this.y1) || 1);
|
62
61
|
|
63
|
-
this.set('left', 'left' in options ? options.left : (this.x1 + this.width / 2));
|
64
|
-
this.set('top', 'top' in options ? options.top : (this.y1 + this.height / 2));
|
62
|
+
this.set('left', 'left' in options ? options.left : (Math.min(this.x1, this.x2) + this.width / 2));
|
63
|
+
this.set('top', 'top' in options ? options.top : (Math.min(this.y1, this.y2) + this.height / 2));
|
65
64
|
},
|
66
65
|
|
67
66
|
/**
|
68
67
|
* @private
|
69
|
-
* @method _set
|
70
68
|
* @param {String} key
|
71
69
|
* @param {Any} value
|
72
70
|
*/
|
@@ -80,19 +78,31 @@
|
|
80
78
|
|
81
79
|
/**
|
82
80
|
* @private
|
83
|
-
* @method _render
|
84
81
|
* @param {CanvasRenderingContext2D} ctx Context to render on
|
85
82
|
*/
|
86
83
|
_render: function(ctx) {
|
87
84
|
ctx.beginPath();
|
88
85
|
|
89
|
-
|
86
|
+
var isInPathGroup = this.group && this.group.type !== 'group';
|
87
|
+
if (isInPathGroup && !this.transformMatrix) {
|
90
88
|
ctx.translate(-this.group.width/2 + this.left, -this.group.height / 2 + this.top);
|
91
89
|
}
|
92
90
|
|
93
|
-
|
94
|
-
|
95
|
-
|
91
|
+
if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) {
|
92
|
+
|
93
|
+
// move from center (of virtual box) to its left/top corner
|
94
|
+
// we can't assume x1, y1 is top left and x2, y2 is bottom right
|
95
|
+
var xMult = this.x1 <= this.x2 ? -1 : 1;
|
96
|
+
var yMult = this.y1 <= this.y2 ? -1 : 1;
|
97
|
+
|
98
|
+
ctx.moveTo(
|
99
|
+
this.width === 1 ? 0 : (xMult * this.width / 2),
|
100
|
+
this.height === 1 ? 0 : (yMult * this.height / 2));
|
101
|
+
|
102
|
+
ctx.lineTo(
|
103
|
+
this.width === 1 ? 0 : (xMult * -1 * this.width / 2),
|
104
|
+
this.height === 1 ? 0 : (yMult * -1 * this.height / 2));
|
105
|
+
}
|
96
106
|
|
97
107
|
ctx.lineWidth = this.strokeWidth;
|
98
108
|
|
@@ -100,18 +110,22 @@
|
|
100
110
|
// make sure setting "fill" changes color of a line
|
101
111
|
// (by copying fillStyle to strokeStyle, since line is stroked, not filled)
|
102
112
|
var origStrokeStyle = ctx.strokeStyle;
|
103
|
-
ctx.strokeStyle = ctx.fillStyle;
|
104
|
-
|
113
|
+
ctx.strokeStyle = this.stroke || ctx.fillStyle;
|
114
|
+
this._renderStroke(ctx);
|
105
115
|
ctx.strokeStyle = origStrokeStyle;
|
106
116
|
},
|
107
117
|
|
108
118
|
/**
|
109
|
-
*
|
110
|
-
* @
|
111
|
-
* @return {Number} complexity
|
119
|
+
* @private
|
120
|
+
* @param {CanvasRenderingContext2D} ctx Context to render on
|
112
121
|
*/
|
113
|
-
|
114
|
-
|
122
|
+
_renderDashedStroke: function(ctx) {
|
123
|
+
var x = this.width === 1 ? 0 : -this.width / 2,
|
124
|
+
y = this.height === 1 ? 0 : -this.height / 2;
|
125
|
+
|
126
|
+
ctx.beginPath();
|
127
|
+
fabric.util.drawDashedLine(ctx, x, y, -x, -y, this.strokeDashArray);
|
128
|
+
ctx.closePath();
|
115
129
|
},
|
116
130
|
|
117
131
|
/**
|
@@ -129,35 +143,52 @@
|
|
129
143
|
});
|
130
144
|
},
|
131
145
|
|
146
|
+
/* _TO_SVG_START_ */
|
132
147
|
/**
|
133
148
|
* Returns SVG representation of an instance
|
134
|
-
* @method toSVG
|
135
149
|
* @return {String} svg representation of an instance
|
136
150
|
*/
|
137
151
|
toSVG: function() {
|
138
|
-
|
152
|
+
var markup = [];
|
153
|
+
|
154
|
+
if (this.stroke && this.stroke.toLive) {
|
155
|
+
markup.push(this.stroke.toSVG(this, true));
|
156
|
+
}
|
157
|
+
|
158
|
+
markup.push(
|
139
159
|
'<line ',
|
140
|
-
'x1="', this.get('x1'),
|
141
|
-
'y1="', this.get('y1'),
|
142
|
-
'x2="', this.get('x2'),
|
143
|
-
'y2="', this.get('y2'),
|
144
|
-
'style="', this.getSvgStyles(),
|
145
|
-
'/>'
|
146
|
-
|
160
|
+
'x1="', this.get('x1'),
|
161
|
+
'" y1="', this.get('y1'),
|
162
|
+
'" x2="', this.get('x2'),
|
163
|
+
'" y2="', this.get('y2'),
|
164
|
+
'" style="', this.getSvgStyles(),
|
165
|
+
'"/>'
|
166
|
+
);
|
167
|
+
|
168
|
+
return markup.join('');
|
169
|
+
},
|
170
|
+
/* _TO_SVG_END_ */
|
171
|
+
|
172
|
+
/**
|
173
|
+
* Returns complexity of an instance
|
174
|
+
* @return {Number} complexity
|
175
|
+
*/
|
176
|
+
complexity: function() {
|
177
|
+
return 1;
|
147
178
|
}
|
148
179
|
});
|
149
180
|
|
181
|
+
/* _FROM_SVG_START_ */
|
150
182
|
/**
|
151
183
|
* List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement})
|
152
184
|
* @static
|
153
185
|
* @see http://www.w3.org/TR/SVG/shapes.html#LineElement
|
154
186
|
*/
|
155
|
-
fabric.Line.ATTRIBUTE_NAMES = 'x1 y1 x2 y2
|
187
|
+
fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' '));
|
156
188
|
|
157
189
|
/**
|
158
190
|
* Returns fabric.Line instance from an SVG element
|
159
191
|
* @static
|
160
|
-
* @method fabric.Line.fromElement
|
161
192
|
* @param {SVGElement} element Element to parse
|
162
193
|
* @param {Object} [options] Options object
|
163
194
|
* @return {fabric.Line} instance of fabric.Line
|
@@ -172,11 +203,11 @@
|
|
172
203
|
];
|
173
204
|
return new fabric.Line(points, extend(parsedAttributes, options));
|
174
205
|
};
|
206
|
+
/* _FROM_SVG_END_ */
|
175
207
|
|
176
208
|
/**
|
177
209
|
* Returns fabric.Line instance from an object representation
|
178
210
|
* @static
|
179
|
-
* @method fabric.Line.fromObject
|
180
211
|
* @param {Object} object Object to create an instance from
|
181
212
|
* @return {fabric.Line} instance of fabric.Line
|
182
213
|
*/
|
@@ -185,4 +216,4 @@
|
|
185
216
|
return new fabric.Line(points, object);
|
186
217
|
};
|
187
218
|
|
188
|
-
})(typeof exports !== 'undefined' ? exports : this);
|
219
|
+
})(typeof exports !== 'undefined' ? exports : this);
|