fabric-rails 1.0.12 → 1.0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +16 -0
- data/README.md +1 -1
- data/lib/fabric/rails/version.rb +2 -2
- data/vendor/assets/javascripts/event.js +1909 -0
- data/vendor/assets/javascripts/fabric.js +64 -16464
- data/vendor/assets/javascripts/fabric/HEADER.js +31 -0
- data/vendor/assets/javascripts/fabric/canvas.class.js +1007 -0
- data/vendor/assets/javascripts/fabric/canvas_animation.mixin.js +113 -0
- data/vendor/assets/javascripts/fabric/canvas_events.mixin.js +482 -0
- data/vendor/assets/javascripts/fabric/canvas_gestures.mixin.js +79 -0
- data/vendor/assets/javascripts/fabric/canvas_serialization.mixin.js +311 -0
- data/vendor/assets/javascripts/fabric/circle.class.js +182 -0
- data/vendor/assets/javascripts/fabric/color.class.js +284 -0
- data/vendor/assets/javascripts/fabric/ellipse.class.js +169 -0
- data/vendor/assets/javascripts/fabric/freedrawing.class.js +256 -0
- data/vendor/assets/javascripts/fabric/gradient.class.js +211 -0
- data/vendor/assets/javascripts/fabric/group.class.js +556 -0
- data/vendor/assets/javascripts/fabric/image.class.js +418 -0
- data/vendor/assets/javascripts/fabric/image_filters.js +809 -0
- data/vendor/assets/javascripts/fabric/intersection.class.js +178 -0
- data/vendor/assets/javascripts/fabric/line.class.js +188 -0
- data/vendor/assets/javascripts/fabric/log.js +26 -0
- data/vendor/assets/javascripts/fabric/node.js +149 -0
- data/vendor/assets/javascripts/fabric/object.class.js +1068 -0
- data/vendor/assets/javascripts/fabric/object_geometry.mixin.js +308 -0
- data/vendor/assets/javascripts/fabric/object_interactivity.mixin.js +496 -0
- data/vendor/assets/javascripts/fabric/object_origin.mixin.js +207 -0
- data/vendor/assets/javascripts/fabric/object_straightening.mixin.js +94 -0
- data/vendor/assets/javascripts/fabric/observable.mixin.js +91 -0
- data/vendor/assets/javascripts/fabric/parser.js +750 -0
- data/vendor/assets/javascripts/fabric/path.class.js +794 -0
- data/vendor/assets/javascripts/fabric/path_group.class.js +240 -0
- data/vendor/assets/javascripts/fabric/pattern.class.js +69 -0
- data/vendor/assets/javascripts/fabric/point.class.js +327 -0
- data/vendor/assets/javascripts/fabric/polygon.class.js +184 -0
- data/vendor/assets/javascripts/fabric/polyline.class.js +157 -0
- data/vendor/assets/javascripts/fabric/rect.class.js +298 -0
- data/vendor/assets/javascripts/fabric/scout.js +45 -0
- data/vendor/assets/javascripts/fabric/shadow.class.js +70 -0
- data/vendor/assets/javascripts/fabric/stateful.js +88 -0
- data/vendor/assets/javascripts/fabric/static_canvas.class.js +1298 -0
- data/vendor/assets/javascripts/fabric/text.class.js +934 -0
- data/vendor/assets/javascripts/fabric/triangle.class.js +108 -0
- data/vendor/assets/javascripts/fabric/util/anim_ease.js +360 -0
- data/vendor/assets/javascripts/fabric/util/dom_event.js +237 -0
- data/vendor/assets/javascripts/fabric/util/dom_misc.js +245 -0
- data/vendor/assets/javascripts/fabric/util/dom_request.js +72 -0
- data/vendor/assets/javascripts/fabric/util/dom_style.js +71 -0
- data/vendor/assets/javascripts/fabric/util/lang_array.js +250 -0
- data/vendor/assets/javascripts/fabric/util/lang_class.js +97 -0
- data/vendor/assets/javascripts/fabric/util/lang_function.js +35 -0
- data/vendor/assets/javascripts/fabric/util/lang_object.js +34 -0
- data/vendor/assets/javascripts/fabric/util/lang_string.js +60 -0
- data/vendor/assets/javascripts/fabric/util/misc.js +406 -0
- data/vendor/assets/javascripts/json2.js +491 -0
- metadata +53 -2
@@ -0,0 +1,79 @@
|
|
1
|
+
(function() {
|
2
|
+
|
3
|
+
var degreesToRadians = fabric.util.degreesToRadians,
|
4
|
+
radiansToDegrees = fabric.util.radiansToDegrees;
|
5
|
+
|
6
|
+
fabric.util.object.extend(fabric.Canvas.prototype, /** @scope fabric.Canvas.prototype */ {
|
7
|
+
|
8
|
+
/**
|
9
|
+
* Method that defines actions when an Event.js gesture is detected on an object. Currently only supports
|
10
|
+
* 2 finger gestures.
|
11
|
+
*
|
12
|
+
* @method __onTransformGesture
|
13
|
+
* @param e Event object by Event.js
|
14
|
+
* @param self Event proxy object by Event.js
|
15
|
+
*/
|
16
|
+
__onTransformGesture: function(e, self) {
|
17
|
+
|
18
|
+
if (this.isDrawingMode || e.touches.length !== 2 || 'gesture' !== self.gesture) {
|
19
|
+
return;
|
20
|
+
}
|
21
|
+
|
22
|
+
var target = this.findTarget(e);
|
23
|
+
if ('undefined' !== typeof target) {
|
24
|
+
this.onBeforeScaleRotate(target);
|
25
|
+
this._rotateObjectByAngle(self.rotation);
|
26
|
+
this._scaleObjectBy(self.scale);
|
27
|
+
}
|
28
|
+
|
29
|
+
this.fire('touch:gesture', {target: target, e: e, self: self});
|
30
|
+
},
|
31
|
+
|
32
|
+
/**
|
33
|
+
* Scales an object by a factor
|
34
|
+
* @param s {Number} The scale factor to apply to the current scale level
|
35
|
+
* @param by {String} Either 'x' or 'y' - specifies dimension constraint by which to scale an object.
|
36
|
+
* When not provided, an object is scaled by both dimensions equally
|
37
|
+
*/
|
38
|
+
_scaleObjectBy: function(s, by) {
|
39
|
+
var t = this._currentTransform,
|
40
|
+
target = t.target;
|
41
|
+
|
42
|
+
var lockScalingX = target.get('lockScalingX'),
|
43
|
+
lockScalingY = target.get('lockScalingY');
|
44
|
+
|
45
|
+
if (lockScalingX && lockScalingY)
|
46
|
+
return;
|
47
|
+
|
48
|
+
target._scaling = true;
|
49
|
+
|
50
|
+
if (!by) {
|
51
|
+
if (!lockScalingX) {
|
52
|
+
target.set('scaleX', t.scaleX * s);
|
53
|
+
}
|
54
|
+
if (!lockScalingY) {
|
55
|
+
target.set('scaleY', t.scaleY * s);
|
56
|
+
}
|
57
|
+
}
|
58
|
+
else if (by === 'x' && !target.get('lockUniScaling')) {
|
59
|
+
lockScalingX || target.set('scaleX', t.scaleX * s);
|
60
|
+
}
|
61
|
+
else if (by === 'y' && !target.get('lockUniScaling')) {
|
62
|
+
lockScalingY || target.set('scaleY', t.scaleY * s);
|
63
|
+
}
|
64
|
+
},
|
65
|
+
|
66
|
+
/**
|
67
|
+
* Rotates object by an angle
|
68
|
+
* @param curAngle {Number} the angle of rotation in degrees
|
69
|
+
*/
|
70
|
+
_rotateObjectByAngle: function(curAngle) {
|
71
|
+
var t = this._currentTransform;
|
72
|
+
|
73
|
+
if (t.target.get('lockRotation'))
|
74
|
+
return;
|
75
|
+
|
76
|
+
t.target.angle = radiansToDegrees(degreesToRadians(curAngle) + t.theta);
|
77
|
+
}
|
78
|
+
});
|
79
|
+
})();
|
@@ -0,0 +1,311 @@
|
|
1
|
+
fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @scope fabric.StaticCanvas.prototype */ {
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Populates canvas with data from the specified dataless JSON
|
5
|
+
* JSON format must conform to the one of `fabric.Canvas#toDatalessJSON`
|
6
|
+
* @method loadFromDatalessJSON
|
7
|
+
* @param {String|Object} json JSON string or object
|
8
|
+
* @param {Function} callback Callback, invoked when json is parsed
|
9
|
+
* and corresponding objects (e.g: fabric.Image)
|
10
|
+
* are initialized
|
11
|
+
* @return {fabric.Canvas} instance
|
12
|
+
* @chainable
|
13
|
+
*/
|
14
|
+
loadFromDatalessJSON: function (json, callback) {
|
15
|
+
|
16
|
+
if (!json) return;
|
17
|
+
|
18
|
+
// serialize if it wasn't already
|
19
|
+
var serialized = (typeof json === 'string')
|
20
|
+
? JSON.parse(json)
|
21
|
+
: json;
|
22
|
+
|
23
|
+
if (!serialized || (serialized && !serialized.objects)) return;
|
24
|
+
|
25
|
+
this.clear();
|
26
|
+
|
27
|
+
var _this = this;
|
28
|
+
this._enlivenDatalessObjects(serialized.objects, function() {
|
29
|
+
_this._setBgOverlayImages(serialized, callback);
|
30
|
+
});
|
31
|
+
},
|
32
|
+
|
33
|
+
/**
|
34
|
+
* @method _enlivenDatalessObjects
|
35
|
+
* @param {Array} objects
|
36
|
+
* @param {Function} callback
|
37
|
+
*/
|
38
|
+
_enlivenDatalessObjects: function (objects, callback) {
|
39
|
+
var _this = this,
|
40
|
+
numLoadedObjects = 0,
|
41
|
+
numTotalObjects = objects.length;
|
42
|
+
|
43
|
+
/** @ignore */
|
44
|
+
function onObjectLoaded(object, index) {
|
45
|
+
_this.insertAt(object, index, true);
|
46
|
+
object.setCoords();
|
47
|
+
if (++numLoadedObjects === numTotalObjects) {
|
48
|
+
callback && callback();
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
/** @ignore */
|
53
|
+
function loadObject(obj, index) {
|
54
|
+
|
55
|
+
var pathProp = obj.paths ? 'paths' : 'path';
|
56
|
+
var path = obj[pathProp];
|
57
|
+
|
58
|
+
delete obj[pathProp];
|
59
|
+
|
60
|
+
if (typeof path !== 'string') {
|
61
|
+
if (obj.type === 'image' || obj.type === 'group') {
|
62
|
+
fabric[fabric.util.string.capitalize(obj.type)].fromObject(obj, function (o) {
|
63
|
+
onObjectLoaded(o, index);
|
64
|
+
});
|
65
|
+
}
|
66
|
+
else {
|
67
|
+
var klass = fabric[fabric.util.string.camelize(fabric.util.string.capitalize(obj.type))];
|
68
|
+
if (!klass || !klass.fromObject) return;
|
69
|
+
|
70
|
+
// restore path
|
71
|
+
if (path) {
|
72
|
+
obj[pathProp] = path;
|
73
|
+
}
|
74
|
+
onObjectLoaded(klass.fromObject(obj), index);
|
75
|
+
}
|
76
|
+
}
|
77
|
+
else {
|
78
|
+
if (obj.type === 'image') {
|
79
|
+
fabric.util.loadImage(path, function (image) {
|
80
|
+
var oImg = new fabric.Image(image);
|
81
|
+
|
82
|
+
oImg.setSourcePath(path);
|
83
|
+
|
84
|
+
fabric.util.object.extend(oImg, obj);
|
85
|
+
oImg.setAngle(obj.angle);
|
86
|
+
|
87
|
+
onObjectLoaded(oImg, index);
|
88
|
+
});
|
89
|
+
}
|
90
|
+
else if (obj.type === 'text') {
|
91
|
+
|
92
|
+
if (obj.useNative) {
|
93
|
+
onObjectLoaded(fabric.Text.fromObject(obj), index);
|
94
|
+
}
|
95
|
+
else {
|
96
|
+
obj.path = path;
|
97
|
+
var object = fabric.Text.fromObject(obj);
|
98
|
+
/** @ignore */
|
99
|
+
var onscriptload = function () {
|
100
|
+
// TODO (kangax): find out why Opera refuses to work without this timeout
|
101
|
+
if (Object.prototype.toString.call(fabric.window.opera) === '[object Opera]') {
|
102
|
+
setTimeout(function () {
|
103
|
+
onObjectLoaded(object, index);
|
104
|
+
}, 500);
|
105
|
+
}
|
106
|
+
else {
|
107
|
+
onObjectLoaded(object, index);
|
108
|
+
}
|
109
|
+
};
|
110
|
+
|
111
|
+
fabric.util.getScript(path, onscriptload);
|
112
|
+
}
|
113
|
+
}
|
114
|
+
else {
|
115
|
+
fabric.loadSVGFromURL(path, function (elements) {
|
116
|
+
var object = fabric.util.groupSVGElements(elements, obj, path);
|
117
|
+
|
118
|
+
// copy parameters from serialied json to object (left, top, scaleX, scaleY, etc.)
|
119
|
+
// skip this step if an object is a PathGroup, since we already passed it options object before
|
120
|
+
if (!(object instanceof fabric.PathGroup)) {
|
121
|
+
fabric.util.object.extend(object, obj);
|
122
|
+
if (typeof obj.angle !== 'undefined') {
|
123
|
+
object.setAngle(obj.angle);
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
onObjectLoaded(object, index);
|
128
|
+
});
|
129
|
+
}
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
133
|
+
if (numTotalObjects === 0 && callback) {
|
134
|
+
callback();
|
135
|
+
}
|
136
|
+
|
137
|
+
try {
|
138
|
+
objects.forEach(loadObject, this);
|
139
|
+
}
|
140
|
+
catch(e) {
|
141
|
+
fabric.log(e);
|
142
|
+
}
|
143
|
+
},
|
144
|
+
|
145
|
+
/**
|
146
|
+
* Populates canvas with data from the specified JSON
|
147
|
+
* JSON format must conform to the one of `fabric.Canvas#toJSON`
|
148
|
+
* @method loadFromJSON
|
149
|
+
* @param {String|Object} json JSON string or object
|
150
|
+
* @param {Function} callback Callback, invoked when json is parsed
|
151
|
+
* and corresponding objects (e.g: fabric.Image)
|
152
|
+
* are initialized
|
153
|
+
* @return {fabric.Canvas} instance
|
154
|
+
* @chainable
|
155
|
+
*/
|
156
|
+
loadFromJSON: function (json, callback) {
|
157
|
+
if (!json) return;
|
158
|
+
|
159
|
+
// serialize if it wasn't already
|
160
|
+
var serialized = (typeof json === 'string')
|
161
|
+
? JSON.parse(json)
|
162
|
+
: json;
|
163
|
+
|
164
|
+
var _this = this;
|
165
|
+
this._enlivenObjects(serialized.objects, function () {
|
166
|
+
_this._setBgOverlayImages(serialized, callback);
|
167
|
+
});
|
168
|
+
|
169
|
+
return this;
|
170
|
+
},
|
171
|
+
|
172
|
+
_setBgOverlayImages: function(serialized, callback) {
|
173
|
+
|
174
|
+
var _this = this,
|
175
|
+
backgroundPatternLoaded,
|
176
|
+
backgroundImageLoaded,
|
177
|
+
overlayImageLoaded;
|
178
|
+
|
179
|
+
if (serialized.backgroundImage) {
|
180
|
+
this.setBackgroundImage(serialized.backgroundImage, function() {
|
181
|
+
|
182
|
+
_this.backgroundImageOpacity = serialized.backgroundImageOpacity;
|
183
|
+
_this.backgroundImageStretch = serialized.backgroundImageStretch;
|
184
|
+
|
185
|
+
_this.renderAll();
|
186
|
+
|
187
|
+
backgroundImageLoaded = true;
|
188
|
+
|
189
|
+
callback && overlayImageLoaded && backgroundPatternLoaded && callback();
|
190
|
+
});
|
191
|
+
}
|
192
|
+
else {
|
193
|
+
backgroundImageLoaded = true;
|
194
|
+
}
|
195
|
+
|
196
|
+
if (serialized.overlayImage) {
|
197
|
+
this.setOverlayImage(serialized.overlayImage, function() {
|
198
|
+
|
199
|
+
_this.overlayImageLeft = serialized.overlayImageLeft || 0;
|
200
|
+
_this.overlayImageTop = serialized.overlayImageTop || 0;
|
201
|
+
|
202
|
+
_this.renderAll();
|
203
|
+
overlayImageLoaded = true;
|
204
|
+
|
205
|
+
callback && backgroundImageLoaded && backgroundPatternLoaded && callback();
|
206
|
+
});
|
207
|
+
}
|
208
|
+
else {
|
209
|
+
overlayImageLoaded = true;
|
210
|
+
}
|
211
|
+
|
212
|
+
if (serialized.background) {
|
213
|
+
this.setBackgroundColor(serialized.background, function() {
|
214
|
+
|
215
|
+
_this.renderAll();
|
216
|
+
backgroundPatternLoaded = true;
|
217
|
+
|
218
|
+
callback && overlayImageLoaded && backgroundImageLoaded && callback();
|
219
|
+
});
|
220
|
+
}
|
221
|
+
else {
|
222
|
+
backgroundPatternLoaded = true;
|
223
|
+
}
|
224
|
+
|
225
|
+
if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background) {
|
226
|
+
callback && callback();
|
227
|
+
}
|
228
|
+
},
|
229
|
+
|
230
|
+
/**
|
231
|
+
* @method _enlivenObjects
|
232
|
+
* @param {Array} objects
|
233
|
+
* @param {Function} callback
|
234
|
+
*/
|
235
|
+
_enlivenObjects: function (objects, callback) {
|
236
|
+
var _this = this;
|
237
|
+
fabric.util.enlivenObjects(objects, function(enlivenedObjects) {
|
238
|
+
enlivenedObjects.forEach(function(obj, index) {
|
239
|
+
_this.insertAt(obj, index, true);
|
240
|
+
});
|
241
|
+
callback && callback();
|
242
|
+
});
|
243
|
+
},
|
244
|
+
|
245
|
+
/**
|
246
|
+
* @private
|
247
|
+
* @method _toDataURL
|
248
|
+
* @param {String} format
|
249
|
+
* @param {Function} callback
|
250
|
+
*/
|
251
|
+
_toDataURL: function (format, callback) {
|
252
|
+
this.clone(function (clone) {
|
253
|
+
callback(clone.toDataURL(format));
|
254
|
+
});
|
255
|
+
},
|
256
|
+
|
257
|
+
/**
|
258
|
+
* @private
|
259
|
+
* @method _toDataURLWithMultiplier
|
260
|
+
* @param {String} format
|
261
|
+
* @param {Number} multiplier
|
262
|
+
* @param {Function} callback
|
263
|
+
*/
|
264
|
+
_toDataURLWithMultiplier: function (format, multiplier, callback) {
|
265
|
+
this.clone(function (clone) {
|
266
|
+
callback(clone.toDataURLWithMultiplier(format, multiplier));
|
267
|
+
});
|
268
|
+
},
|
269
|
+
|
270
|
+
/**
|
271
|
+
* Clones canvas instance
|
272
|
+
* @method clone
|
273
|
+
* @param {Object} [callback] Receives cloned instance as a first argument
|
274
|
+
*/
|
275
|
+
clone: function (callback) {
|
276
|
+
var data = JSON.stringify(this);
|
277
|
+
this.cloneWithoutData(function(clone) {
|
278
|
+
clone.loadFromJSON(data, function() {
|
279
|
+
callback && callback(clone);
|
280
|
+
});
|
281
|
+
});
|
282
|
+
},
|
283
|
+
|
284
|
+
/**
|
285
|
+
* Clones canvas instance without cloning existing data.
|
286
|
+
* This essentially copies canvas dimensions, clipping properties, etc.
|
287
|
+
* but leaves data empty (so that you can populate it with your own)
|
288
|
+
* @method cloneWithoutData
|
289
|
+
* @param {Object} [callback] Receives cloned instance as a first argument
|
290
|
+
*/
|
291
|
+
cloneWithoutData: function(callback) {
|
292
|
+
var el = fabric.document.createElement('canvas');
|
293
|
+
|
294
|
+
el.width = this.getWidth();
|
295
|
+
el.height = this.getHeight();
|
296
|
+
|
297
|
+
var clone = new fabric.Canvas(el);
|
298
|
+
clone.clipTo = this.clipTo;
|
299
|
+
if (this.backgroundImage) {
|
300
|
+
clone.setBackgroundImage(this.backgroundImage.src, function() {
|
301
|
+
clone.renderAll();
|
302
|
+
callback && callback(clone);
|
303
|
+
});
|
304
|
+
clone.backgroundImageOpacity = this.backgroundImageOpacity;
|
305
|
+
clone.backgroundImageStretch = this.backgroundImageStretch;
|
306
|
+
}
|
307
|
+
else {
|
308
|
+
callback && callback(clone);
|
309
|
+
}
|
310
|
+
}
|
311
|
+
});
|
@@ -0,0 +1,182 @@
|
|
1
|
+
(function(global) {
|
2
|
+
|
3
|
+
"use strict";
|
4
|
+
|
5
|
+
var fabric = global.fabric || (global.fabric = { }),
|
6
|
+
piBy2 = Math.PI * 2,
|
7
|
+
extend = fabric.util.object.extend;
|
8
|
+
|
9
|
+
if (fabric.Circle) {
|
10
|
+
fabric.warn('fabric.Circle is already defined.');
|
11
|
+
return;
|
12
|
+
}
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Circle class
|
16
|
+
* @class Circle
|
17
|
+
* @extends fabric.Object
|
18
|
+
*/
|
19
|
+
fabric.Circle = fabric.util.createClass(fabric.Object, /** @scope fabric.Circle.prototype */ {
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Type of an object
|
23
|
+
* @property
|
24
|
+
* @type String
|
25
|
+
*/
|
26
|
+
type: 'circle',
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Constructor
|
30
|
+
* @method initialize
|
31
|
+
* @param {Object} [options] Options object
|
32
|
+
* @return {fabric.Circle} thisArg
|
33
|
+
*/
|
34
|
+
initialize: function(options) {
|
35
|
+
options = options || { };
|
36
|
+
|
37
|
+
this.set('radius', options.radius || 0);
|
38
|
+
this.callSuper('initialize', options);
|
39
|
+
|
40
|
+
var diameter = this.get('radius') * 2;
|
41
|
+
this.set('width', diameter).set('height', diameter);
|
42
|
+
},
|
43
|
+
|
44
|
+
/**
|
45
|
+
* Returns object representation of an instance
|
46
|
+
* @method toObject
|
47
|
+
* @param {Array} propertiesToInclude
|
48
|
+
* @return {Object} object representation of an instance
|
49
|
+
*/
|
50
|
+
toObject: function(propertiesToInclude) {
|
51
|
+
return extend(this.callSuper('toObject', propertiesToInclude), {
|
52
|
+
radius: this.get('radius')
|
53
|
+
});
|
54
|
+
},
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Returns svg representation of an instance
|
58
|
+
* @method toSVG
|
59
|
+
* @return {String} svg representation of an instance
|
60
|
+
*/
|
61
|
+
toSVG: function() {
|
62
|
+
return ('<circle ' +
|
63
|
+
'cx="0" cy="0" ' +
|
64
|
+
'r="' + this.radius + '" ' +
|
65
|
+
'style="' + this.getSvgStyles() + '" ' +
|
66
|
+
'transform="' + this.getSvgTransform() + '" ' +
|
67
|
+
'/>');
|
68
|
+
},
|
69
|
+
|
70
|
+
/**
|
71
|
+
* @private
|
72
|
+
* @method _render
|
73
|
+
* @param ctx {CanvasRenderingContext2D} context to render on
|
74
|
+
*/
|
75
|
+
_render: function(ctx, noTransform) {
|
76
|
+
ctx.beginPath();
|
77
|
+
// multiply by currently set alpha (the one that was set by path group where this object is contained, for example)
|
78
|
+
ctx.globalAlpha = this.group ? (ctx.globalAlpha * this.opacity) : this.opacity;
|
79
|
+
ctx.arc(noTransform ? this.left : 0, noTransform ? this.top : 0, this.radius, 0, piBy2, false);
|
80
|
+
ctx.closePath();
|
81
|
+
if (this.fill) {
|
82
|
+
ctx.fill();
|
83
|
+
}
|
84
|
+
this._removeShadow(ctx);
|
85
|
+
if (this.stroke) {
|
86
|
+
ctx.stroke();
|
87
|
+
}
|
88
|
+
},
|
89
|
+
|
90
|
+
/**
|
91
|
+
* Returns horizontal radius of an object (according to how an object is scaled)
|
92
|
+
* @method getRadiusX
|
93
|
+
* @return {Number}
|
94
|
+
*/
|
95
|
+
getRadiusX: function() {
|
96
|
+
return this.get('radius') * this.get('scaleX');
|
97
|
+
},
|
98
|
+
|
99
|
+
/**
|
100
|
+
* Returns vertical radius of an object (according to how an object is scaled)
|
101
|
+
* @method getRadiusY
|
102
|
+
* @return {Number}
|
103
|
+
*/
|
104
|
+
getRadiusY: function() {
|
105
|
+
return this.get('radius') * this.get('scaleY');
|
106
|
+
},
|
107
|
+
|
108
|
+
/**
|
109
|
+
* Sets radius of an object (and updates width accordingly)
|
110
|
+
* @method setRadius
|
111
|
+
* @return {Number}
|
112
|
+
*/
|
113
|
+
setRadius: function(value) {
|
114
|
+
this.radius = value;
|
115
|
+
this.set('width', value * 2).set('height', value * 2);
|
116
|
+
},
|
117
|
+
|
118
|
+
/**
|
119
|
+
* Returns complexity of an instance
|
120
|
+
* @method complexity
|
121
|
+
* @return {Number} complexity of this instance
|
122
|
+
*/
|
123
|
+
complexity: function() {
|
124
|
+
return 1;
|
125
|
+
}
|
126
|
+
});
|
127
|
+
|
128
|
+
/**
|
129
|
+
* List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement})
|
130
|
+
* @static
|
131
|
+
* @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement
|
132
|
+
*/
|
133
|
+
fabric.Circle.ATTRIBUTE_NAMES = 'cx cy r fill fill-opacity opacity stroke stroke-width transform'.split(' ');
|
134
|
+
|
135
|
+
/**
|
136
|
+
* Returns {@link fabric.Circle} instance from an SVG element
|
137
|
+
* @static
|
138
|
+
* @method fabric.Circle.fromElement
|
139
|
+
* @param {SVGElement} element Element to parse
|
140
|
+
* @param {Object} [options] Options object
|
141
|
+
* @throws {Error} If value of `r` attribute is missing or invalid
|
142
|
+
* @return {Object} Instance of fabric.Circle
|
143
|
+
*/
|
144
|
+
fabric.Circle.fromElement = function(element, options) {
|
145
|
+
options || (options = { });
|
146
|
+
var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES);
|
147
|
+
if (!isValidRadius(parsedAttributes)) {
|
148
|
+
throw new Error('value of `r` attribute is required and can not be negative');
|
149
|
+
}
|
150
|
+
if ('left' in parsedAttributes) {
|
151
|
+
parsedAttributes.left -= (options.width / 2) || 0;
|
152
|
+
}
|
153
|
+
if ('top' in parsedAttributes) {
|
154
|
+
parsedAttributes.top -= (options.height / 2) || 0;
|
155
|
+
}
|
156
|
+
var obj = new fabric.Circle(extend(parsedAttributes, options));
|
157
|
+
|
158
|
+
obj.cx = parseFloat(element.getAttribute('cx')) || 0;
|
159
|
+
obj.cy = parseFloat(element.getAttribute('cy')) || 0;
|
160
|
+
|
161
|
+
return obj;
|
162
|
+
};
|
163
|
+
|
164
|
+
/**
|
165
|
+
* @private
|
166
|
+
*/
|
167
|
+
function isValidRadius(attributes) {
|
168
|
+
return (('radius' in attributes) && (attributes.radius > 0));
|
169
|
+
}
|
170
|
+
|
171
|
+
/**
|
172
|
+
* Returns {@link fabric.Circle} instance from an object representation
|
173
|
+
* @static
|
174
|
+
* @method fabric.Circle.fromObject
|
175
|
+
* @param {Object} object Object to create an instance from
|
176
|
+
* @return {Object} Instance of fabric.Circle
|
177
|
+
*/
|
178
|
+
fabric.Circle.fromObject = function(object) {
|
179
|
+
return new fabric.Circle(object);
|
180
|
+
};
|
181
|
+
|
182
|
+
})(typeof exports !== 'undefined' ? exports : this);
|