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.
Files changed (76) hide show
  1. data/CHANGELOG.md +4 -0
  2. data/README.md +1 -1
  3. data/lib/fabric/rails/version.rb +2 -2
  4. data/vendor/assets/javascripts/cufon.js +1226 -0
  5. data/vendor/assets/javascripts/event.js +20 -20
  6. data/vendor/assets/javascripts/excanvas.js +1464 -0
  7. data/vendor/assets/javascripts/fabric.js +56 -33
  8. data/vendor/assets/javascripts/fabric/HEADER.js +2 -4
  9. data/vendor/assets/javascripts/fabric/brushes/base_brush.class.js +96 -0
  10. data/vendor/assets/javascripts/fabric/brushes/circle_brush.class.js +99 -0
  11. data/vendor/assets/javascripts/fabric/brushes/pattern_brush.class.js +55 -0
  12. data/vendor/assets/javascripts/fabric/{freedrawing.class.js → brushes/pencil_brush.class.js} +73 -65
  13. data/vendor/assets/javascripts/fabric/brushes/spray_brush.class.js +157 -0
  14. data/vendor/assets/javascripts/fabric/canvas.class.js +154 -135
  15. data/vendor/assets/javascripts/fabric/color.class.js +195 -29
  16. data/vendor/assets/javascripts/fabric/filters/brightness_filter.class.js +70 -0
  17. data/vendor/assets/javascripts/fabric/filters/convolute_filter.class.js +122 -0
  18. data/vendor/assets/javascripts/fabric/filters/gradienttransparency_filter.class.js +69 -0
  19. data/vendor/assets/javascripts/fabric/filters/grayscale_filter.class.js +61 -0
  20. data/vendor/assets/javascripts/fabric/filters/invert_filter.class.js +57 -0
  21. data/vendor/assets/javascripts/fabric/filters/noise_filter.class.js +73 -0
  22. data/vendor/assets/javascripts/fabric/filters/pixelate_filter.class.js +98 -0
  23. data/vendor/assets/javascripts/fabric/filters/removewhite_filter.class.js +86 -0
  24. data/vendor/assets/javascripts/fabric/filters/sepia2_filter.class.js +61 -0
  25. data/vendor/assets/javascripts/fabric/filters/sepia_filter.class.js +58 -0
  26. data/vendor/assets/javascripts/fabric/filters/tint_filter.class.js +80 -0
  27. data/vendor/assets/javascripts/fabric/gradient.class.js +232 -80
  28. data/vendor/assets/javascripts/fabric/intersection.class.js +10 -28
  29. data/vendor/assets/javascripts/fabric/log.js +0 -2
  30. data/vendor/assets/javascripts/fabric/{canvas_animation.mixin.js → mixins/canvas_animation.mixin.js} +3 -6
  31. data/vendor/assets/javascripts/fabric/mixins/canvas_dataurl_exporter.mixin.js +137 -0
  32. data/vendor/assets/javascripts/fabric/{canvas_events.mixin.js → mixins/canvas_events.mixin.js} +97 -144
  33. data/vendor/assets/javascripts/fabric/{canvas_gestures.mixin.js → mixins/canvas_gestures.mixin.js} +4 -8
  34. data/vendor/assets/javascripts/fabric/{canvas_serialization.mixin.js → mixins/canvas_serialization.mixin.js} +19 -14
  35. data/vendor/assets/javascripts/fabric/mixins/collection.mixin.js +137 -0
  36. data/vendor/assets/javascripts/fabric/{object_geometry.mixin.js → mixins/object_geometry.mixin.js} +130 -47
  37. data/vendor/assets/javascripts/fabric/{object_interactivity.mixin.js → mixins/object_interactivity.mixin.js} +21 -102
  38. data/vendor/assets/javascripts/fabric/{object_origin.mixin.js → mixins/object_origin.mixin.js} +36 -26
  39. data/vendor/assets/javascripts/fabric/{object_straightening.mixin.js → mixins/object_straightening.mixin.js} +4 -9
  40. data/vendor/assets/javascripts/fabric/{observable.mixin.js → mixins/observable.mixin.js} +27 -35
  41. data/vendor/assets/javascripts/fabric/mixins/stateful.mixin.js +45 -0
  42. data/vendor/assets/javascripts/fabric/node.js +62 -26
  43. data/vendor/assets/javascripts/fabric/parser.js +181 -58
  44. data/vendor/assets/javascripts/fabric/pattern.class.js +43 -14
  45. data/vendor/assets/javascripts/fabric/point.class.js +4 -43
  46. data/vendor/assets/javascripts/fabric/shadow.class.js +19 -19
  47. data/vendor/assets/javascripts/fabric/{circle.class.js → shapes/circle.class.js} +32 -29
  48. data/vendor/assets/javascripts/fabric/{ellipse.class.js → shapes/ellipse.class.js} +45 -27
  49. data/vendor/assets/javascripts/fabric/{group.class.js → shapes/group.class.js} +67 -169
  50. data/vendor/assets/javascripts/fabric/{image.class.js → shapes/image.class.js} +134 -72
  51. data/vendor/assets/javascripts/fabric/{line.class.js → shapes/line.class.js} +67 -36
  52. data/vendor/assets/javascripts/fabric/{object.class.js → shapes/object.class.js} +394 -252
  53. data/vendor/assets/javascripts/fabric/{path.class.js → shapes/path.class.js} +89 -174
  54. data/vendor/assets/javascripts/fabric/{path_group.class.js → shapes/path_group.class.js} +12 -18
  55. data/vendor/assets/javascripts/fabric/{polygon.class.js → shapes/polygon.class.js} +64 -38
  56. data/vendor/assets/javascripts/fabric/{polyline.class.js → shapes/polyline.class.js} +64 -39
  57. data/vendor/assets/javascripts/fabric/{rect.class.js → shapes/rect.class.js} +78 -112
  58. data/vendor/assets/javascripts/fabric/{text.class.js → shapes/text.class.js} +264 -270
  59. data/vendor/assets/javascripts/fabric/shapes/text.cufon.js +79 -0
  60. data/vendor/assets/javascripts/fabric/{triangle.class.js → shapes/triangle.class.js} +46 -26
  61. data/vendor/assets/javascripts/fabric/static_canvas.class.js +134 -358
  62. data/vendor/assets/javascripts/fabric/util/anim_ease.js +2 -31
  63. data/vendor/assets/javascripts/fabric/util/dom_event.js +21 -7
  64. data/vendor/assets/javascripts/fabric/util/dom_misc.js +49 -39
  65. data/vendor/assets/javascripts/fabric/util/dom_request.js +1 -2
  66. data/vendor/assets/javascripts/fabric/util/dom_style.js +1 -2
  67. data/vendor/assets/javascripts/fabric/util/lang_array.js +19 -13
  68. data/vendor/assets/javascripts/fabric/util/lang_class.js +1 -2
  69. data/vendor/assets/javascripts/fabric/util/lang_function.js +3 -1
  70. data/vendor/assets/javascripts/fabric/util/lang_object.js +5 -5
  71. data/vendor/assets/javascripts/fabric/util/lang_string.js +7 -5
  72. data/vendor/assets/javascripts/fabric/util/misc.js +207 -42
  73. metadata +47 -29
  74. data/vendor/assets/javascripts/fabric/image_filters.js +0 -809
  75. data/vendor/assets/javascripts/fabric/scout.js +0 -45
  76. data/vendor/assets/javascripts/fabric/stateful.js +0 -88
