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,61 @@
|
|
1
|
+
/**
|
2
|
+
* @namespace fabric.Image.filters
|
3
|
+
* @memberOf fabric.Image
|
4
|
+
*/
|
5
|
+
fabric.Image.filters = fabric.Image.filters || { };
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Sepia2 filter class
|
9
|
+
* @class fabric.Image.filters.Sepia2
|
10
|
+
* @memberOf fabric.Image.filters
|
11
|
+
*/
|
12
|
+
fabric.Image.filters.Sepia2 = fabric.util.createClass(/** @lends fabric.Image.filters.Sepia2.prototype */ {
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Filter type
|
16
|
+
* @param {String} type
|
17
|
+
* @default
|
18
|
+
*/
|
19
|
+
type: 'Sepia2',
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Applies filter to canvas element
|
23
|
+
* @memberOf fabric.Image.filters.Sepia.prototype
|
24
|
+
* @param {Object} canvasEl Canvas element to apply filter to
|
25
|
+
*/
|
26
|
+
applyTo: function(canvasEl) {
|
27
|
+
var context = canvasEl.getContext('2d'),
|
28
|
+
imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
|
29
|
+
data = imageData.data,
|
30
|
+
iLen = data.length, i, r, g, b;
|
31
|
+
|
32
|
+
for (i = 0; i < iLen; i+=4) {
|
33
|
+
r = data[i];
|
34
|
+
g = data[i + 1];
|
35
|
+
b = data[i + 2];
|
36
|
+
|
37
|
+
data[i] = (r * 0.393 + g * 0.769 + b * 0.189 ) / 1.351;
|
38
|
+
data[i + 1] = (r * 0.349 + g * 0.686 + b * 0.168 ) / 1.203;
|
39
|
+
data[i + 2] = (r * 0.272 + g * 0.534 + b * 0.131 ) / 2.140;
|
40
|
+
}
|
41
|
+
|
42
|
+
context.putImageData(imageData, 0, 0);
|
43
|
+
},
|
44
|
+
|
45
|
+
/**
|
46
|
+
* Returns json representation of filter
|
47
|
+
* @return {String} json representation of filter
|
48
|
+
*/
|
49
|
+
toJSON: function() {
|
50
|
+
return { type: this.type };
|
51
|
+
}
|
52
|
+
});
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Returns filter instance from an object representation
|
56
|
+
* @static
|
57
|
+
* @return {fabric.Image.filters.Sepia2} Instance of fabric.Image.filters.Sepia2
|
58
|
+
*/
|
59
|
+
fabric.Image.filters.Sepia2.fromObject = function() {
|
60
|
+
return new fabric.Image.filters.Sepia2();
|
61
|
+
};
|
@@ -0,0 +1,58 @@
|
|
1
|
+
/**
|
2
|
+
* @namespace fabric.Image.filters
|
3
|
+
* @memberOf fabric.Image
|
4
|
+
*/
|
5
|
+
fabric.Image.filters = fabric.Image.filters || { };
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Sepia filter class
|
9
|
+
* @class fabric.Image.filters.Sepia
|
10
|
+
* @memberOf fabric.Image.filters
|
11
|
+
*/
|
12
|
+
fabric.Image.filters.Sepia = fabric.util.createClass(/** @lends fabric.Image.filters.Sepia.prototype */ {
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Filter type
|
16
|
+
* @param {String} type
|
17
|
+
* @default
|
18
|
+
*/
|
19
|
+
type: 'Sepia',
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Applies filter to canvas element
|
23
|
+
* @memberOf fabric.Image.filters.Sepia.prototype
|
24
|
+
* @param {Object} canvasEl Canvas element to apply filter to
|
25
|
+
*/
|
26
|
+
applyTo: function(canvasEl) {
|
27
|
+
var context = canvasEl.getContext('2d'),
|
28
|
+
imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
|
29
|
+
data = imageData.data,
|
30
|
+
iLen = data.length, i, avg;
|
31
|
+
|
32
|
+
for (i = 0; i < iLen; i+=4) {
|
33
|
+
avg = 0.3 * data[i] + 0.59 * data[i + 1] + 0.11 * data[i + 2];
|
34
|
+
data[i] = avg + 100;
|
35
|
+
data[i + 1] = avg + 50;
|
36
|
+
data[i + 2] = avg + 255;
|
37
|
+
}
|
38
|
+
|
39
|
+
context.putImageData(imageData, 0, 0);
|
40
|
+
},
|
41
|
+
|
42
|
+
/**
|
43
|
+
* Returns json representation of filter
|
44
|
+
* @return {String} json representation of filter
|
45
|
+
*/
|
46
|
+
toJSON: function() {
|
47
|
+
return { type: this.type };
|
48
|
+
}
|
49
|
+
});
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Returns filter instance from an object representation
|
53
|
+
* @static
|
54
|
+
* @return {fabric.Image.filters.Sepia} Instance of fabric.Image.filters.Sepia
|
55
|
+
*/
|
56
|
+
fabric.Image.filters.Sepia.fromObject = function() {
|
57
|
+
return new fabric.Image.filters.Sepia();
|
58
|
+
};
|
@@ -0,0 +1,80 @@
|
|
1
|
+
/**
|
2
|
+
* @namespace fabric.Image.filters
|
3
|
+
* @memberOf fabric.Image
|
4
|
+
*/
|
5
|
+
fabric.Image.filters = fabric.Image.filters || { };
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Tint filter class
|
9
|
+
* @class fabric.Image.filters.Tint
|
10
|
+
* @memberOf fabric.Image.filters
|
11
|
+
*/
|
12
|
+
fabric.Image.filters.Tint = fabric.util.createClass(/** @lends fabric.Image.filters.Tint.prototype */ {
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Filter type
|
16
|
+
* @param {String} type
|
17
|
+
* @default
|
18
|
+
*/
|
19
|
+
type: 'Tint',
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Constructor
|
23
|
+
* @memberOf fabric.Image.filters.Tint.prototype
|
24
|
+
* @param {Object} [options] Options object
|
25
|
+
*/
|
26
|
+
initialize: function(options) {
|
27
|
+
options = options || { };
|
28
|
+
this.color = options.color || 0;
|
29
|
+
},
|
30
|
+
|
31
|
+
/**
|
32
|
+
* Applies filter to canvas element
|
33
|
+
* @param {Object} canvasEl Canvas element to apply filter to
|
34
|
+
*/
|
35
|
+
applyTo: function(canvasEl) {
|
36
|
+
var context = canvasEl.getContext('2d'),
|
37
|
+
imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
|
38
|
+
data = imageData.data,
|
39
|
+
iLen = data.length, i, a;
|
40
|
+
|
41
|
+
var rgb = parseInt(this.color, 10).toString(16);
|
42
|
+
|
43
|
+
var cr = parseInt('0x' + rgb.substr(0, 2), 16);
|
44
|
+
var cg = parseInt('0x' + rgb.substr(2, 2), 16);
|
45
|
+
var cb = parseInt('0x' + rgb.substr(4, 2), 16);
|
46
|
+
|
47
|
+
for (i = 0; i < iLen; i+=4) {
|
48
|
+
a = data[i+3];
|
49
|
+
|
50
|
+
if (a > 0){
|
51
|
+
data[i] = cr;
|
52
|
+
data[i+1] = cg;
|
53
|
+
data[i+2] = cb;
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
context.putImageData(imageData, 0, 0);
|
58
|
+
},
|
59
|
+
|
60
|
+
/**
|
61
|
+
* Returns json representation of filter
|
62
|
+
* @return {Object} json representation of filter
|
63
|
+
*/
|
64
|
+
toJSON: function() {
|
65
|
+
return {
|
66
|
+
type: this.type,
|
67
|
+
color: this.color
|
68
|
+
};
|
69
|
+
}
|
70
|
+
});
|
71
|
+
|
72
|
+
/**
|
73
|
+
* Returns filter instance from an object representation
|
74
|
+
* @static
|
75
|
+
* @param {Object} object Object to create an instance from
|
76
|
+
* @return {fabric.Image.filters.Tint} Instance of fabric.Image.filters.Tint
|
77
|
+
*/
|
78
|
+
fabric.Image.filters.Tint.fromObject = function(object) {
|
79
|
+
return new fabric.Image.filters.Tint(object);
|
80
|
+
};
|
@@ -1,7 +1,13 @@
|
|
1
1
|
(function() {
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
/* _FROM_SVG_START_ */
|
4
|
+
function getColorStop(el) {
|
5
|
+
var style = el.getAttribute('style'),
|
6
|
+
offset = el.getAttribute('offset'),
|
7
|
+
color, opacity;
|
8
|
+
|
9
|
+
// convert percents to absolute values
|
10
|
+
offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);
|
5
11
|
|
6
12
|
if (style) {
|
7
13
|
var keyValuePairs = style.split(/\s*;\s*/);
|
@@ -17,65 +23,190 @@
|
|
17
23
|
value = split[1].trim();
|
18
24
|
|
19
25
|
if (key === 'stop-color') {
|
20
|
-
|
26
|
+
color = value;
|
27
|
+
}
|
28
|
+
else if (key === 'stop-opacity') {
|
29
|
+
opacity = value;
|
21
30
|
}
|
22
31
|
}
|
23
32
|
}
|
33
|
+
|
34
|
+
if (!color) {
|
35
|
+
color = el.getAttribute('stop-color') || 'rgb(0,0,0)';
|
36
|
+
}
|
37
|
+
if (!opacity) {
|
38
|
+
opacity = el.getAttribute('stop-opacity');
|
39
|
+
}
|
40
|
+
|
41
|
+
// convert rgba color to rgb color - alpha value has no affect in svg
|
42
|
+
color = new fabric.Color(color).toRgb();
|
43
|
+
|
44
|
+
return {
|
45
|
+
offset: offset,
|
46
|
+
color: color,
|
47
|
+
opacity: isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity)
|
48
|
+
};
|
24
49
|
}
|
50
|
+
/* _FROM_SVG_END_ */
|
25
51
|
|
26
52
|
/**
|
27
53
|
* Gradient class
|
28
|
-
* @class Gradient
|
29
|
-
* @memberOf fabric
|
54
|
+
* @class fabric.Gradient
|
30
55
|
*/
|
31
|
-
fabric.Gradient = fabric.util.createClass(/** @
|
56
|
+
fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ {
|
32
57
|
|
33
58
|
/**
|
34
59
|
* Constructor
|
35
|
-
* @
|
36
|
-
* @param [options] Options object with x1, y1, x2, y2 and colorStops
|
60
|
+
* @param {Object} [options] Options object with type, coords, gradientUnits and colorStops
|
37
61
|
* @return {fabric.Gradient} thisArg
|
38
62
|
*/
|
39
63
|
initialize: function(options) {
|
40
|
-
|
41
64
|
options || (options = { });
|
42
65
|
|
43
|
-
|
44
|
-
|
45
|
-
this.
|
46
|
-
this.
|
66
|
+
var coords = { };
|
67
|
+
|
68
|
+
this.id = fabric.Object.__uid++;
|
69
|
+
this.type = options.type || 'linear';
|
47
70
|
|
48
|
-
|
71
|
+
coords = {
|
72
|
+
x1: options.coords.x1 || 0,
|
73
|
+
y1: options.coords.y1 || 0,
|
74
|
+
x2: options.coords.x2 || 0,
|
75
|
+
y2: options.coords.y2 || 0
|
76
|
+
};
|
77
|
+
|
78
|
+
if (this.type === 'radial') {
|
79
|
+
coords.r1 = options.coords.r1 || 0;
|
80
|
+
coords.r2 = options.coords.r2 || 0;
|
81
|
+
}
|
82
|
+
|
83
|
+
this.coords = coords;
|
84
|
+
this.gradientUnits = options.gradientUnits || 'objectBoundingBox';
|
85
|
+
this.colorStops = options.colorStops.slice();
|
86
|
+
},
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Adds another colorStop
|
90
|
+
* @param {Object} colorStop Object with offset and color
|
91
|
+
* @return {fabric.Gradient} thisArg
|
92
|
+
*/
|
93
|
+
addColorStop: function(colorStop) {
|
94
|
+
for (var position in colorStop) {
|
95
|
+
var color = new fabric.Color(colorStop[position]);
|
96
|
+
this.colorStops.push({offset: position, color: color.toRgb(), opacity: color.getAlpha()});
|
97
|
+
}
|
98
|
+
return this;
|
49
99
|
},
|
50
100
|
|
51
101
|
/**
|
52
102
|
* Returns object representation of a gradient
|
53
|
-
* @method toObject
|
54
103
|
* @return {Object}
|
55
104
|
*/
|
56
105
|
toObject: function() {
|
57
106
|
return {
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
y2: this.y2,
|
107
|
+
type: this.type,
|
108
|
+
coords: this.coords,
|
109
|
+
gradientUnits: this.gradientUnits,
|
62
110
|
colorStops: this.colorStops
|
63
111
|
};
|
64
112
|
},
|
65
113
|
|
114
|
+
/* _TO_SVG_START_ */
|
115
|
+
/**
|
116
|
+
* Returns SVG representation of an gradient
|
117
|
+
* @param {Object} object Object to create a gradient for
|
118
|
+
* @param {Boolean} normalize Whether coords should be normalized
|
119
|
+
* @return {String} SVG representation of an gradient (linear/radial)
|
120
|
+
*/
|
121
|
+
toSVG: function(object, normalize) {
|
122
|
+
var coords = fabric.util.object.clone(this.coords),
|
123
|
+
markup;
|
124
|
+
|
125
|
+
// colorStops must be sorted ascending
|
126
|
+
this.colorStops.sort(function(a, b) {
|
127
|
+
return a.offset - b.offset;
|
128
|
+
});
|
129
|
+
|
130
|
+
if (normalize && this.gradientUnits === 'userSpaceOnUse') {
|
131
|
+
coords.x1 += object.width / 2;
|
132
|
+
coords.y1 += object.height / 2;
|
133
|
+
coords.x2 += object.width / 2;
|
134
|
+
coords.y2 += object.height / 2;
|
135
|
+
}
|
136
|
+
else if (this.gradientUnits === 'objectBoundingBox') {
|
137
|
+
_convertValuesToPercentUnits(object, coords);
|
138
|
+
}
|
139
|
+
|
140
|
+
if (this.type === 'linear') {
|
141
|
+
markup = [
|
142
|
+
'<linearGradient ',
|
143
|
+
'id="SVGID_', this.id,
|
144
|
+
'" gradientUnits="', this.gradientUnits,
|
145
|
+
'" x1="', coords.x1,
|
146
|
+
'" y1="', coords.y1,
|
147
|
+
'" x2="', coords.x2,
|
148
|
+
'" y2="', coords.y2,
|
149
|
+
'">'
|
150
|
+
];
|
151
|
+
}
|
152
|
+
else if (this.type === 'radial') {
|
153
|
+
markup = [
|
154
|
+
'<radialGradient ',
|
155
|
+
'id="SVGID_', this.id,
|
156
|
+
'" gradientUnits="', this.gradientUnits,
|
157
|
+
'" cx="', coords.x2,
|
158
|
+
'" cy="', coords.y2,
|
159
|
+
'" r="', coords.r2,
|
160
|
+
'" fx="', coords.x1,
|
161
|
+
'" fy="', coords.y1,
|
162
|
+
'">'
|
163
|
+
];
|
164
|
+
}
|
165
|
+
|
166
|
+
for (var i = 0; i < this.colorStops.length; i++) {
|
167
|
+
markup.push(
|
168
|
+
'<stop ',
|
169
|
+
'offset="', (this.colorStops[i].offset * 100) + '%',
|
170
|
+
'" style="stop-color:', this.colorStops[i].color,
|
171
|
+
(this.colorStops[i].opacity ? ';stop-opacity: ' + this.colorStops[i].opacity : ';'),
|
172
|
+
'"/>'
|
173
|
+
);
|
174
|
+
}
|
175
|
+
|
176
|
+
markup.push((this.type === 'linear' ? '</linearGradient>' : '</radialGradient>'));
|
177
|
+
|
178
|
+
return markup.join('');
|
179
|
+
},
|
180
|
+
/* _TO_SVG_END_ */
|
181
|
+
|
66
182
|
/**
|
67
183
|
* Returns an instance of CanvasGradient
|
68
|
-
* @method toLive
|
69
184
|
* @param ctx
|
70
185
|
* @return {CanvasGradient}
|
71
186
|
*/
|
72
187
|
toLive: function(ctx) {
|
73
|
-
var gradient
|
74
|
-
|
188
|
+
var gradient;
|
189
|
+
|
190
|
+
if (!this.type) return;
|
191
|
+
|
192
|
+
if (this.type === 'linear') {
|
193
|
+
gradient = ctx.createLinearGradient(
|
194
|
+
this.coords.x1, this.coords.y1, this.coords.x2, this.coords.y2);
|
195
|
+
}
|
196
|
+
else if (this.type === 'radial') {
|
197
|
+
gradient = ctx.createRadialGradient(
|
198
|
+
this.coords.x1, this.coords.y1, this.coords.r1, this.coords.x2, this.coords.y2, this.coords.r2);
|
199
|
+
}
|
75
200
|
|
76
|
-
for (var
|
77
|
-
var
|
78
|
-
|
201
|
+
for (var i = 0, len = this.colorStops.length; i < len; i++) {
|
202
|
+
var color = this.colorStops[i].color,
|
203
|
+
opacity = this.colorStops[i].opacity,
|
204
|
+
offset = this.colorStops[i].offset;
|
205
|
+
|
206
|
+
if (typeof opacity !== 'undefined') {
|
207
|
+
color = new fabric.Color(color).setAlpha(opacity).toRgba();
|
208
|
+
}
|
209
|
+
gradient.addColorStop(parseFloat(offset), color);
|
79
210
|
}
|
80
211
|
|
81
212
|
return gradient;
|
@@ -84,68 +215,94 @@
|
|
84
215
|
|
85
216
|
fabric.util.object.extend(fabric.Gradient, {
|
86
217
|
|
218
|
+
/* _FROM_SVG_START_ */
|
87
219
|
/**
|
88
220
|
* Returns {@link fabric.Gradient} instance from an SVG element
|
89
|
-
* @method fromElement
|
90
221
|
* @static
|
91
222
|
* @memberof fabric.Gradient
|
92
223
|
* @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement
|
224
|
+
* @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement
|
93
225
|
*/
|
94
226
|
fromElement: function(el, instance) {
|
95
227
|
|
96
228
|
/**
|
97
229
|
* @example:
|
98
230
|
*
|
99
|
-
* <linearGradient id="
|
231
|
+
* <linearGradient id="linearGrad1">
|
100
232
|
* <stop offset="0%" stop-color="white"/>
|
101
233
|
* <stop offset="100%" stop-color="black"/>
|
102
234
|
* </linearGradient>
|
103
235
|
*
|
104
236
|
* OR
|
105
237
|
*
|
106
|
-
* <linearGradient id="
|
107
|
-
* <stop offset="0
|
108
|
-
* <stop offset="
|
238
|
+
* <linearGradient id="linearGrad2">
|
239
|
+
* <stop offset="0" style="stop-color:rgb(255,255,255)"/>
|
240
|
+
* <stop offset="1" style="stop-color:rgb(0,0,0)"/>
|
109
241
|
* </linearGradient>
|
110
242
|
*
|
243
|
+
* OR
|
244
|
+
*
|
245
|
+
* <radialGradient id="radialGrad1">
|
246
|
+
* <stop offset="0%" stop-color="white" stop-opacity="1" />
|
247
|
+
* <stop offset="50%" stop-color="black" stop-opacity="0.5" />
|
248
|
+
* <stop offset="100%" stop-color="white" stop-opacity="1" />
|
249
|
+
* </radialGradient>
|
250
|
+
*
|
251
|
+
* OR
|
252
|
+
*
|
253
|
+
* <radialGradient id="radialGrad2">
|
254
|
+
* <stop offset="0" stop-color="rgb(255,255,255)" />
|
255
|
+
* <stop offset="0.5" stop-color="rgb(0,0,0)" />
|
256
|
+
* <stop offset="1" stop-color="rgb(255,255,255)" />
|
257
|
+
* </radialGradient>
|
258
|
+
*
|
111
259
|
*/
|
112
260
|
|
113
261
|
var colorStopEls = el.getElementsByTagName('stop'),
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
y1: el.getAttribute('y1') || 0,
|
119
|
-
x2: el.getAttribute('x2') || '100%',
|
120
|
-
y2: el.getAttribute('y2') || 0
|
121
|
-
};
|
262
|
+
type = (el.nodeName === 'linearGradient' ? 'linear' : 'radial'),
|
263
|
+
gradientUnits = el.getAttribute('gradientUnits') || 'objectBoundingBox',
|
264
|
+
colorStops = [],
|
265
|
+
coords = { };
|
122
266
|
|
123
|
-
|
124
|
-
|
125
|
-
|
267
|
+
if (type === 'linear') {
|
268
|
+
coords = {
|
269
|
+
x1: el.getAttribute('x1') || 0,
|
270
|
+
y1: el.getAttribute('y1') || 0,
|
271
|
+
x2: el.getAttribute('x2') || '100%',
|
272
|
+
y2: el.getAttribute('y2') || 0
|
273
|
+
};
|
274
|
+
}
|
275
|
+
else if (type === 'radial') {
|
276
|
+
coords = {
|
277
|
+
x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%',
|
278
|
+
y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%',
|
279
|
+
r1: 0,
|
280
|
+
x2: el.getAttribute('cx') || '50%',
|
281
|
+
y2: el.getAttribute('cy') || '50%',
|
282
|
+
r2: el.getAttribute('r') || '50%'
|
283
|
+
};
|
284
|
+
}
|
126
285
|
|
127
|
-
|
128
|
-
|
129
|
-
colorStops[offset] = getColorStopFromStyle(el) || el.getAttribute('stop-color');
|
286
|
+
for (var i = colorStopEls.length; i--; ) {
|
287
|
+
colorStops.push(getColorStop(colorStopEls[i]));
|
130
288
|
}
|
131
289
|
|
132
290
|
_convertPercentUnitsToValues(instance, coords);
|
133
291
|
|
134
292
|
return new fabric.Gradient({
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
y2: coords.y2,
|
293
|
+
type: type,
|
294
|
+
coords: coords,
|
295
|
+
gradientUnits: gradientUnits,
|
139
296
|
colorStops: colorStops
|
140
297
|
});
|
141
298
|
},
|
299
|
+
/* _FROM_SVG_END_ */
|
142
300
|
|
143
301
|
/**
|
144
302
|
* Returns {@link fabric.Gradient} instance from its object representation
|
145
|
-
* @method forObject
|
146
303
|
* @static
|
147
|
-
* @param obj
|
148
|
-
* @param [options]
|
304
|
+
* @param {Object} obj
|
305
|
+
* @param {Object} [options] Options object
|
149
306
|
* @memberof fabric.Gradient
|
150
307
|
*/
|
151
308
|
forObject: function(obj, options) {
|
@@ -155,11 +312,14 @@
|
|
155
312
|
}
|
156
313
|
});
|
157
314
|
|
315
|
+
/**
|
316
|
+
* @private
|
317
|
+
*/
|
158
318
|
function _convertPercentUnitsToValues(object, options) {
|
159
319
|
for (var prop in options) {
|
160
320
|
if (typeof options[prop] === 'string' && /^\d+%$/.test(options[prop])) {
|
161
321
|
var percents = parseFloat(options[prop], 10);
|
162
|
-
if (prop === 'x1' || prop === 'x2') {
|
322
|
+
if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
|
163
323
|
options[prop] = fabric.util.toFixed(object.width * percents / 100, 2);
|
164
324
|
}
|
165
325
|
else if (prop === 'y1' || prop === 'y2') {
|
@@ -176,36 +336,28 @@
|
|
176
336
|
}
|
177
337
|
}
|
178
338
|
|
339
|
+
/* _TO_SVG_START_ */
|
179
340
|
/**
|
180
|
-
*
|
181
|
-
* @static
|
182
|
-
* @function
|
183
|
-
* @memberOf fabric
|
184
|
-
* @method getGradientDefs
|
185
|
-
* @param {SVGDocument} doc SVG document to parse
|
186
|
-
* @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element
|
341
|
+
* @private
|
187
342
|
*/
|
188
|
-
function
|
189
|
-
var
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
343
|
+
function _convertValuesToPercentUnits(object, options) {
|
344
|
+
for (var prop in options) {
|
345
|
+
// normalize rendering point (should be from center rather than top/left corner of the shape)
|
346
|
+
if (prop === 'x1' || prop === 'x2') {
|
347
|
+
options[prop] += fabric.util.toFixed(object.width / 2, 2);
|
348
|
+
}
|
349
|
+
else if (prop === 'y1' || prop === 'y2') {
|
350
|
+
options[prop] += fabric.util.toFixed(object.height / 2, 2);
|
351
|
+
}
|
352
|
+
// convert to percent units
|
353
|
+
if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
|
354
|
+
options[prop] = fabric.util.toFixed(options[prop] / object.width * 100, 2) + '%';
|
355
|
+
}
|
356
|
+
else if (prop === 'y1' || prop === 'y2') {
|
357
|
+
options[prop] = fabric.util.toFixed(options[prop] / object.height * 100, 2) + '%';
|
358
|
+
}
|
204
359
|
}
|
205
|
-
|
206
|
-
return gradientDefs;
|
207
360
|
}
|
361
|
+
/* _TO_SVG_END_ */
|
208
362
|
|
209
|
-
|
210
|
-
|
211
|
-
})();
|
363
|
+
})();
|