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
@@ -0,0 +1,79 @@
|
|
1
|
+
/**
|
2
|
+
* @private
|
3
|
+
* @param {CanvasRenderingContext2D} ctx Context to render on
|
4
|
+
*/
|
5
|
+
fabric.util.object.extend(fabric.Text.prototype, {
|
6
|
+
_renderViaCufon: function(ctx) {
|
7
|
+
|
8
|
+
var o = Cufon.textOptions || (Cufon.textOptions = { });
|
9
|
+
|
10
|
+
// export options to be used by cufon.js
|
11
|
+
o.left = this.left;
|
12
|
+
o.top = this.top;
|
13
|
+
o.context = ctx;
|
14
|
+
o.color = this.fill;
|
15
|
+
|
16
|
+
var el = this._initDummyElementForCufon();
|
17
|
+
|
18
|
+
// set "cursor" to top/left corner
|
19
|
+
this.transform(ctx);
|
20
|
+
|
21
|
+
// draw text
|
22
|
+
Cufon.replaceElement(el, {
|
23
|
+
engine: 'canvas',
|
24
|
+
separate: 'none',
|
25
|
+
fontFamily: this.fontFamily,
|
26
|
+
fontWeight: this.fontWeight,
|
27
|
+
textDecoration: this.textDecoration,
|
28
|
+
textShadow: this.textShadow,
|
29
|
+
textAlign: this.textAlign,
|
30
|
+
fontStyle: this.fontStyle,
|
31
|
+
lineHeight: this.lineHeight,
|
32
|
+
stroke: this.stroke,
|
33
|
+
strokeWidth: this.strokeWidth,
|
34
|
+
backgroundColor: this.backgroundColor,
|
35
|
+
textBackgroundColor: this.textBackgroundColor
|
36
|
+
});
|
37
|
+
|
38
|
+
// update width, height
|
39
|
+
this.width = o.width;
|
40
|
+
this.height = o.height;
|
41
|
+
|
42
|
+
this._totalLineHeight = o.totalLineHeight;
|
43
|
+
this._fontAscent = o.fontAscent;
|
44
|
+
this._boundaries = o.boundaries;
|
45
|
+
this._shadowOffsets = o.shadowOffsets;
|
46
|
+
this._shadows = o.shadows || [ ];
|
47
|
+
|
48
|
+
el = null;
|
49
|
+
|
50
|
+
// need to set coords _after_ the width/height was retreived from Cufon
|
51
|
+
this.setCoords();
|
52
|
+
},
|
53
|
+
|
54
|
+
/**
|
55
|
+
* @private
|
56
|
+
*/
|
57
|
+
_initDummyElementForCufon: function() {
|
58
|
+
var el = fabric.document.createElement('pre'),
|
59
|
+
container = fabric.document.createElement('div');
|
60
|
+
|
61
|
+
// Cufon doesn't play nice with textDecoration=underline if element doesn't have a parent
|
62
|
+
container.appendChild(el);
|
63
|
+
|
64
|
+
if (typeof G_vmlCanvasManager === 'undefined') {
|
65
|
+
el.innerHTML = this.text;
|
66
|
+
}
|
67
|
+
else {
|
68
|
+
// IE 7 & 8 drop newlines and white space on text nodes
|
69
|
+
// see: http://web.student.tuwien.ac.at/~e0226430/innerHtmlQuirk.html
|
70
|
+
// see: http://www.w3schools.com/dom/dom_mozilla_vs_ie.asp
|
71
|
+
el.innerText = this.text.replace(/\r?\n/gi, '\r');
|
72
|
+
}
|
73
|
+
|
74
|
+
el.style.fontSize = this.fontSize + 'px';
|
75
|
+
el.style.letterSpacing = 'normal';
|
76
|
+
|
77
|
+
return el;
|
78
|
+
}
|
79
|
+
});
|
@@ -11,21 +11,21 @@
|
|
11
11
|
|
12
12
|
/**
|
13
13
|
* Triangle class
|
14
|
-
* @class Triangle
|
14
|
+
* @class fabric.Triangle
|
15
15
|
* @extends fabric.Object
|
16
|
+
* @return {fabric.Triangle} thisArg
|
16
17
|
*/
|
17
|
-
fabric.Triangle = fabric.util.createClass(fabric.Object, /** @
|
18
|
+
fabric.Triangle = fabric.util.createClass(fabric.Object, /** @lends fabric.Triangle.prototype */ {
|
18
19
|
|
19
20
|
/**
|
20
21
|
* Type of an object
|
21
|
-
* @property
|
22
22
|
* @type String
|
23
|
+
* @default
|
23
24
|
*/
|
24
25
|
type: 'triangle',
|
25
26
|
|
26
27
|
/**
|
27
28
|
* Constructor
|
28
|
-
* @method initialize
|
29
29
|
* @param {Object} [options] Options object
|
30
30
|
* @return {Object} thisArg
|
31
31
|
*/
|
@@ -40,7 +40,6 @@
|
|
40
40
|
|
41
41
|
/**
|
42
42
|
* @private
|
43
|
-
* @method _render
|
44
43
|
* @param ctx {CanvasRenderingContext2D} Context to render on
|
45
44
|
*/
|
46
45
|
_render: function(ctx) {
|
@@ -53,31 +52,33 @@
|
|
53
52
|
ctx.lineTo(widthBy2, heightBy2);
|
54
53
|
ctx.closePath();
|
55
54
|
|
56
|
-
|
57
|
-
|
58
|
-
}
|
59
|
-
if (this.stroke) {
|
60
|
-
ctx.stroke();
|
61
|
-
}
|
55
|
+
this._renderFill(ctx);
|
56
|
+
this._renderStroke(ctx);
|
62
57
|
},
|
63
58
|
|
64
59
|
/**
|
65
|
-
*
|
66
|
-
* @
|
67
|
-
* @return {Number} complexity of this instance
|
60
|
+
* @private
|
61
|
+
* @param ctx {CanvasRenderingContext2D} Context to render on
|
68
62
|
*/
|
69
|
-
|
70
|
-
|
63
|
+
_renderDashedStroke: function(ctx) {
|
64
|
+
var widthBy2 = this.width / 2,
|
65
|
+
heightBy2 = this.height / 2;
|
66
|
+
|
67
|
+
ctx.beginPath();
|
68
|
+
fabric.util.drawDashedLine(ctx, -widthBy2, heightBy2, 0, -heightBy2, this.strokeDashArray);
|
69
|
+
fabric.util.drawDashedLine(ctx, 0, -heightBy2, widthBy2, heightBy2, this.strokeDashArray);
|
70
|
+
fabric.util.drawDashedLine(ctx, widthBy2, heightBy2, -widthBy2, heightBy2, this.strokeDashArray);
|
71
|
+
ctx.closePath();
|
71
72
|
},
|
72
73
|
|
74
|
+
/* _TO_SVG_START_ */
|
73
75
|
/**
|
74
76
|
* Returns SVG representation of an instance
|
75
|
-
* @method toSVG
|
76
77
|
* @return {String} svg representation of an instance
|
77
78
|
*/
|
78
79
|
toSVG: function() {
|
79
|
-
|
80
|
-
|
80
|
+
var markup = [],
|
81
|
+
widthBy2 = this.width / 2,
|
81
82
|
heightBy2 = this.height / 2;
|
82
83
|
|
83
84
|
var points = [
|
@@ -86,18 +87,37 @@
|
|
86
87
|
widthBy2 + " " + heightBy2
|
87
88
|
].join(",");
|
88
89
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
90
|
+
if (this.fill && this.fill.toLive) {
|
91
|
+
markup.push(this.fill.toSVG(this, true));
|
92
|
+
}
|
93
|
+
if (this.stroke && this.stroke.toLive) {
|
94
|
+
markup.push(this.stroke.toSVG(this, true));
|
95
|
+
}
|
96
|
+
|
97
|
+
markup.push(
|
98
|
+
'<polygon ',
|
99
|
+
'points="', points,
|
100
|
+
'" style="', this.getSvgStyles(),
|
101
|
+
'" transform="', this.getSvgTransform(),
|
102
|
+
'"/>'
|
103
|
+
);
|
104
|
+
|
105
|
+
return markup.join('');
|
106
|
+
},
|
107
|
+
/* _TO_SVG_END_ */
|
108
|
+
|
109
|
+
/**
|
110
|
+
* Returns complexity of an instance
|
111
|
+
* @return {Number} complexity of this instance
|
112
|
+
*/
|
113
|
+
complexity: function() {
|
114
|
+
return 1;
|
94
115
|
}
|
95
116
|
});
|
96
117
|
|
97
118
|
/**
|
98
119
|
* Returns fabric.Triangle instance from an object representation
|
99
120
|
* @static
|
100
|
-
* @method Canvas.Trangle.fromObject
|
101
121
|
* @param object {Object} object to create an instance from
|
102
122
|
* @return {Object} instance of Canvas.Triangle
|
103
123
|
*/
|
@@ -105,4 +125,4 @@
|
|
105
125
|
return new fabric.Triangle(object);
|
106
126
|
};
|
107
127
|
|
108
|
-
})(typeof exports !== 'undefined' ? exports : this);
|
128
|
+
})(typeof exports !== 'undefined' ? exports : this);
|
@@ -19,8 +19,12 @@
|
|
19
19
|
* Static canvas class
|
20
20
|
* @class fabric.StaticCanvas
|
21
21
|
* @constructor
|
22
|
+
*
|
22
23
|
* @param {HTMLElement | String} el <canvas> element to initialize instance on
|
23
24
|
* @param {Object} [options] Options object
|
25
|
+
*
|
26
|
+
* @extends fabric.Collection
|
27
|
+
* @extends fabric.Observable
|
24
28
|
*/
|
25
29
|
fabric.StaticCanvas = function (el, options) {
|
26
30
|
options || (options = { });
|
@@ -30,71 +34,64 @@
|
|
30
34
|
};
|
31
35
|
|
32
36
|
extend(fabric.StaticCanvas.prototype, fabric.Observable);
|
37
|
+
extend(fabric.StaticCanvas.prototype, fabric.Collection);
|
38
|
+
extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter);
|
33
39
|
|
34
|
-
extend(fabric.StaticCanvas.prototype, /** @
|
40
|
+
extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {
|
35
41
|
|
36
42
|
/**
|
37
43
|
* Background color of canvas instance
|
38
|
-
* @property
|
39
44
|
* @type String
|
40
45
|
*/
|
41
46
|
backgroundColor: '',
|
42
47
|
|
43
48
|
/**
|
44
49
|
* Background image of canvas instance
|
45
|
-
* Should be set via
|
46
|
-
* @property
|
50
|
+
* Should be set via {@link fabric.StaticCanvas#setBackgroundImage}
|
47
51
|
* @type String
|
48
52
|
*/
|
49
53
|
backgroundImage: '',
|
50
54
|
|
51
55
|
/**
|
52
56
|
* Opacity of the background image of the canvas instance
|
53
|
-
* @property
|
54
57
|
* @type Float
|
55
58
|
*/
|
56
|
-
backgroundImageOpacity: 1
|
59
|
+
backgroundImageOpacity: 1,
|
57
60
|
|
58
61
|
/**
|
59
62
|
* Indicates whether the background image should be stretched to fit the
|
60
63
|
* dimensions of the canvas instance.
|
61
|
-
* @property
|
62
64
|
* @type Boolean
|
63
65
|
*/
|
64
66
|
backgroundImageStretch: true,
|
65
67
|
|
66
68
|
/**
|
67
69
|
* Overlay image of canvas instance
|
68
|
-
* Should be set via
|
69
|
-
* @property
|
70
|
+
* Should be set via {@link fabric.StaticCanvas#setOverlayImage}
|
70
71
|
* @type String
|
71
72
|
*/
|
72
73
|
overlayImage: '',
|
73
74
|
|
74
75
|
/**
|
75
76
|
* Left offset of overlay image (if present)
|
76
|
-
* @property
|
77
77
|
* @type Number
|
78
78
|
*/
|
79
79
|
overlayImageLeft: 0,
|
80
80
|
|
81
81
|
/**
|
82
82
|
* Top offset of overlay image (if present)
|
83
|
-
* @property
|
84
83
|
* @type Number
|
85
84
|
*/
|
86
85
|
overlayImageTop: 0,
|
87
86
|
|
88
87
|
/**
|
89
88
|
* Indicates whether toObject/toDatalessObject should include default values
|
90
|
-
* @property
|
91
89
|
* @type Boolean
|
92
90
|
*/
|
93
91
|
includeDefaultValues: true,
|
94
92
|
|
95
93
|
/**
|
96
94
|
* Indicates whether objects' state should be saved
|
97
|
-
* @property
|
98
95
|
* @type Boolean
|
99
96
|
*/
|
100
97
|
stateful: true,
|
@@ -103,29 +100,25 @@
|
|
103
100
|
* Indicates whether {@link fabric.Canvas.prototype.add} should also re-render canvas.
|
104
101
|
* Disabling this option could give a great performance boost when adding a lot of objects to canvas at once
|
105
102
|
* (followed by a manual rendering after addition)
|
106
|
-
* @property
|
107
103
|
* @type Boolean
|
108
104
|
*/
|
109
105
|
renderOnAddition: true,
|
110
106
|
|
111
107
|
/**
|
112
108
|
* Function that determines clipping of entire canvas area
|
113
|
-
* Being passed context as first argument. See clipping canvas area in https://github.com/kangax/fabric.js/wiki/FAQ
|
114
|
-
* @property
|
109
|
+
* Being passed context as first argument. See clipping canvas area in {@link https://github.com/kangax/fabric.js/wiki/FAQ}
|
115
110
|
* @type Function
|
116
111
|
*/
|
117
112
|
clipTo: null,
|
118
113
|
|
119
114
|
/**
|
120
115
|
* Indicates whether object controls (borders/controls) are rendered above overlay image
|
121
|
-
* @property
|
122
116
|
* @type Boolean
|
123
117
|
*/
|
124
118
|
controlsAboveOverlay: false,
|
125
119
|
|
126
120
|
/**
|
127
121
|
* Callback; invoked right before object is about to be scaled/rotated
|
128
|
-
* @method onBeforeScaleRotate
|
129
122
|
* @param {fabric.Object} target Object that's about to be scaled/rotated
|
130
123
|
*/
|
131
124
|
onBeforeScaleRotate: function () {
|
@@ -133,7 +126,6 @@
|
|
133
126
|
},
|
134
127
|
|
135
128
|
/**
|
136
|
-
* @method _initStatic
|
137
129
|
* @private
|
138
130
|
*/
|
139
131
|
_initStatic: function(el, options) {
|
@@ -157,7 +149,6 @@
|
|
157
149
|
/**
|
158
150
|
* Calculates canvas element offset relative to the document
|
159
151
|
* This method is also attached as "resize" event handler of window
|
160
|
-
* @method calcOffset
|
161
152
|
* @return {fabric.Canvas} instance
|
162
153
|
* @chainable
|
163
154
|
*/
|
@@ -168,7 +159,6 @@
|
|
168
159
|
|
169
160
|
/**
|
170
161
|
* Sets overlay image for this canvas
|
171
|
-
* @method setOverlayImage
|
172
162
|
* @param {String} url url of an image to set overlay to
|
173
163
|
* @param {Function} callback callback to invoke when image is loaded and set as an overlay
|
174
164
|
* @param {Object} [options] optional options to set for the overlay image
|
@@ -192,7 +182,6 @@
|
|
192
182
|
|
193
183
|
/**
|
194
184
|
* Sets background image for this canvas
|
195
|
-
* @method setBackgroundImage
|
196
185
|
* @param {String} url url of an image to set background to
|
197
186
|
* @param {Function} callback callback to invoke when image is loaded and set as background
|
198
187
|
* @param {Object} [options] optional options to set for the background image
|
@@ -216,7 +205,6 @@
|
|
216
205
|
|
217
206
|
/**
|
218
207
|
* Sets background color for this canvas
|
219
|
-
* @method setBackgroundColor
|
220
208
|
* @param {String|fabric.Pattern} Color of pattern to set background color to
|
221
209
|
* @param {Function} callback callback to invoke when background color is set
|
222
210
|
* @return {fabric.Canvas} thisArg
|
@@ -243,7 +231,6 @@
|
|
243
231
|
|
244
232
|
/**
|
245
233
|
* @private
|
246
|
-
* @method _createCanvasElement
|
247
234
|
*/
|
248
235
|
_createCanvasElement: function() {
|
249
236
|
var element = fabric.document.createElement('canvas');
|
@@ -258,7 +245,7 @@
|
|
258
245
|
},
|
259
246
|
|
260
247
|
/**
|
261
|
-
* @
|
248
|
+
* @private
|
262
249
|
* @param {HTMLElement} element
|
263
250
|
*/
|
264
251
|
_initCanvasElement: function(element) {
|
@@ -270,7 +257,7 @@
|
|
270
257
|
},
|
271
258
|
|
272
259
|
/**
|
273
|
-
* @
|
260
|
+
* @private
|
274
261
|
* @param {Object} [options]
|
275
262
|
*/
|
276
263
|
_initOptions: function (options) {
|
@@ -289,7 +276,7 @@
|
|
289
276
|
|
290
277
|
/**
|
291
278
|
* Creates a bottom canvas
|
292
|
-
* @
|
279
|
+
* @private
|
293
280
|
*/
|
294
281
|
_createLowerCanvas: function (canvasEl) {
|
295
282
|
this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement();
|
@@ -306,7 +293,6 @@
|
|
306
293
|
|
307
294
|
/**
|
308
295
|
* Returns canvas width (in px)
|
309
|
-
* @method getWidth
|
310
296
|
* @return {Number}
|
311
297
|
*/
|
312
298
|
getWidth: function () {
|
@@ -315,7 +301,6 @@
|
|
315
301
|
|
316
302
|
/**
|
317
303
|
* Returns canvas height (in px)
|
318
|
-
* @method getHeight
|
319
304
|
* @return {Number}
|
320
305
|
*/
|
321
306
|
getHeight: function () {
|
@@ -324,7 +309,6 @@
|
|
324
309
|
|
325
310
|
/**
|
326
311
|
* Sets width of this canvas instance
|
327
|
-
* @method setWidth
|
328
312
|
* @param {Number} width value to set width to
|
329
313
|
* @return {fabric.Canvas} instance
|
330
314
|
* @chainable true
|
@@ -335,7 +319,6 @@
|
|
335
319
|
|
336
320
|
/**
|
337
321
|
* Sets height of this canvas instance
|
338
|
-
* @method setHeight
|
339
322
|
* @param {Number} height value to set height to
|
340
323
|
* @return {fabric.Canvas} instance
|
341
324
|
* @chainable true
|
@@ -346,7 +329,6 @@
|
|
346
329
|
|
347
330
|
/**
|
348
331
|
* Sets dimensions (width, height) of this canvas instance
|
349
|
-
* @method setDimensions
|
350
332
|
* @param {Object} dimensions
|
351
333
|
* @return {fabric.Canvas} thisArg
|
352
334
|
* @chainable
|
@@ -361,7 +343,6 @@
|
|
361
343
|
/**
|
362
344
|
* Helper for setting width/height
|
363
345
|
* @private
|
364
|
-
* @method _setDimensions
|
365
346
|
* @param {String} prop property (width|height)
|
366
347
|
* @param {Number} value value to set property to
|
367
348
|
* @return {fabric.Canvas} instance
|
@@ -394,7 +375,6 @@
|
|
394
375
|
|
395
376
|
/**
|
396
377
|
* Returns <canvas> element corresponding to this instance
|
397
|
-
* @method getElement
|
398
378
|
* @return {HTMLCanvasElement}
|
399
379
|
*/
|
400
380
|
getElement: function () {
|
@@ -403,7 +383,6 @@
|
|
403
383
|
|
404
384
|
/**
|
405
385
|
* Returns currently selected object, if any
|
406
|
-
* @method getActiveObject
|
407
386
|
* @return {fabric.Object}
|
408
387
|
*/
|
409
388
|
getActiveObject: function() {
|
@@ -412,7 +391,6 @@
|
|
412
391
|
|
413
392
|
/**
|
414
393
|
* Returns currently selected group of object, if any
|
415
|
-
* @method getActiveGroup
|
416
394
|
* @return {fabric.Group}
|
417
395
|
*/
|
418
396
|
getActiveGroup: function() {
|
@@ -440,28 +418,10 @@
|
|
440
418
|
}
|
441
419
|
},
|
442
420
|
|
443
|
-
/**
|
444
|
-
* Adds objects to canvas, then renders canvas (if `renderOnAddition` is not `false`).
|
445
|
-
* Objects should be instances of (or inherit from) fabric.Object
|
446
|
-
* @method add
|
447
|
-
* @param [...] Zero or more fabric instances
|
448
|
-
* @return {fabric.Canvas} thisArg
|
449
|
-
* @chainable
|
450
|
-
*/
|
451
|
-
add: function () {
|
452
|
-
this._objects.push.apply(this._objects, arguments);
|
453
|
-
for (var i = arguments.length; i--; ) {
|
454
|
-
this._initObject(arguments[i]);
|
455
|
-
}
|
456
|
-
this.renderOnAddition && this.renderAll();
|
457
|
-
return this;
|
458
|
-
},
|
459
|
-
|
460
421
|
/**
|
461
422
|
* @private
|
462
|
-
* @method _initObject
|
463
423
|
*/
|
464
|
-
|
424
|
+
_onObjectAdded: function(obj) {
|
465
425
|
this.stateful && obj.setupState();
|
466
426
|
obj.setCoords();
|
467
427
|
obj.canvas = this;
|
@@ -470,30 +430,15 @@
|
|
470
430
|
},
|
471
431
|
|
472
432
|
/**
|
473
|
-
*
|
474
|
-
* An object should be an instance of (or inherit from) fabric.Object
|
475
|
-
* @method insertAt
|
476
|
-
* @param object {Object} Object to insert
|
477
|
-
* @param index {Number} index to insert object at
|
478
|
-
* @param nonSplicing {Boolean} when `true`, no splicing (shifting) of objects occurs
|
479
|
-
* @return {fabric.Canvas} thisArg
|
480
|
-
* @chainable
|
433
|
+
* @private
|
481
434
|
*/
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
}
|
486
|
-
else {
|
487
|
-
this._objects.splice(index, 0, object);
|
488
|
-
}
|
489
|
-
this._initObject(object);
|
490
|
-
this.renderOnAddition && this.renderAll();
|
491
|
-
return this;
|
435
|
+
_onObjectRemoved: function(obj) {
|
436
|
+
this.fire('object:removed', { target: obj });
|
437
|
+
obj.fire('removed');
|
492
438
|
},
|
493
439
|
|
494
440
|
/**
|
495
441
|
* Returns an array of objects this instance has
|
496
|
-
* @method getObjects
|
497
442
|
* @return {Array}
|
498
443
|
*/
|
499
444
|
getObjects: function () {
|
@@ -502,7 +447,6 @@
|
|
502
447
|
|
503
448
|
/**
|
504
449
|
* Clears specified context of canvas element
|
505
|
-
* @method clearContext
|
506
450
|
* @param context {Object} ctx context to clear
|
507
451
|
* @return {fabric.Canvas} thisArg
|
508
452
|
* @chainable
|
@@ -514,7 +458,6 @@
|
|
514
458
|
|
515
459
|
/**
|
516
460
|
* Returns context of canvas where objects are drawn
|
517
|
-
* @method getContext
|
518
461
|
* @return {CanvasRenderingContext2D}
|
519
462
|
*/
|
520
463
|
getContext: function () {
|
@@ -523,7 +466,6 @@
|
|
523
466
|
|
524
467
|
/**
|
525
468
|
* Clears all contexts (background, main, top) of an instance
|
526
|
-
* @method clear
|
527
469
|
* @return {fabric.Canvas} thisArg
|
528
470
|
* @chainable
|
529
471
|
*/
|
@@ -532,6 +474,9 @@
|
|
532
474
|
if (this.discardActiveGroup) {
|
533
475
|
this.discardActiveGroup();
|
534
476
|
}
|
477
|
+
if (this.discardActiveObject) {
|
478
|
+
this.discardActiveObject();
|
479
|
+
}
|
535
480
|
this.clearContext(this.contextContainer);
|
536
481
|
if (this.contextTop) {
|
537
482
|
this.clearContext(this.contextTop);
|
@@ -543,7 +488,6 @@
|
|
543
488
|
|
544
489
|
/**
|
545
490
|
* Renders both the top canvas and the secondary container canvas.
|
546
|
-
* @method renderAll
|
547
491
|
* @param allOnTop {Boolean} optional Whether we want to force all images to be rendered on the top canvas
|
548
492
|
* @return {fabric.Canvas} instance
|
549
493
|
* @chainable
|
@@ -552,7 +496,7 @@
|
|
552
496
|
|
553
497
|
var canvasToDrawOn = this[(allOnTop === true && this.interactive) ? 'contextTop' : 'contextContainer'];
|
554
498
|
|
555
|
-
if (this.contextTop && this.selection) {
|
499
|
+
if (this.contextTop && this.selection && !this._groupSelector) {
|
556
500
|
this.clearContext(this.contextTop);
|
557
501
|
}
|
558
502
|
|
@@ -563,7 +507,7 @@
|
|
563
507
|
this.fire('before:render');
|
564
508
|
|
565
509
|
if (this.clipTo) {
|
566
|
-
|
510
|
+
fabric.util.clipContext(this, canvasToDrawOn);
|
567
511
|
}
|
568
512
|
|
569
513
|
if (this.backgroundColor) {
|
@@ -571,7 +515,11 @@
|
|
571
515
|
? this.backgroundColor.toLive(canvasToDrawOn)
|
572
516
|
: this.backgroundColor;
|
573
517
|
|
574
|
-
canvasToDrawOn.fillRect(
|
518
|
+
canvasToDrawOn.fillRect(
|
519
|
+
this.backgroundColor.offsetX || 0,
|
520
|
+
this.backgroundColor.offsetY || 0,
|
521
|
+
this.width,
|
522
|
+
this.height);
|
575
523
|
}
|
576
524
|
|
577
525
|
if (typeof this.backgroundImage === 'object') {
|
@@ -607,7 +555,7 @@
|
|
607
555
|
canvasToDrawOn.drawImage(this.overlayImage, this.overlayImageLeft, this.overlayImageTop);
|
608
556
|
}
|
609
557
|
|
610
|
-
if (this.controlsAboveOverlay) {
|
558
|
+
if (this.controlsAboveOverlay && this.interactive) {
|
611
559
|
this.drawControls(canvasToDrawOn);
|
612
560
|
}
|
613
561
|
|
@@ -618,18 +566,6 @@
|
|
618
566
|
|
619
567
|
/**
|
620
568
|
* @private
|
621
|
-
* @method _clipCanvas
|
622
|
-
*/
|
623
|
-
_clipCanvas: function(canvasToDrawOn) {
|
624
|
-
canvasToDrawOn.save();
|
625
|
-
canvasToDrawOn.beginPath();
|
626
|
-
this.clipTo(canvasToDrawOn);
|
627
|
-
canvasToDrawOn.clip();
|
628
|
-
},
|
629
|
-
|
630
|
-
/**
|
631
|
-
* @private
|
632
|
-
* @method _drawBackroundImage
|
633
569
|
*/
|
634
570
|
_drawBackroundImage: function(canvasToDrawOn) {
|
635
571
|
canvasToDrawOn.save();
|
@@ -647,7 +583,6 @@
|
|
647
583
|
/**
|
648
584
|
* Method to render only the top canvas.
|
649
585
|
* Also used to render the group selection box.
|
650
|
-
* @method renderTop
|
651
586
|
* @return {fabric.Canvas} thisArg
|
652
587
|
* @chainable
|
653
588
|
*/
|
@@ -676,143 +611,9 @@
|
|
676
611
|
return this;
|
677
612
|
},
|
678
613
|
|
679
|
-
/**
|
680
|
-
* Draws objects' controls (borders/controls)
|
681
|
-
* @method drawControls
|
682
|
-
* @param {Object} ctx context to render controls on
|
683
|
-
*/
|
684
|
-
drawControls: function(ctx) {
|
685
|
-
var activeGroup = this.getActiveGroup();
|
686
|
-
if (activeGroup) {
|
687
|
-
ctx.save();
|
688
|
-
fabric.Group.prototype.transform.call(activeGroup, ctx);
|
689
|
-
activeGroup.drawBorders(ctx).drawControls(ctx);
|
690
|
-
ctx.restore();
|
691
|
-
}
|
692
|
-
else {
|
693
|
-
for (var i = 0, len = this._objects.length; i < len; ++i) {
|
694
|
-
if (!this._objects[i] || !this._objects[i].active) continue;
|
695
|
-
|
696
|
-
ctx.save();
|
697
|
-
fabric.Object.prototype.transform.call(this._objects[i], ctx);
|
698
|
-
this._objects[i].drawBorders(ctx).drawControls(ctx);
|
699
|
-
ctx.restore();
|
700
|
-
|
701
|
-
this.lastRenderedObjectWithControlsAboveOverlay = this._objects[i];
|
702
|
-
}
|
703
|
-
}
|
704
|
-
},
|
705
|
-
|
706
|
-
/**
|
707
|
-
* Exports canvas element to a dataurl image.
|
708
|
-
* @method toDataURL
|
709
|
-
* @param {String} format the format of the output image. Either "jpeg" or "png".
|
710
|
-
* @param {Number} quality quality level (0..1)
|
711
|
-
* @return {String}
|
712
|
-
*/
|
713
|
-
toDataURL: function (format, quality) {
|
714
|
-
var canvasEl = this.upperCanvasEl || this.lowerCanvasEl;
|
715
|
-
|
716
|
-
this.renderAll(true);
|
717
|
-
var data = (fabric.StaticCanvas.supports('toDataURLWithQuality'))
|
718
|
-
? canvasEl.toDataURL('image/' + format, quality)
|
719
|
-
: canvasEl.toDataURL('image/' + format);
|
720
|
-
|
721
|
-
this.contextTop && this.clearContext(this.contextTop);
|
722
|
-
this.renderAll();
|
723
|
-
return data;
|
724
|
-
},
|
725
|
-
|
726
|
-
/**
|
727
|
-
* Exports canvas element to a dataurl image (allowing to change image size via multiplier).
|
728
|
-
* @method toDataURLWithMultiplier
|
729
|
-
* @param {String} format (png|jpeg)
|
730
|
-
* @param {Number} multiplier
|
731
|
-
* @param {Number} quality (0..1)
|
732
|
-
* @return {String}
|
733
|
-
*/
|
734
|
-
toDataURLWithMultiplier: function (format, multiplier, quality) {
|
735
|
-
|
736
|
-
var origWidth = this.getWidth(),
|
737
|
-
origHeight = this.getHeight(),
|
738
|
-
scaledWidth = origWidth * multiplier,
|
739
|
-
scaledHeight = origHeight * multiplier,
|
740
|
-
activeObject = this.getActiveObject(),
|
741
|
-
activeGroup = this.getActiveGroup(),
|
742
|
-
|
743
|
-
ctx = this.contextTop || this.contextContainer;
|
744
|
-
|
745
|
-
this.setWidth(scaledWidth).setHeight(scaledHeight);
|
746
|
-
ctx.scale(multiplier, multiplier);
|
747
|
-
|
748
|
-
if (activeGroup) {
|
749
|
-
// not removing group due to complications with restoring it with correct state afterwords
|
750
|
-
this._tempRemoveBordersControlsFromGroup(activeGroup);
|
751
|
-
}
|
752
|
-
else if (activeObject && this.deactivateAll) {
|
753
|
-
this.deactivateAll();
|
754
|
-
}
|
755
|
-
|
756
|
-
// restoring width, height for `renderAll` to draw
|
757
|
-
// background properly (while context is scaled)
|
758
|
-
this.width = origWidth;
|
759
|
-
this.height = origHeight;
|
760
|
-
|
761
|
-
this.renderAll(true);
|
762
|
-
|
763
|
-
var dataURL = this.toDataURL(format, quality);
|
764
|
-
|
765
|
-
ctx.scale(1 / multiplier, 1 / multiplier);
|
766
|
-
this.setWidth(origWidth).setHeight(origHeight);
|
767
|
-
|
768
|
-
if (activeGroup) {
|
769
|
-
this._restoreBordersControlsOnGroup(activeGroup);
|
770
|
-
}
|
771
|
-
else if (activeObject && this.setActiveObject) {
|
772
|
-
this.setActiveObject(activeObject);
|
773
|
-
}
|
774
|
-
|
775
|
-
this.contextTop && this.clearContext(this.contextTop);
|
776
|
-
this.renderAll();
|
777
|
-
|
778
|
-
return dataURL;
|
779
|
-
},
|
780
|
-
|
781
|
-
/**
|
782
|
-
* @private
|
783
|
-
* @method _tempRemoveBordersControlsFromGroup
|
784
|
-
*/
|
785
|
-
_tempRemoveBordersControlsFromGroup: function(group) {
|
786
|
-
group.origHasControls = group.hasControls;
|
787
|
-
group.origBorderColor = group.borderColor;
|
788
|
-
|
789
|
-
group.hasControls = true;
|
790
|
-
group.borderColor = 'rgba(0,0,0,0)';
|
791
|
-
|
792
|
-
group.forEachObject(function(o) {
|
793
|
-
o.origBorderColor = o.borderColor;
|
794
|
-
o.borderColor = 'rgba(0,0,0,0)';
|
795
|
-
});
|
796
|
-
},
|
797
|
-
|
798
|
-
/**
|
799
|
-
* @private
|
800
|
-
* @method _restoreBordersControlsOnGroup
|
801
|
-
*/
|
802
|
-
_restoreBordersControlsOnGroup: function(group) {
|
803
|
-
group.hideControls = group.origHideControls;
|
804
|
-
group.borderColor = group.origBorderColor;
|
805
|
-
|
806
|
-
group.forEachObject(function(o) {
|
807
|
-
o.borderColor = o.origBorderColor;
|
808
|
-
delete o.origBorderColor;
|
809
|
-
});
|
810
|
-
},
|
811
|
-
|
812
614
|
/**
|
813
615
|
* Returns coordinates of a center of canvas.
|
814
616
|
* Returned value is an object with top and left properties
|
815
|
-
* @method getCenter
|
816
617
|
* @return {Object} object with "top" and "left" number values
|
817
618
|
*/
|
818
619
|
getCenter: function () {
|
@@ -824,7 +625,6 @@
|
|
824
625
|
|
825
626
|
/**
|
826
627
|
* Centers object horizontally.
|
827
|
-
* @method centerObjectH
|
828
628
|
* @param {fabric.Object} object Object to center
|
829
629
|
* @return {fabric.Canvas} thisArg
|
830
630
|
*/
|
@@ -836,7 +636,6 @@
|
|
836
636
|
|
837
637
|
/**
|
838
638
|
* Centers object vertically.
|
839
|
-
* @method centerObjectH
|
840
639
|
* @param {fabric.Object} object Object to center
|
841
640
|
* @return {fabric.Canvas} thisArg
|
842
641
|
* @chainable
|
@@ -849,7 +648,6 @@
|
|
849
648
|
|
850
649
|
/**
|
851
650
|
* Centers object vertically and horizontally.
|
852
|
-
* @method centerObject
|
853
651
|
* @param {fabric.Object} object Object to center
|
854
652
|
* @return {fabric.Canvas} thisArg
|
855
653
|
* @chainable
|
@@ -860,7 +658,6 @@
|
|
860
658
|
|
861
659
|
/**
|
862
660
|
* Returs dataless JSON representation of canvas
|
863
|
-
* @method toDatalessJSON
|
864
661
|
* @param {Array} propertiesToInclude
|
865
662
|
* @return {String} json string
|
866
663
|
*/
|
@@ -870,7 +667,6 @@
|
|
870
667
|
|
871
668
|
/**
|
872
669
|
* Returns object representation of canvas
|
873
|
-
* @method toObject
|
874
670
|
* @param {Array} propertiesToInclude
|
875
671
|
* @return {Object} object representation of an instance
|
876
672
|
*/
|
@@ -880,7 +676,6 @@
|
|
880
676
|
|
881
677
|
/**
|
882
678
|
* Returns dataless object representation of canvas
|
883
|
-
* @method toDatalessObject
|
884
679
|
* @param {Array} propertiesToInclude
|
885
680
|
* @return {Object} object representation of an instance
|
886
681
|
*/
|
@@ -890,11 +685,15 @@
|
|
890
685
|
|
891
686
|
/**
|
892
687
|
* @private
|
893
|
-
* @method _toObjectMethod
|
894
688
|
*/
|
895
689
|
_toObjectMethod: function (methodName, propertiesToInclude) {
|
690
|
+
|
691
|
+
var activeGroup = this.getActiveGroup();
|
692
|
+
if (activeGroup) {
|
693
|
+
this.discardActiveGroup();
|
694
|
+
}
|
896
695
|
var data = {
|
897
|
-
objects: this.
|
696
|
+
objects: this.getObjects().map(function (instance) {
|
898
697
|
// TODO (kangax): figure out how to clean this up
|
899
698
|
var originalValue;
|
900
699
|
if (!this.includeDefaultValues) {
|
@@ -922,15 +721,19 @@
|
|
922
721
|
data.overlayImageTop = this.overlayImageTop;
|
923
722
|
}
|
924
723
|
fabric.util.populateWithProperties(this, data, propertiesToInclude);
|
724
|
+
if (activeGroup) {
|
725
|
+
this.setActiveGroup(new fabric.Group(activeGroup.getObjects()));
|
726
|
+
activeGroup.forEachObject(function(o) { o.set('active', true) });
|
727
|
+
}
|
925
728
|
return data;
|
926
729
|
},
|
927
730
|
|
731
|
+
/* _TO_SVG_START_ */
|
928
732
|
/**
|
929
733
|
* Returns SVG representation of canvas
|
930
734
|
* @function
|
931
|
-
* @
|
932
|
-
*
|
933
|
-
* will start the svg output directly at "<svg...")
|
735
|
+
* @param {Object} [options] Options for SVG output (suppressPreamble: true/false (if true xml tag is not included),
|
736
|
+
* viewBox: {x, y, width, height} to define the svg output viewBox)
|
934
737
|
* @return {String}
|
935
738
|
*/
|
936
739
|
toSVG: function(options) {
|
@@ -949,9 +752,10 @@
|
|
949
752
|
'xmlns="http://www.w3.org/2000/svg" ',
|
950
753
|
'xmlns:xlink="http://www.w3.org/1999/xlink" ',
|
951
754
|
'version="1.1" ',
|
952
|
-
'width="', this.width, '" ',
|
953
|
-
'height="', this.height, '" ',
|
954
|
-
(this.backgroundColor && !this.backgroundColor.source
|
755
|
+
'width="', (options.viewBox ? options.viewBox.width : this.width), '" ',
|
756
|
+
'height="', (options.viewBox ? options.viewBox.height : this.height), '" ',
|
757
|
+
(this.backgroundColor && !this.backgroundColor.source ? 'style="background-color: ' + this.backgroundColor +'" ' : null),
|
758
|
+
(options.viewBox ? 'viewBox="' + options.viewBox.x + ' ' + options.viewBox.y + ' ' + options.viewBox.width + ' ' + options.viewBox.height + '" ' : null),
|
955
759
|
'xml:space="preserve">',
|
956
760
|
'<desc>Created with Fabric.js ', fabric.version, '</desc>',
|
957
761
|
'<defs>', fabric.createSVGFontFacesMarkup(this.getObjects()), fabric.createSVGRefElementsMarkup(this), '</defs>'
|
@@ -990,26 +794,25 @@
|
|
990
794
|
);
|
991
795
|
}
|
992
796
|
|
797
|
+
var activeGroup = this.getActiveGroup();
|
798
|
+
if (activeGroup) {
|
799
|
+
this.discardActiveGroup();
|
800
|
+
}
|
993
801
|
for (var i = 0, objects = this.getObjects(), len = objects.length; i < len; i++) {
|
994
802
|
markup.push(objects[i].toSVG());
|
995
803
|
}
|
804
|
+
if (activeGroup) {
|
805
|
+
this.setActiveGroup(new fabric.Group(activeGroup.getObjects()));
|
806
|
+
activeGroup.forEachObject(function(o) { o.set('active', true) });
|
807
|
+
}
|
996
808
|
markup.push('</svg>');
|
997
809
|
|
998
810
|
return markup.join('');
|
999
811
|
},
|
1000
|
-
|
1001
|
-
/**
|
1002
|
-
* Returns true if canvas contains no objects
|
1003
|
-
* @method isEmpty
|
1004
|
-
* @return {Boolean} true if canvas is empty
|
1005
|
-
*/
|
1006
|
-
isEmpty: function () {
|
1007
|
-
return this._objects.length === 0;
|
1008
|
-
},
|
812
|
+
/* _TO_SVG_END_ */
|
1009
813
|
|
1010
814
|
/**
|
1011
815
|
* Removes an object from canvas and returns it
|
1012
|
-
* @method remove
|
1013
816
|
* @param object {Object} Object to remove
|
1014
817
|
* @return {Object} removed object
|
1015
818
|
*/
|
@@ -1021,22 +824,11 @@
|
|
1021
824
|
this.fire('selection:cleared');
|
1022
825
|
}
|
1023
826
|
|
1024
|
-
|
1025
|
-
var index = objects.indexOf(object);
|
1026
|
-
|
1027
|
-
// removing any object should fire "objct:removed" events
|
1028
|
-
if (index !== -1) {
|
1029
|
-
objects.splice(index,1);
|
1030
|
-
this.fire('object:removed', { target: object });
|
1031
|
-
}
|
1032
|
-
|
1033
|
-
this.renderAll();
|
1034
|
-
return object;
|
827
|
+
return fabric.Collection.remove.call(this, object);
|
1035
828
|
},
|
1036
829
|
|
1037
830
|
/**
|
1038
831
|
* Moves an object to the bottom of the stack of drawn objects
|
1039
|
-
* @method sendToBack
|
1040
832
|
* @param object {fabric.Object} Object to send to back
|
1041
833
|
* @return {fabric.Canvas} thisArg
|
1042
834
|
* @chainable
|
@@ -1044,12 +836,11 @@
|
|
1044
836
|
sendToBack: function (object) {
|
1045
837
|
removeFromArray(this._objects, object);
|
1046
838
|
this._objects.unshift(object);
|
1047
|
-
return this.renderAll();
|
839
|
+
return this.renderAll && this.renderAll();
|
1048
840
|
},
|
1049
841
|
|
1050
842
|
/**
|
1051
843
|
* Moves an object to the top of the stack of drawn objects
|
1052
|
-
* @method bringToFront
|
1053
844
|
* @param object {fabric.Object} Object to send
|
1054
845
|
* @return {fabric.Canvas} thisArg
|
1055
846
|
* @chainable
|
@@ -1057,147 +848,132 @@
|
|
1057
848
|
bringToFront: function (object) {
|
1058
849
|
removeFromArray(this._objects, object);
|
1059
850
|
this._objects.push(object);
|
1060
|
-
return this.renderAll();
|
851
|
+
return this.renderAll && this.renderAll();
|
1061
852
|
},
|
1062
853
|
|
1063
854
|
/**
|
1064
|
-
* Moves an object
|
1065
|
-
* @method sendBackwards
|
855
|
+
* Moves an object down in stack of drawn objects
|
1066
856
|
* @param object {fabric.Object} Object to send
|
857
|
+
* @param intersecting {Boolean} If `true`, send object behind next lower intersecting object
|
1067
858
|
* @return {fabric.Canvas} thisArg
|
1068
859
|
* @chainable
|
1069
860
|
*/
|
1070
|
-
sendBackwards: function (object) {
|
1071
|
-
var idx = this._objects.indexOf(object)
|
1072
|
-
nextIntersectingIdx = idx;
|
861
|
+
sendBackwards: function (object, intersecting) {
|
862
|
+
var idx = this._objects.indexOf(object);
|
1073
863
|
|
1074
864
|
// if object is not on the bottom of stack
|
1075
865
|
if (idx !== 0) {
|
866
|
+
var newIdx;
|
1076
867
|
|
1077
|
-
|
1078
|
-
|
868
|
+
if (intersecting) {
|
869
|
+
newIdx = idx;
|
870
|
+
|
871
|
+
// traverse down the stack looking for the nearest intersecting object
|
872
|
+
for (var i=idx-1; i>=0; --i) {
|
1079
873
|
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
874
|
+
var isIntersecting = object.intersectsWithObject(this._objects[i]) ||
|
875
|
+
object.isContainedWithinObject(this._objects[i]) ||
|
876
|
+
this._objects[i].isContainedWithinObject(object);
|
1083
877
|
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
878
|
+
if (isIntersecting) {
|
879
|
+
newIdx = i;
|
880
|
+
break;
|
881
|
+
}
|
1087
882
|
}
|
1088
883
|
}
|
884
|
+
else {
|
885
|
+
newIdx = idx-1;
|
886
|
+
}
|
887
|
+
|
1089
888
|
removeFromArray(this._objects, object);
|
1090
|
-
this._objects.splice(
|
889
|
+
this._objects.splice(newIdx, 0, object);
|
890
|
+
this.renderAll && this.renderAll();
|
1091
891
|
}
|
1092
|
-
return this
|
892
|
+
return this;
|
1093
893
|
},
|
1094
894
|
|
1095
895
|
/**
|
1096
|
-
* Moves an object
|
1097
|
-
* @method bringForward
|
896
|
+
* Moves an object up in stack of drawn objects
|
1098
897
|
* @param object {fabric.Object} Object to send
|
898
|
+
* @param intersecting {Boolean} If `true`, send object in front of next upper intersecting object
|
1099
899
|
* @return {fabric.Canvas} thisArg
|
1100
900
|
* @chainable
|
1101
901
|
*/
|
1102
|
-
bringForward: function (object) {
|
1103
|
-
var
|
1104
|
-
idx = objects.indexOf(object),
|
1105
|
-
nextIntersectingIdx = idx;
|
1106
|
-
|
902
|
+
bringForward: function (object, intersecting) {
|
903
|
+
var idx = this._objects.indexOf(object);
|
1107
904
|
|
1108
905
|
// if object is not on top of stack (last item in an array)
|
1109
|
-
if (idx !==
|
906
|
+
if (idx !== this._objects.length-1) {
|
907
|
+
var newIdx;
|
908
|
+
|
909
|
+
if (intersecting) {
|
910
|
+
newIdx = idx;
|
1110
911
|
|
1111
|
-
|
1112
|
-
|
912
|
+
// traverse up the stack looking for the nearest intersecting object
|
913
|
+
for (var i = idx + 1; i < this._objects.length; ++i) {
|
1113
914
|
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
915
|
+
var isIntersecting = object.intersectsWithObject(this._objects[i]) ||
|
916
|
+
object.isContainedWithinObject(this._objects[i]) ||
|
917
|
+
this._objects[i].isContainedWithinObject(object);
|
1117
918
|
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
919
|
+
if (isIntersecting) {
|
920
|
+
newIdx = i;
|
921
|
+
break;
|
922
|
+
}
|
1121
923
|
}
|
1122
924
|
}
|
1123
|
-
|
1124
|
-
|
925
|
+
else {
|
926
|
+
newIdx = idx+1;
|
927
|
+
}
|
928
|
+
|
929
|
+
removeFromArray(this._objects, object);
|
930
|
+
this._objects.splice(newIdx, 0, object);
|
931
|
+
this.renderAll && this.renderAll();
|
1125
932
|
}
|
1126
|
-
this
|
1127
|
-
},
|
1128
|
-
|
1129
|
-
/**
|
1130
|
-
* Returns object at specified index
|
1131
|
-
* @method item
|
1132
|
-
* @param {Number} index
|
1133
|
-
* @return {fabric.Object}
|
1134
|
-
*/
|
1135
|
-
item: function (index) {
|
1136
|
-
return this.getObjects()[index];
|
1137
|
-
},
|
1138
|
-
|
1139
|
-
/**
|
1140
|
-
* Returns number representation of an instance complexity
|
1141
|
-
* @method complexity
|
1142
|
-
* @return {Number} complexity
|
1143
|
-
*/
|
1144
|
-
complexity: function () {
|
1145
|
-
return this.getObjects().reduce(function (memo, current) {
|
1146
|
-
memo += current.complexity ? current.complexity() : 0;
|
1147
|
-
return memo;
|
1148
|
-
}, 0);
|
933
|
+
return this;
|
1149
934
|
},
|
1150
935
|
|
1151
936
|
/**
|
1152
|
-
*
|
1153
|
-
* @
|
937
|
+
* Moves an object to specified level in stack of drawn objects
|
938
|
+
* @param object {fabric.Object} Object to send
|
939
|
+
* @param {Number} index Position to move to
|
1154
940
|
* @return {fabric.Canvas} thisArg
|
941
|
+
* @chainable
|
1155
942
|
*/
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
callback.call(context, objects[i], i, objects);
|
1161
|
-
}
|
1162
|
-
return this;
|
943
|
+
moveTo: function (object, index) {
|
944
|
+
removeFromArray(this._objects, object);
|
945
|
+
this._objects.splice(index, 0, object);
|
946
|
+
return this.renderAll && this.renderAll();
|
1163
947
|
},
|
1164
948
|
|
1165
949
|
/**
|
1166
950
|
* Clears a canvas element and removes all event handlers.
|
1167
|
-
* @method dispose
|
1168
951
|
* @return {fabric.Canvas} thisArg
|
1169
952
|
* @chainable
|
1170
953
|
*/
|
1171
954
|
dispose: function () {
|
1172
955
|
this.clear();
|
1173
|
-
|
956
|
+
|
957
|
+
if (!this.interactive) return this;
|
958
|
+
|
959
|
+
if (fabric.isTouchSupported) {
|
960
|
+
removeListener(this.upperCanvasEl, 'touchstart', this._onMouseDown);
|
961
|
+
removeListener(this.upperCanvasEl, 'touchmove', this._onMouseMove);
|
962
|
+
if (typeof Event !== 'undefined' && 'remove' in Event) {
|
963
|
+
Event.remove(this.upperCanvasEl, 'gesture', this._onGesture);
|
964
|
+
}
|
965
|
+
}
|
966
|
+
else {
|
1174
967
|
removeListener(this.upperCanvasEl, 'mousedown', this._onMouseDown);
|
1175
968
|
removeListener(this.upperCanvasEl, 'mousemove', this._onMouseMove);
|
1176
969
|
removeListener(fabric.window, 'resize', this._onResize);
|
1177
970
|
}
|
1178
971
|
return this;
|
1179
|
-
},
|
1180
|
-
|
1181
|
-
/**
|
1182
|
-
* @private
|
1183
|
-
* @method _resizeImageToFit
|
1184
|
-
* @param {HTMLImageElement} imgEl
|
1185
|
-
*/
|
1186
|
-
_resizeImageToFit: function (imgEl) {
|
1187
|
-
|
1188
|
-
var imageWidth = imgEl.width || imgEl.offsetWidth,
|
1189
|
-
widthScaleFactor = this.getWidth() / imageWidth;
|
1190
|
-
|
1191
|
-
// scale image down so that it has original dimensions when printed in large resolution
|
1192
|
-
if (imageWidth) {
|
1193
|
-
imgEl.width = imageWidth * widthScaleFactor;
|
1194
|
-
}
|
1195
972
|
}
|
1196
973
|
});
|
1197
974
|
|
1198
975
|
/**
|
1199
976
|
* Returns a string representation of an instance
|
1200
|
-
* @method toString
|
1201
977
|
* @return {String} string representation of an instance
|
1202
978
|
*/
|
1203
979
|
fabric.StaticCanvas.prototype.toString = function () { // Assign explicitly since `extend` doesn't take care of DontEnum bug yet
|
@@ -1205,11 +981,10 @@
|
|
1205
981
|
'{ objects: ' + this.getObjects().length + ' }>';
|
1206
982
|
};
|
1207
983
|
|
1208
|
-
extend(fabric.StaticCanvas, /** @
|
984
|
+
extend(fabric.StaticCanvas, /** @lends fabric.StaticCanvas */ {
|
1209
985
|
|
1210
986
|
/**
|
1211
987
|
* @static
|
1212
|
-
* @property EMPTY_JSON
|
1213
988
|
* @type String
|
1214
989
|
*/
|
1215
990
|
EMPTY_JSON: '{"objects": [], "background": "white"}',
|
@@ -1217,7 +992,6 @@
|
|
1217
992
|
/**
|
1218
993
|
* Takes <canvas> element and transforms its data in such way that it becomes grayscale
|
1219
994
|
* @static
|
1220
|
-
* @method toGrayscale
|
1221
995
|
* @param {HTMLCanvasElement} canvasEl
|
1222
996
|
*/
|
1223
997
|
toGrayscale: function (canvasEl) {
|
@@ -1247,9 +1021,8 @@
|
|
1247
1021
|
* Provides a way to check support of some of the canvas methods
|
1248
1022
|
* (either those of HTMLCanvasElement itself, or rendering context)
|
1249
1023
|
*
|
1250
|
-
* @method supports
|
1251
1024
|
* @param methodName {String} Method to check support for;
|
1252
|
-
* Could be one of "getImageData", "toDataURL" or "
|
1025
|
+
* Could be one of "getImageData", "toDataURL", "toDataURLWithQuality" or "setLineDash"
|
1253
1026
|
* @return {Boolean | null} `true` if method is supported (or at least exists),
|
1254
1027
|
* `null` if canvas element or context can not be initialized
|
1255
1028
|
*/
|
@@ -1270,6 +1043,9 @@
|
|
1270
1043
|
case 'getImageData':
|
1271
1044
|
return typeof ctx.getImageData !== 'undefined';
|
1272
1045
|
|
1046
|
+
case 'setLineDash':
|
1047
|
+
return typeof ctx.setLineDash !== 'undefined';
|
1048
|
+
|
1273
1049
|
case 'toDataURL':
|
1274
1050
|
return typeof el.toDataURL !== 'undefined';
|
1275
1051
|
|
@@ -1290,7 +1066,7 @@
|
|
1290
1066
|
/**
|
1291
1067
|
* Returs JSON representation of canvas
|
1292
1068
|
* @function
|
1293
|
-
* @
|
1069
|
+
* @param {Array} propertiesToInclude
|
1294
1070
|
* @return {String} json string
|
1295
1071
|
*/
|
1296
1072
|
fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject;
|