@@ -14,8 +14,7 @@
14
14
  * The purpose of {@link fabric.Color} is to abstract and encapsulate common color operations;
15
15
  * {@link fabric.Color} is a constructor and creates instances of {@link fabric.Color} objects.
16
16
  *
17
- * @class Color
18
- * @memberOf fabric
17
+ * @class fabric.Color
19
18
  * @param {String} color optional in hex or rgb(a) format
20
19
  * @return {fabric.Color} thisArg
21
20
  */
@@ -30,25 +29,78 @@
30
29
 
31
30
  fabric.Color = Color;
32
31
 
33
- fabric.Color.prototype = /** @scope fabric.Color.prototype */ {
32
+ fabric.Color.prototype = /** @lends fabric.Color.prototype */ {
34
33
 
35
34
  /**
36
35
  * @private
37
- * @method _tryParsingColor
36
+ * @param {String|Array} color Color value to parse
38
37
  */
39
38
  _tryParsingColor: function(color) {
40
- var source = Color.sourceFromHex(color);
39
+ var source;
40
+
41
+ if (color in Color.colorNameMap) {
42
+ color = Color.colorNameMap[color];
43
+ }
44
+
45
+ source = Color.sourceFromHex(color);
46
+
41
47
  if (!source) {
42
48
  source = Color.sourceFromRgb(color);
43
49
  }
50
+ if (!source) {
51
+ source = Color.sourceFromHsl(color);
52
+ }
44
53
  if (source) {
45
54
  this.setSource(source);
46
55
  }
47
56
  },
48
57
 
58
+ /**
59
+ * Adapted from <a href="https://rawgithub.com/mjijackson/mjijackson.github.com/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.html">https://github.com/mjijackson</a>
60
+ * @private
61
+ * @param {Number} r Red color value
62
+ * @param {Number} g Green color value
63
+ * @param {Number} b Blue color value
64
+ * @return {Array} Hsl color
65
+ */
66
+ _rgbToHsl: function(r, g, b) {
67
+ r /= 255, g /= 255, b /= 255;
68
+
69
+ var h, s, l,
70
+ max = fabric.util.array.max([r, g, b]),
71
+ min = fabric.util.array.min([r, g, b]);
72
+
73
+ l = (max + min) / 2;
74
+
75
+ if (max === min) {
76
+ h = s = 0; // achromatic
77
+ }
78
+ else {
79
+ var d = max - min;
80
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
81
+ switch (max) {
82
+ case r:
83
+ h = (g - b) / d + (g < b ? 6 : 0);
84
+ break;
85
+ case g:
86
+ h = (b - r) / d + 2;
87
+ break;
88
+ case b:
89
+ h = (r - g) / d + 4;
90
+ break;
91
+ }
92
+ h /= 6;
93
+ }
94
+
95
+ return [
96
+ Math.round(h * 360),
97
+ Math.round(s * 100),
98
+ Math.round(l * 100)
99
+ ];
100
+ },
101
+
49
102
  /**
50
103
  * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1])
51
- * @method getSource
52
104
  * @return {Array}
53
105
  */
54
106
  getSource: function() {
@@ -57,7 +109,6 @@
57
109
 
58
110
  /**
59
111
  * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1])
60
- * @method setSource
61
112
  * @param {Array} source
62
113
  */
63
114
  setSource: function(source) {
@@ -66,7 +117,6 @@
66
117
 
67
118
  /**
68
119
  * Returns color represenation in RGB format
69
- * @method toRgb
70
120
  * @return {String} ex: rgb(0-255,0-255,0-255)
71
121
  */
72
122
  toRgb: function() {
@@ -76,7 +126,6 @@
76
126
 
77
127
  /**
78
128
  * Returns color represenation in RGBA format
79
- * @method toRgba
80
129
  * @return {String} ex: rgba(0-255,0-255,0-255,0-1)
81
130
  */
82
131
  toRgba: function() {
@@ -84,9 +133,30 @@
84
133
  return 'rgba(' + source[0] + ',' + source[1] + ',' + source[2] + ',' + source[3] + ')';
85
134
  },
86
135
 
136
+ /**
137
+ * Returns color represenation in HSL format
138
+ * @return {String} ex: hsl(0-360,0%-100%,0%-100%)
139
+ */
140
+ toHsl: function() {
141
+ var source = this.getSource(),
142
+ hsl = this._rgbToHsl(source[0], source[1], source[2]);
143
+
144
+ return 'hsl(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%)';
145
+ },
146
+
147
+ /**
148
+ * Returns color represenation in HSLA format
149
+ * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1)
150
+ */
151
+ toHsla: function() {
152
+ var source = this.getSource(),
153
+ hsl = this._rgbToHsl(source[0], source[1], source[2]);
154
+
155
+ return 'hsla(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%,' + source[3] + ')';
156
+ },
157
+
87
158
  /**
88
159
  * Returns color represenation in HEX format
89
- * @method toHex
90
160
  * @return {String} ex: FF5555
91
161
  */
92
162
  toHex: function() {
@@ -106,7 +176,6 @@
106
176
 
107
177
  /**
108
178
  * Gets value of alpha channel for this color
109
- * @method getAlpha
110
179
  * @return {Number} 0-1
111
180
  */
112
181
  getAlpha: function() {
@@ -115,8 +184,7 @@
115
184
 
116
185
  /**
117
186
  * Sets value of alpha channel for this color
118
- * @method setAlpha
119
- * @param {Number} 0-1
187
+ * @param {Number} alpha 0-1
120
188
  * @return {fabric.Color} thisArg
121
189
  */
122
190
  setAlpha: function(alpha) {
@@ -128,7 +196,6 @@
128
196
 
129
197
  /**
130
198
  * Transforms color to its grayscale representation
131
- * @method toGrayscale
132
199
  * @return {fabric.Color} thisArg
133
200
  */
134
201
  toGrayscale: function() {
@@ -141,7 +208,7 @@
141
208
 
142
209
  /**
143
210
  * Transforms color to its black and white representation
144
- * @method toGrayscale
211
+ * @param {Number} threshold
145
212
  * @return {fabric.Color} thisArg
146
213
  */
147
214
  toBlackWhite: function(threshold) {
@@ -158,7 +225,6 @@
158
225
 
159
226
  /**
160
227
  * Overlays color with another color
161
- * @method overlayWith
162
228
  * @param {String|fabric.Color} otherColor
163
229
  * @return {fabric.Color} thisArg
164
230
  */
@@ -184,11 +250,18 @@
184
250
  };
185
251
 
186
252
  /**
187
- * Regex matching color in RGB or RGBA formats (ex: rgb(0, 0, 0), rgb(255, 100, 10, 0.5), rgb(1,1,1))
253
+ * Regex matching color in RGB or RGBA formats (ex: rgb(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5))
254
+ * @static
255
+ * @field
256
+ */
257
+ fabric.Color.reRGBa = /^rgba?\(\s*(\d{1,3}\%?)\s*,\s*(\d{1,3}\%?)\s*,\s*(\d{1,3}\%?)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/;
258
+
259
+ /**
260
+ * Regex matching color in HSL or HSLA formats (ex: hsl(200, 80%, 10%), hsla(300, 50%, 80%, 0.5), hsla( 300 , 50% , 80% , 0.5 ))
188
261
  * @static
189
262
  * @field
190
263
  */
191
- fabric.Color.reRGBa = /^rgba?\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(\d+(?:\.\d+)?))?\)$/;
264
+ fabric.Color.reHSLa = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/;
192
265
 
193
266
  /**
194
267
  * Regex matching color in HEX format (ex: #FF5555, 010155, aff)
@@ -197,9 +270,48 @@
197
270
  */
198
271
  fabric.Color.reHex = /^#?([0-9a-f]{6}|[0-9a-f]{3})$/i;
199
272
 
273
+ /**
274
+ * Map of the 16 basic color names with HEX code
275
+ * @static
276
+ * @field
277
+ */
278
+ fabric.Color.colorNameMap = {
279
+ 'aqua': '#00FFFF',
280
+ 'black': '#000000',
281
+ 'blue': '#0000FF',
282
+ 'fuchsia': '#FF00FF',
283
+ 'gray': '#808080',
284
+ 'green': '#008000',
285
+ 'lime': '#00FF00',
286
+ 'maroon': '#800000',
287
+ 'navy': '#000080',
288
+ 'olive': '#808000',
289
+ 'purple': '#800080',
290
+ 'red': '#FF0000',
291
+ 'silver': '#C0C0C0',
292
+ 'teal': '#008080',
293
+ 'white': '#FFFFFF',
294
+ 'yellow': '#FFFF00'
295
+ };
296
+
297
+ /**
298
+ * @private
299
+ * @param {Number} p
300
+ * @param {Number} q
301
+ * @param {Number} t
302
+ * @return {Number}
303
+ */
304
+ function hue2rgb(p, q, t){
305
+ if(t < 0) t += 1;
306
+ if(t > 1) t -= 1;
307
+ if(t < 1/6) return p + (q - p) * 6 * t;
308
+ if(t < 1/2) return q;
309
+ if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
310
+ return p;
311
+ }
312
+
200
313
  /**
201
314
  * Returns new color object, when given a color in RGB format
202
- * @method fromRgb
203
315
  * @param {String} color ex: rgb(0-255,0-255,0-255)
204
316
  * @return {fabric.Color}
205
317
  */
@@ -209,17 +321,20 @@
209
321
 
210
322
  /**
211
323
  * Returns array represenatation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format
212
- * @method sourceFromRgb
213
- * @param {String} color ex: rgb(0-255,0-255,0-255)
324
+ * @param {String} color ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%)
214
325
  * @return {Array} source
215
326
  */
216
327
  fabric.Color.sourceFromRgb = function(color) {
217
328
  var match = color.match(Color.reRGBa);
218
329
  if (match) {
330
+ var r = parseInt(match[1], 10) / (/%$/.test(match[1]) ? 100 : 1) * (/%$/.test(match[1]) ? 255 : 1),
331
+ g = parseInt(match[2], 10) / (/%$/.test(match[2]) ? 100 : 1) * (/%$/.test(match[2]) ? 255 : 1),
332
+ b = parseInt(match[3], 10) / (/%$/.test(match[3]) ? 100 : 1) * (/%$/.test(match[3]) ? 255 : 1);
333
+
219
334
  return [
220
- parseInt(match[1], 10),
221
- parseInt(match[2], 10),
222
- parseInt(match[3], 10),
335
+ parseInt(r, 10),
336
+ parseInt(g, 10),
337
+ parseInt(b, 10),
223
338
  match[4] ? parseFloat(match[4]) : 1
224
339
  ];
225
340
  }
@@ -229,16 +344,68 @@
229
344
  * Returns new color object, when given a color in RGBA format
230
345
  * @static
231
346
  * @function
232
- * @method fromRgba
233
347
  * @param {String} color
234
348
  * @return {fabric.Color}
235
349
  */
236
350
  fabric.Color.fromRgba = Color.fromRgb;
237
351
 
352
+ /**
353
+ * Returns new color object, when given a color in HSL format
354
+ * @param {String} color ex: hsl(0-260,0%-100%,0%-100%)
355
+ * @return {fabric.Color}
356
+ */
357
+ fabric.Color.fromHsl = function(color) {
358
+ return Color.fromSource(Color.sourceFromHsl(color));
359
+ };
360
+
361
+ /**
362
+ * Returns array represenatation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format.
363
+ * Adapted from <a href="https://rawgithub.com/mjijackson/mjijackson.github.com/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.html">https://github.com/mjijackson</a>
364
+ * @param {String} color ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1)
365
+ * @return {Array} source
366
+ * @see http://http://www.w3.org/TR/css3-color/#hsl-color
367
+ */
368
+ fabric.Color.sourceFromHsl = function(color) {
369
+ var match = color.match(Color.reHSLa);
370
+ if (!match) return;
371
+
372
+ var h = (((parseFloat(match[1]) % 360) + 360) % 360) / 360,
373
+ s = parseFloat(match[2]) / (/%$/.test(match[2]) ? 100 : 1),
374
+ l = parseFloat(match[3]) / (/%$/.test(match[3]) ? 100 : 1),
375
+ r, g, b;
376
+
377
+ if (s === 0) {
378
+ r = g = b = l;
379
+ }
380
+ else {
381
+ var q = l <= 0.5 ? l * (s + 1) : l + s - l * s;
382
+ var p = l * 2 - q;
383
+
384
+ r = hue2rgb(p, q, h + 1/3);
385
+ g = hue2rgb(p, q, h);
386
+ b = hue2rgb(p, q, h - 1/3);
387
+ }
388
+
389
+ return [
390
+ Math.round(r * 255),
391
+ Math.round(g * 255),
392
+ Math.round(b * 255),
393
+ match[4] ? parseFloat(match[4]) : 1
394
+ ];
395
+ };
396
+
397
+ /**
398
+ * Returns new color object, when given a color in HSLA format
399
+ * @static
400
+ * @function
401
+ * @param {String} color
402
+ * @return {fabric.Color}
403
+ */
404
+ fabric.Color.fromHsla = Color.fromHsl;
405
+
238
406
  /**
239
407
  * Returns new color object, when given a color in HEX format
240
408
  * @static
241
- * @method fromHex
242
409
  * @return {fabric.Color}
243
410
  */
244
411
  fabric.Color.fromHex = function(color) {
@@ -248,7 +415,6 @@
248
415
  /**
249
416
  * Returns array represenatation (ex: [100, 100, 200, 1]) of a color that's in HEX format
250
417
  * @static
251
- * @method sourceFromHex
252
418
  * @param {String} color ex: FF5555
253
419
  * @return {Array} source
254
420
  */
@@ -272,7 +438,7 @@
272
438
  /**
273
439
  * Returns new color object, when given color in array representation (ex: [200, 100, 100, 0.5])
274
440
  * @static
275
- * @method fromSource
441
+ * @param {Array} source
276
442
  * @return {fabric.Color}
277
443
  */
278
444
  fabric.Color.fromSource = function(source) {
@@ -281,4 +447,4 @@
281
447
  return oColor;
282
448
  };
283
449
 
284
- })(typeof exports !== 'undefined' ? exports : this);
450
+ })(typeof exports !== 'undefined' ? exports : this);
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @namespace fabric.Image.filters
3
+ * @memberOf fabric.Image
4
+ */
5
+ fabric.Image.filters = fabric.Image.filters || { };
6
+
7
+ /**
8
+ * Brightness filter class
9
+ * @class fabric.Image.filters.Brightness
10
+ * @memberOf fabric.Image.filters
11
+ */
12
+ fabric.Image.filters.Brightness = fabric.util.createClass(/** @lends fabric.Image.filters.Brightness.prototype */ {
13
+
14
+ /**
15
+ * Filter type
16
+ * @param {String} type
17
+ * @default
18
+ */
19
+ type: 'Brightness',
20
+
21
+ /**
22
+ * Constructor
23
+ * @memberOf fabric.Image.filters.Brightness.prototype
24
+ * @param {Object} [options] Options object
25
+ */
26
+ initialize: function(options) {
27
+ options = options || { };
28
+ this.brightness = options.brightness || 100;
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
+ brightness = this.brightness;
40
+
41
+ for (var i = 0, len = data.length; i < len; i += 4) {
42
+ data[i] += brightness;
43
+ data[i + 1] += brightness;
44
+ data[i + 2] += brightness;
45
+ }
46
+
47
+ context.putImageData(imageData, 0, 0);
48
+ },
49
+
50
+ /**
51
+ * Returns json representation of filter
52
+ * @return {String} json representation of filter
53
+ */
54
+ toJSON: function() {
55
+ return {
56
+ type: this.type,
57
+ brightness: this.brightness
58
+ };
59
+ }
60
+ });
61
+
62
+ /**
63
+ * Returns filter instance from an object representation
64
+ * @static
65
+ * @param {Object} object Object to create an instance from
66
+ * @return {fabric.Image.filters.Brightness} Instance of fabric.Image.filters.Brightness
67
+ */
68
+ fabric.Image.filters.Brightness.fromObject = function(object) {
69
+ return new fabric.Image.filters.Brightness(object);
70
+ };
@@ -0,0 +1,122 @@
1
+ /**
2
+ * @namespace fabric.Image.filters
3
+ * @memberOf fabric.Image
4
+ */
5
+ fabric.Image.filters = fabric.Image.filters || { };
6
+
7
+ /**
8
+ * Adapted from <a href="http://www.html5rocks.com/en/tutorials/canvas/imagefilters/">html5rocks article</a>
9
+ * @class fabric.Image.filters.Convolute
10
+ * @memberOf fabric.Image.filters
11
+ */
12
+ fabric.Image.filters.Convolute = fabric.util.createClass(/** @lends fabric.Image.filters.Convolute.prototype */ {
13
+
14
+ /**
15
+ * Filter type
16
+ * @param {String} type
17
+ * @default
18
+ */
19
+ type: 'Convolute',
20
+
21
+ /**
22
+ * Constructor
23
+ * @memberOf fabric.Image.filters.Convolute.prototype
24
+ * @param {Object} [options] Options object
25
+ */
26
+ initialize: function(options) {
27
+ options = options || { };
28
+
29
+ this.opaque = options.opaque;
30
+ this.matrix = options.matrix || [ 0, 0, 0,
31
+ 0, 1, 0,
32
+ 0, 0, 0 ];
33
+
34
+ var canvasEl = fabric.util.createCanvasElement();
35
+ this.tmpCtx = canvasEl.getContext('2d');
36
+ },
37
+
38
+ /**
39
+ * @private
40
+ */
41
+ _createImageData: function(w, h) {
42
+ return this.tmpCtx.createImageData(w, h);
43
+ },
44
+
45
+ /**
46
+ * Applies filter to canvas element
47
+ * @param {Object} canvasEl Canvas element to apply filter to
48
+ */
49
+ applyTo: function(canvasEl) {
50
+ var weights = this.matrix;
51
+ var context = canvasEl.getContext('2d');
52
+ var pixels = context.getImageData(0, 0, canvasEl.width, canvasEl.height);
53
+
54
+ var side = Math.round(Math.sqrt(weights.length));
55
+ var halfSide = Math.floor(side/2);
56
+ var src = pixels.data;
57
+ var sw = pixels.width;
58
+ var sh = pixels.height;
59
+
60
+ // pad output by the convolution matrix
61
+ var w = sw;
62
+ var h = sh;
63
+ var output = this._createImageData(w, h);
64
+
65
+ var dst = output.data;
66
+
67
+ // go through the destination image pixels
68
+ var alphaFac = this.opaque ? 1 : 0;
69
+ for (var y=0; y<h; y++) {
70
+ for (var x=0; x<w; x++) {
71
+ var sy = y;
72
+ var sx = x;
73
+ var dstOff = (y*w+x)*4;
74
+ // calculate the weighed sum of the source image pixels that
75
+ // fall under the convolution matrix
76
+ var r=0, g=0, b=0, a=0;
77
+ for (var cy=0; cy<side; cy++) {
78
+ for (var cx=0; cx<side; cx++) {
79
+ var scy = sy + cy - halfSide;
80
+ var scx = sx + cx - halfSide;
81
+ if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) {
82
+ var srcOff = (scy*sw+scx)*4;
83
+ var wt = weights[cy*side+cx];
84
+ r += src[srcOff] * wt;
85
+ g += src[srcOff+1] * wt;
86
+ b += src[srcOff+2] * wt;
87
+ a += src[srcOff+3] * wt;
88
+ }
89
+ }
90
+ }
91
+ dst[dstOff] = r;
92
+ dst[dstOff+1] = g;
93
+ dst[dstOff+2] = b;
94
+ dst[dstOff+3] = a + alphaFac*(255-a);
95
+ }
96
+ }
97
+
98
+ context.putImageData(output, 0, 0);
99
+ },
100
+
101
+ /**
102
+ * Returns json representation of filter
103
+ * @return {String} json representation of filter
104
+ */
105
+ toJSON: function() {
106
+ return {
107
+ type: this.type,
108
+ opaque: this.opaque,
109
+ matrix: this.matrix
110
+ };
111
+ }
112
+ });
113
+
114
+ /**
115
+ * Returns filter instance from an object representation
116
+ * @static
117
+ * @param {Object} object Object to create an instance from
118
+ * @return {fabric.Image.filters.Convolute} Instance of fabric.Image.filters.Convolute
119
+ */
120
+ fabric.Image.filters.Convolute.fromObject = function(object) {
121
+ return new fabric.Image.filters.Convolute(object);
122
+ };