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,184 @@
|
|
1
|
+
(function(global) {
|
2
|
+
|
3
|
+
"use strict";
|
4
|
+
|
5
|
+
var fabric = global.fabric || (global.fabric = { }),
|
6
|
+
extend = fabric.util.object.extend,
|
7
|
+
min = fabric.util.array.min,
|
8
|
+
max = fabric.util.array.max,
|
9
|
+
toFixed = fabric.util.toFixed;
|
10
|
+
|
11
|
+
if (fabric.Polygon) {
|
12
|
+
fabric.warn('fabric.Polygon is already defined');
|
13
|
+
return;
|
14
|
+
}
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Polygon class
|
18
|
+
* @class Polygon
|
19
|
+
* @extends fabric.Object
|
20
|
+
*/
|
21
|
+
fabric.Polygon = fabric.util.createClass(fabric.Object, /** @scope fabric.Polygon.prototype */ {
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Type of an object
|
25
|
+
* @property
|
26
|
+
* @type String
|
27
|
+
*/
|
28
|
+
type: 'polygon',
|
29
|
+
|
30
|
+
/**
|
31
|
+
* Constructor
|
32
|
+
* @method initialize
|
33
|
+
* @param {Array} points Array of points
|
34
|
+
* @param {Object} [options] Options object
|
35
|
+
* @param {Boolean} Whether points offsetting should be skipped
|
36
|
+
* @return {fabric.Polygon} thisArg
|
37
|
+
*/
|
38
|
+
initialize: function(points, options, skipOffset) {
|
39
|
+
options = options || { };
|
40
|
+
this.points = points;
|
41
|
+
this.callSuper('initialize', options);
|
42
|
+
this._calcDimensions(skipOffset);
|
43
|
+
},
|
44
|
+
|
45
|
+
/**
|
46
|
+
* @private
|
47
|
+
* @method _calcDimensions
|
48
|
+
*/
|
49
|
+
_calcDimensions: function(skipOffset) {
|
50
|
+
|
51
|
+
var points = this.points,
|
52
|
+
minX = min(points, 'x'),
|
53
|
+
minY = min(points, 'y'),
|
54
|
+
maxX = max(points, 'x'),
|
55
|
+
maxY = max(points, 'y');
|
56
|
+
|
57
|
+
this.width = (maxX - minX) || 1;
|
58
|
+
this.height = (maxY - minY) || 1;
|
59
|
+
|
60
|
+
this.minX = minX;
|
61
|
+
this.minY = minY;
|
62
|
+
|
63
|
+
if (skipOffset) return;
|
64
|
+
|
65
|
+
var halfWidth = this.width / 2,
|
66
|
+
halfHeight = this.height / 2;
|
67
|
+
|
68
|
+
// change points to offset polygon into a bounding box
|
69
|
+
this.points.forEach(function(p) {
|
70
|
+
p.x -= halfWidth;
|
71
|
+
p.y -= halfHeight;
|
72
|
+
}, this);
|
73
|
+
},
|
74
|
+
|
75
|
+
/**
|
76
|
+
* Returns object representation of an instance
|
77
|
+
* @method toObject
|
78
|
+
* @param {Array} propertiesToInclude
|
79
|
+
* @return {Object} object representation of an instance
|
80
|
+
*/
|
81
|
+
toObject: function(propertiesToInclude) {
|
82
|
+
return extend(this.callSuper('toObject', propertiesToInclude), {
|
83
|
+
points: this.points.concat()
|
84
|
+
});
|
85
|
+
},
|
86
|
+
|
87
|
+
/**
|
88
|
+
* Returns svg representation of an instance
|
89
|
+
* @method toSVG
|
90
|
+
* @return {String} svg representation of an instance
|
91
|
+
*/
|
92
|
+
toSVG: function() {
|
93
|
+
var points = [];
|
94
|
+
for (var i = 0, len = this.points.length; i < len; i++) {
|
95
|
+
points.push(toFixed(this.points[i].x, 2), ',', toFixed(this.points[i].y, 2), ' ');
|
96
|
+
}
|
97
|
+
|
98
|
+
return [
|
99
|
+
'<polygon ',
|
100
|
+
'points="', points.join(''), '" ',
|
101
|
+
'style="', this.getSvgStyles(), '" ',
|
102
|
+
'transform="', this.getSvgTransform(), '" ',
|
103
|
+
'/>'
|
104
|
+
].join('');
|
105
|
+
},
|
106
|
+
|
107
|
+
/**
|
108
|
+
* @private
|
109
|
+
* @method _render
|
110
|
+
* @param ctx {CanvasRenderingContext2D} context to render on
|
111
|
+
*/
|
112
|
+
_render: function(ctx) {
|
113
|
+
var point;
|
114
|
+
ctx.beginPath();
|
115
|
+
ctx.moveTo(this.points[0].x, this.points[0].y);
|
116
|
+
for (var i = 0, len = this.points.length; i < len; i++) {
|
117
|
+
point = this.points[i];
|
118
|
+
ctx.lineTo(point.x, point.y);
|
119
|
+
}
|
120
|
+
if (this.fill) {
|
121
|
+
ctx.fill();
|
122
|
+
}
|
123
|
+
this._removeShadow(ctx);
|
124
|
+
if (this.stroke) {
|
125
|
+
ctx.closePath();
|
126
|
+
ctx.stroke();
|
127
|
+
}
|
128
|
+
},
|
129
|
+
|
130
|
+
/**
|
131
|
+
* Returns complexity of an instance
|
132
|
+
* @method complexity
|
133
|
+
* @return {Number} complexity of this instance
|
134
|
+
*/
|
135
|
+
complexity: function() {
|
136
|
+
return this.points.length;
|
137
|
+
}
|
138
|
+
});
|
139
|
+
|
140
|
+
/**
|
141
|
+
* List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`)
|
142
|
+
* @static
|
143
|
+
* @see: http://www.w3.org/TR/SVG/shapes.html#PolygonElement
|
144
|
+
*/
|
145
|
+
fabric.Polygon.ATTRIBUTE_NAMES = 'fill fill-opacity opacity stroke stroke-width transform'.split(' ');
|
146
|
+
|
147
|
+
/**
|
148
|
+
* Returns {@link fabric.Polygon} instance from an SVG element
|
149
|
+
* @static
|
150
|
+
* @method fabric.Polygon.fromElement
|
151
|
+
* @param {SVGElement} element Element to parse
|
152
|
+
* @param {Object} [options] Options object
|
153
|
+
* @return {fabric.Polygon}
|
154
|
+
*/
|
155
|
+
fabric.Polygon.fromElement = function(element, options) {
|
156
|
+
if (!element) {
|
157
|
+
return null;
|
158
|
+
}
|
159
|
+
options || (options = { });
|
160
|
+
|
161
|
+
var points = fabric.parsePointsAttribute(element.getAttribute('points')),
|
162
|
+
parsedAttributes = fabric.parseAttributes(element, fabric.Polygon.ATTRIBUTE_NAMES);
|
163
|
+
|
164
|
+
for (var i = 0, len = points.length; i < len; i++) {
|
165
|
+
// normalize coordinates, according to containing box (dimensions of which are passed via `options`)
|
166
|
+
points[i].x -= (options.width / 2) || 0;
|
167
|
+
points[i].y -= (options.height / 2) || 0;
|
168
|
+
}
|
169
|
+
|
170
|
+
return new fabric.Polygon(points, extend(parsedAttributes, options), true);
|
171
|
+
};
|
172
|
+
|
173
|
+
/**
|
174
|
+
* Returns fabric.Polygon instance from an object representation
|
175
|
+
* @static
|
176
|
+
* @method fabric.Polygon.fromObject
|
177
|
+
* @param {Object} object Object to create an instance from
|
178
|
+
* @return {fabric.Polygon}
|
179
|
+
*/
|
180
|
+
fabric.Polygon.fromObject = function(object) {
|
181
|
+
return new fabric.Polygon(object.points, object, true);
|
182
|
+
};
|
183
|
+
|
184
|
+
})(typeof exports !== 'undefined' ? exports : this);
|
@@ -0,0 +1,157 @@
|
|
1
|
+
(function(global) {
|
2
|
+
|
3
|
+
"use strict";
|
4
|
+
|
5
|
+
var fabric = global.fabric || (global.fabric = { }),
|
6
|
+
toFixed = fabric.util.toFixed;
|
7
|
+
|
8
|
+
if (fabric.Polyline) {
|
9
|
+
fabric.warn('fabric.Polyline is already defined');
|
10
|
+
return;
|
11
|
+
}
|
12
|
+
|
13
|
+
/**
|
14
|
+
* Polyline class
|
15
|
+
* @class Polyline
|
16
|
+
* @extends fabric.Object
|
17
|
+
*/
|
18
|
+
fabric.Polyline = fabric.util.createClass(fabric.Object, /** @scope fabric.Polyline.prototype */ {
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Type of an object
|
22
|
+
* @property
|
23
|
+
* @type String
|
24
|
+
*/
|
25
|
+
type: 'polyline',
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Constructor
|
29
|
+
* @method initialize
|
30
|
+
* @param {Array} points array of points
|
31
|
+
* @param {Object} [options] Options object
|
32
|
+
* @param {Boolean} Whether points offsetting should be skipped
|
33
|
+
* @return {Object} thisArg
|
34
|
+
*/
|
35
|
+
initialize: function(points, options, skipOffset) {
|
36
|
+
options = options || { };
|
37
|
+
this.set('points', points);
|
38
|
+
this.callSuper('initialize', options);
|
39
|
+
this._calcDimensions(skipOffset);
|
40
|
+
},
|
41
|
+
|
42
|
+
/**
|
43
|
+
* @private
|
44
|
+
* @method _calcDimensions
|
45
|
+
*/
|
46
|
+
_calcDimensions: function(skipOffset) {
|
47
|
+
return fabric.Polygon.prototype._calcDimensions.call(this, skipOffset);
|
48
|
+
},
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Returns object representation of an instance
|
52
|
+
* @method toObject
|
53
|
+
* @param {Array} propertiesToInclude
|
54
|
+
* @return {Object} object representation of an instance
|
55
|
+
*/
|
56
|
+
toObject: function(propertiesToInclude) {
|
57
|
+
return fabric.Polygon.prototype.toObject.call(this, propertiesToInclude);
|
58
|
+
},
|
59
|
+
|
60
|
+
/**
|
61
|
+
* Returns SVG representation of an instance
|
62
|
+
* @method toSVG
|
63
|
+
* @return {String} svg representation of an instance
|
64
|
+
*/
|
65
|
+
toSVG: function() {
|
66
|
+
var points = [];
|
67
|
+
for (var i = 0, len = this.points.length; i < len; i++) {
|
68
|
+
points.push(toFixed(this.points[i].x, 2), ',', toFixed(this.points[i].y, 2), ' ');
|
69
|
+
}
|
70
|
+
|
71
|
+
return [
|
72
|
+
'<polyline ',
|
73
|
+
'points="', points.join(''), '" ',
|
74
|
+
'style="', this.getSvgStyles(), '" ',
|
75
|
+
'transform="', this.getSvgTransform(), '" ',
|
76
|
+
'/>'
|
77
|
+
].join('');
|
78
|
+
},
|
79
|
+
|
80
|
+
/**
|
81
|
+
* @private
|
82
|
+
* @method _render
|
83
|
+
* @param {CanvasRenderingContext2D} ctx Context to render on
|
84
|
+
*/
|
85
|
+
_render: function(ctx) {
|
86
|
+
var point;
|
87
|
+
ctx.beginPath();
|
88
|
+
ctx.moveTo(this.points[0].x, this.points[0].y);
|
89
|
+
for (var i = 0, len = this.points.length; i < len; i++) {
|
90
|
+
point = this.points[i];
|
91
|
+
ctx.lineTo(point.x, point.y);
|
92
|
+
}
|
93
|
+
if (this.fill) {
|
94
|
+
ctx.fill();
|
95
|
+
}
|
96
|
+
this._removeShadow(ctx);
|
97
|
+
if (this.stroke) {
|
98
|
+
ctx.stroke();
|
99
|
+
}
|
100
|
+
},
|
101
|
+
|
102
|
+
/**
|
103
|
+
* Returns complexity of an instance
|
104
|
+
* @method complexity
|
105
|
+
* @return {Number} complexity
|
106
|
+
*/
|
107
|
+
complexity: function() {
|
108
|
+
return this.get('points').length;
|
109
|
+
}
|
110
|
+
});
|
111
|
+
|
112
|
+
/**
|
113
|
+
* List of attribute names to account for when parsing SVG element (used by {@link fabric.Polyline.fromElement})
|
114
|
+
* @static
|
115
|
+
* @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement
|
116
|
+
*/
|
117
|
+
fabric.Polyline.ATTRIBUTE_NAMES = 'fill fill-opacity opacity stroke stroke-width transform'.split(' ');
|
118
|
+
|
119
|
+
/**
|
120
|
+
* Returns fabric.Polyline instance from an SVG element
|
121
|
+
* @static
|
122
|
+
* @method fabric.Polyline.fromElement
|
123
|
+
* @param {SVGElement} element Element to parse
|
124
|
+
* @param {Object} [options] Options object
|
125
|
+
* @return {Object} instance of fabric.Polyline
|
126
|
+
*/
|
127
|
+
fabric.Polyline.fromElement = function(element, options) {
|
128
|
+
if (!element) {
|
129
|
+
return null;
|
130
|
+
}
|
131
|
+
options || (options = { });
|
132
|
+
|
133
|
+
var points = fabric.parsePointsAttribute(element.getAttribute('points')),
|
134
|
+
parsedAttributes = fabric.parseAttributes(element, fabric.Polyline.ATTRIBUTE_NAMES);
|
135
|
+
|
136
|
+
for (var i = 0, len = points.length; i < len; i++) {
|
137
|
+
// normalize coordinates, according to containing box (dimensions of which are passed via `options`)
|
138
|
+
points[i].x -= (options.width / 2) || 0;
|
139
|
+
points[i].y -= (options.height / 2) || 0;
|
140
|
+
}
|
141
|
+
|
142
|
+
return new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options), true);
|
143
|
+
};
|
144
|
+
|
145
|
+
/**
|
146
|
+
* Returns fabric.Polyline instance from an object representation
|
147
|
+
* @static
|
148
|
+
* @method fabric.Polyline.fromObject
|
149
|
+
* @param {Object} [object] Object to create an instance from
|
150
|
+
* @return {fabric.Polyline}
|
151
|
+
*/
|
152
|
+
fabric.Polyline.fromObject = function(object) {
|
153
|
+
var points = object.points;
|
154
|
+
return new fabric.Polyline(points, object, true);
|
155
|
+
};
|
156
|
+
|
157
|
+
})(typeof exports !== 'undefined' ? exports : this);
|
@@ -0,0 +1,298 @@
|
|
1
|
+
(function(global) {
|
2
|
+
|
3
|
+
"use strict";
|
4
|
+
|
5
|
+
var fabric = global.fabric || (global.fabric = { }),
|
6
|
+
extend = fabric.util.object.extend;
|
7
|
+
|
8
|
+
if (fabric.Rect) {
|
9
|
+
console.warn('fabric.Rect is already defined');
|
10
|
+
return;
|
11
|
+
}
|
12
|
+
|
13
|
+
/**
|
14
|
+
* Rectangle class
|
15
|
+
* @class Rect
|
16
|
+
* @extends fabric.Object
|
17
|
+
*/
|
18
|
+
fabric.Rect = fabric.util.createClass(fabric.Object, /** @scope fabric.Rect.prototype */ {
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Type of an object
|
22
|
+
* @property
|
23
|
+
* @type String
|
24
|
+
*/
|
25
|
+
type: 'rect',
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Horizontal border radius
|
29
|
+
* @property
|
30
|
+
* @type Number
|
31
|
+
*/
|
32
|
+
rx: 0,
|
33
|
+
|
34
|
+
/**
|
35
|
+
* Vertical border radius
|
36
|
+
* @property
|
37
|
+
* @type Number
|
38
|
+
*/
|
39
|
+
ry: 0,
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Constructor
|
43
|
+
* @method initialize
|
44
|
+
* @param {Object} [options] Options object
|
45
|
+
* @return {Object} thisArg
|
46
|
+
*/
|
47
|
+
initialize: function(options) {
|
48
|
+
options = options || { };
|
49
|
+
|
50
|
+
this._initStateProperties();
|
51
|
+
this.callSuper('initialize', options);
|
52
|
+
this._initRxRy();
|
53
|
+
|
54
|
+
this.x = 0;
|
55
|
+
this.y = 0;
|
56
|
+
},
|
57
|
+
|
58
|
+
/**
|
59
|
+
* Creates `stateProperties` list on an instance, and adds `fabric.Rect` -specific ones to it
|
60
|
+
* (such as "rx", "ry", etc.)
|
61
|
+
* @private
|
62
|
+
* @method _initStateProperties
|
63
|
+
*/
|
64
|
+
_initStateProperties: function() {
|
65
|
+
this.stateProperties = this.stateProperties.concat(['rx', 'ry']);
|
66
|
+
},
|
67
|
+
|
68
|
+
/**
|
69
|
+
* Initializes rx/ry attributes
|
70
|
+
* @private
|
71
|
+
* @method _initRxRy
|
72
|
+
*/
|
73
|
+
_initRxRy: function() {
|
74
|
+
if (this.rx && !this.ry) {
|
75
|
+
this.ry = this.rx;
|
76
|
+
}
|
77
|
+
else if (this.ry && !this.rx) {
|
78
|
+
this.rx = this.ry;
|
79
|
+
}
|
80
|
+
},
|
81
|
+
|
82
|
+
/**
|
83
|
+
* @private
|
84
|
+
* @method _render
|
85
|
+
* @param ctx {CanvasRenderingContext2D} context to render on
|
86
|
+
*/
|
87
|
+
_render: function(ctx) {
|
88
|
+
var rx = this.rx || 0,
|
89
|
+
ry = this.ry || 0,
|
90
|
+
x = -this.width / 2,
|
91
|
+
y = -this.height / 2,
|
92
|
+
w = this.width,
|
93
|
+
h = this.height;
|
94
|
+
|
95
|
+
ctx.beginPath();
|
96
|
+
ctx.globalAlpha = this.group ? (ctx.globalAlpha * this.opacity) : this.opacity;
|
97
|
+
|
98
|
+
if (this.transformMatrix && this.group) {
|
99
|
+
ctx.translate(
|
100
|
+
this.width / 2 + this.x,
|
101
|
+
this.height / 2 + this.y);
|
102
|
+
}
|
103
|
+
if (!this.transformMatrix && this.group) {
|
104
|
+
ctx.translate(
|
105
|
+
-this.group.width / 2 + this.width / 2 + this.x,
|
106
|
+
-this.group.height / 2 + this.height / 2 + this.y);
|
107
|
+
}
|
108
|
+
|
109
|
+
ctx.moveTo(x+rx, y);
|
110
|
+
ctx.lineTo(x+w-rx, y);
|
111
|
+
ctx.quadraticCurveTo(x+w, y, x+w, y+ry, x+w, y+ry);
|
112
|
+
ctx.lineTo(x+w, y+h-ry);
|
113
|
+
ctx.quadraticCurveTo(x+w,y+h,x+w-rx,y+h,x+w-rx,y+h);
|
114
|
+
ctx.lineTo(x+rx,y+h);
|
115
|
+
ctx.quadraticCurveTo(x,y+h,x,y+h-ry,x,y+h-ry);
|
116
|
+
ctx.lineTo(x,y+ry);
|
117
|
+
ctx.quadraticCurveTo(x,y,x+rx,y,x+rx,y);
|
118
|
+
ctx.closePath();
|
119
|
+
|
120
|
+
if (this.fill) {
|
121
|
+
ctx.fill();
|
122
|
+
}
|
123
|
+
|
124
|
+
this._removeShadow(ctx);
|
125
|
+
|
126
|
+
if (this.strokeDashArray) {
|
127
|
+
this._renderDashedStroke(ctx);
|
128
|
+
}
|
129
|
+
else if (this.stroke) {
|
130
|
+
ctx.stroke();
|
131
|
+
}
|
132
|
+
},
|
133
|
+
|
134
|
+
/**
|
135
|
+
* @private
|
136
|
+
* @method _renderDashedStroke
|
137
|
+
*/
|
138
|
+
_renderDashedStroke: function(ctx) {
|
139
|
+
|
140
|
+
if (1 & this.strokeDashArray.length /* if odd number of items */) {
|
141
|
+
/* duplicate items */
|
142
|
+
this.strokeDashArray.push.apply(this.strokeDashArray, this.strokeDashArray);
|
143
|
+
}
|
144
|
+
|
145
|
+
var i = 0,
|
146
|
+
x = -this.width/2, y = -this.height/2,
|
147
|
+
_this = this,
|
148
|
+
padding = this.padding,
|
149
|
+
dashedArrayLength = this.strokeDashArray.length;
|
150
|
+
|
151
|
+
ctx.save();
|
152
|
+
ctx.beginPath();
|
153
|
+
|
154
|
+
/** @ignore */
|
155
|
+
function renderSide(xMultiplier, yMultiplier) {
|
156
|
+
|
157
|
+
var lineLength = 0,
|
158
|
+
lengthDiff = 0,
|
159
|
+
sideLength = (yMultiplier ? _this.height : _this.width) + padding * 2;
|
160
|
+
|
161
|
+
while (lineLength < sideLength) {
|
162
|
+
|
163
|
+
var lengthOfSubPath = _this.strokeDashArray[i++];
|
164
|
+
lineLength += lengthOfSubPath;
|
165
|
+
|
166
|
+
if (lineLength > sideLength) {
|
167
|
+
lengthDiff = lineLength - sideLength;
|
168
|
+
}
|
169
|
+
|
170
|
+
// track coords
|
171
|
+
if (xMultiplier) {
|
172
|
+
x += (lengthOfSubPath * xMultiplier) - (lengthDiff * xMultiplier || 0);
|
173
|
+
}
|
174
|
+
else {
|
175
|
+
y += (lengthOfSubPath * yMultiplier) - (lengthDiff * yMultiplier || 0);
|
176
|
+
}
|
177
|
+
|
178
|
+
ctx[1 & i /* odd */ ? 'moveTo' : 'lineTo'](x, y);
|
179
|
+
if (i >= dashedArrayLength) {
|
180
|
+
i = 0;
|
181
|
+
}
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
renderSide(1, 0);
|
186
|
+
renderSide(0, 1);
|
187
|
+
renderSide(-1, 0);
|
188
|
+
renderSide(0, -1);
|
189
|
+
|
190
|
+
ctx.stroke();
|
191
|
+
ctx.closePath();
|
192
|
+
ctx.restore();
|
193
|
+
},
|
194
|
+
|
195
|
+
/**
|
196
|
+
* @method _normalizeLeftTopProperties
|
197
|
+
* @private
|
198
|
+
* Since coordinate system differs from that of SVG
|
199
|
+
*/
|
200
|
+
_normalizeLeftTopProperties: function(parsedAttributes) {
|
201
|
+
if (parsedAttributes.left) {
|
202
|
+
this.set('left', parsedAttributes.left + this.getWidth() / 2);
|
203
|
+
}
|
204
|
+
this.set('x', parsedAttributes.left || 0);
|
205
|
+
if (parsedAttributes.top) {
|
206
|
+
this.set('top', parsedAttributes.top + this.getHeight() / 2);
|
207
|
+
}
|
208
|
+
this.set('y', parsedAttributes.top || 0);
|
209
|
+
return this;
|
210
|
+
},
|
211
|
+
|
212
|
+
/**
|
213
|
+
* Returns complexity of an instance
|
214
|
+
* @method complexity
|
215
|
+
* @return {Number} complexity
|
216
|
+
*/
|
217
|
+
complexity: function() {
|
218
|
+
return 1;
|
219
|
+
},
|
220
|
+
|
221
|
+
/**
|
222
|
+
* Returns object representation of an instance
|
223
|
+
* @method toObject
|
224
|
+
* @param {Array} propertiesToInclude
|
225
|
+
* @return {Object} object representation of an instance
|
226
|
+
*/
|
227
|
+
toObject: function(propertiesToInclude) {
|
228
|
+
return extend(this.callSuper('toObject', propertiesToInclude), {
|
229
|
+
rx: this.get('rx') || 0,
|
230
|
+
ry: this.get('ry') || 0
|
231
|
+
});
|
232
|
+
},
|
233
|
+
|
234
|
+
/**
|
235
|
+
* Returns svg representation of an instance
|
236
|
+
* @method toSVG
|
237
|
+
* @return {String} svg representation of an instance
|
238
|
+
*/
|
239
|
+
toSVG: function() {
|
240
|
+
return '<rect ' +
|
241
|
+
'x="' + (-1 * this.width / 2) + '" y="' + (-1 * this.height / 2) + '" ' +
|
242
|
+
'rx="' + this.get('rx') + '" ry="' + this.get('ry') + '" ' +
|
243
|
+
'width="' + this.width + '" height="' + this.height + '" ' +
|
244
|
+
'style="' + this.getSvgStyles() + '" ' +
|
245
|
+
'transform="' + this.getSvgTransform() + '" ' +
|
246
|
+
'/>';
|
247
|
+
}
|
248
|
+
});
|
249
|
+
|
250
|
+
/**
|
251
|
+
* List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`)
|
252
|
+
* @static
|
253
|
+
*/
|
254
|
+
fabric.Rect.ATTRIBUTE_NAMES = 'x y width height rx ry fill fill-opacity opacity stroke stroke-width transform'.split(' ');
|
255
|
+
|
256
|
+
/**
|
257
|
+
* @private
|
258
|
+
*/
|
259
|
+
function _setDefaultLeftTopValues(attributes) {
|
260
|
+
attributes.left = attributes.left || 0;
|
261
|
+
attributes.top = attributes.top || 0;
|
262
|
+
return attributes;
|
263
|
+
}
|
264
|
+
|
265
|
+
/**
|
266
|
+
* Returns {@link fabric.Rect} instance from an SVG element
|
267
|
+
* @static
|
268
|
+
* @method fabric.Rect.fromElement
|
269
|
+
* @param {SVGElement} element Element to parse
|
270
|
+
* @param {Object} [options] Options object
|
271
|
+
* @return {fabric.Rect} Instance of fabric.Rect
|
272
|
+
*/
|
273
|
+
fabric.Rect.fromElement = function(element, options) {
|
274
|
+
if (!element) {
|
275
|
+
return null;
|
276
|
+
}
|
277
|
+
|
278
|
+
var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES);
|
279
|
+
parsedAttributes = _setDefaultLeftTopValues(parsedAttributes);
|
280
|
+
|
281
|
+
var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));
|
282
|
+
rect._normalizeLeftTopProperties(parsedAttributes);
|
283
|
+
|
284
|
+
return rect;
|
285
|
+
};
|
286
|
+
|
287
|
+
/**
|
288
|
+
* Returns {@link fabric.Rect} instance from an object representation
|
289
|
+
* @static
|
290
|
+
* @method fabric.Rect.fromObject
|
291
|
+
* @param object {Object} object to create an instance from
|
292
|
+
* @return {Object} instance of fabric.Rect
|
293
|
+
*/
|
294
|
+
fabric.Rect.fromObject = function(object) {
|
295
|
+
return new fabric.Rect(object);
|
296
|
+
};
|
297
|
+
|
298
|
+
})(typeof exports !== 'undefined' ? exports : this);
|