From 60e9d0f144582433bcdc7c452c2140b0452905c4 Mon Sep 17 00:00:00 2001 From: Stefan Kienzle Date: Fri, 20 Sep 2013 19:51:55 +0200 Subject: [PATCH] [BACK_INCOMPAT] Initialization of `fabric.Image.filters.Tint` is now different - options.color: color string value, options.opacity: 0..1 Now you can define opacity of the tint filter (by rgba/hsla colors or with opacity attribute) Doc additions --- src/filters/brightness_filter.class.js | 1 + src/filters/convolute_filter.class.js | 2 + .../gradienttransparency_filter.class.js | 1 + src/filters/mask_filter.class.js | 2 + src/filters/noise_filter.class.js | 1 + src/filters/pixelate_filter.class.js | 1 + src/filters/removewhite_filter.class.js | 2 + src/filters/tint_filter.class.js | 44 ++++++++++++------- test/unit/image_filters.js | 31 ++++++++++--- 9 files changed, 64 insertions(+), 21 deletions(-) diff --git a/src/filters/brightness_filter.class.js b/src/filters/brightness_filter.class.js index f447bd41..2e37d4c8 100644 --- a/src/filters/brightness_filter.class.js +++ b/src/filters/brightness_filter.class.js @@ -24,6 +24,7 @@ * Constructor * @memberOf fabric.Image.filters.Brightness.prototype * @param {Object} [options] Options object + * @param {Number} [options.brightness=100] Value to brighten the image up (0..255) */ initialize: function(options) { options = options || { }; diff --git a/src/filters/convolute_filter.class.js b/src/filters/convolute_filter.class.js index 23de87b1..e354901a 100644 --- a/src/filters/convolute_filter.class.js +++ b/src/filters/convolute_filter.class.js @@ -24,6 +24,8 @@ * Constructor * @memberOf fabric.Image.filters.Convolute.prototype * @param {Object} [options] Options object + * @param {Boolean} [options.opaque=false] Opaque value (true/false) + * @param {Array} [options.matrix] Filter matrix */ initialize: function(options) { options = options || { }; diff --git a/src/filters/gradienttransparency_filter.class.js b/src/filters/gradienttransparency_filter.class.js index 67ef41e5..3a2df791 100644 --- a/src/filters/gradienttransparency_filter.class.js +++ b/src/filters/gradienttransparency_filter.class.js @@ -24,6 +24,7 @@ * Constructor * @memberOf fabric.Image.filters.GradientTransparency * @param {Object} [options] Options object + * @param {Number} [options.threshold=100] Threshold value */ initialize: function(options) { options = options || { }; diff --git a/src/filters/mask_filter.class.js b/src/filters/mask_filter.class.js index 279ab31d..b61cf266 100644 --- a/src/filters/mask_filter.class.js +++ b/src/filters/mask_filter.class.js @@ -24,6 +24,8 @@ * Constructor * @memberOf fabric.Image.filters.Mask.prototype * @param {Object} [options] Options object + * @param {fabric.Image} [options.mask] Mask image object + * @param {Number} [options.channel=0] Rgb channel (0, 1, 2 or 3) */ initialize: function(options) { options = options || { }; diff --git a/src/filters/noise_filter.class.js b/src/filters/noise_filter.class.js index 3139fc49..a3a20c3b 100644 --- a/src/filters/noise_filter.class.js +++ b/src/filters/noise_filter.class.js @@ -24,6 +24,7 @@ * Constructor * @memberOf fabric.Image.filters.Noise.prototype * @param {Object} [options] Options object + * @param {Number} [options.noise=100] Noise value */ initialize: function(options) { options = options || { }; diff --git a/src/filters/pixelate_filter.class.js b/src/filters/pixelate_filter.class.js index 3290d9ce..6f2cf47e 100644 --- a/src/filters/pixelate_filter.class.js +++ b/src/filters/pixelate_filter.class.js @@ -24,6 +24,7 @@ * Constructor * @memberOf fabric.Image.filters.Pixelate.prototype * @param {Object} [options] Options object + * @param {Number} [options.blocksize=4] Blocksize for pixelate */ initialize: function(options) { options = options || { }; diff --git a/src/filters/removewhite_filter.class.js b/src/filters/removewhite_filter.class.js index db48b8b8..d587fd01 100644 --- a/src/filters/removewhite_filter.class.js +++ b/src/filters/removewhite_filter.class.js @@ -24,6 +24,8 @@ * Constructor * @memberOf fabric.Image.filters.RemoveWhite.prototype * @param {Object} [options] Options object + * @param {Number} [options.threshold=30] Threshold value + * @param {Number} [options.distance=20] Distance value */ initialize: function(options) { options = options || { }; diff --git a/src/filters/tint_filter.class.js b/src/filters/tint_filter.class.js index 0a11a15d..9b7534e1 100644 --- a/src/filters/tint_filter.class.js +++ b/src/filters/tint_filter.class.js @@ -7,6 +7,7 @@ /** * Tint filter class + * Adapted from https://github.com/mezzoblue/PaintbrushJS * @class fabric.Image.filters.Tint * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter @@ -24,10 +25,16 @@ * Constructor * @memberOf fabric.Image.filters.Tint.prototype * @param {Object} [options] Options object + * @param {String} [options.color=#000000] Color to tint the image with + * @param {Number} [options.opacity] Opacity value that controls the tint effect's transparency (0..1) */ initialize: function(options) { options = options || { }; - this.color = options.color || 0; + + this.color = options.color || '#000000'; + this.opacity = typeof options.opacity !== 'undefined' + ? options.opacity + : new fabric.Color(this.color).getAlpha(); }, /** @@ -38,25 +45,31 @@ var context = canvasEl.getContext('2d'), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, - iLen = data.length, i, a; + iLen = data.length, i, + tintR, tintG, tintB, + r, g, b, alpha1, + color, source; - var rgb = parseInt(this.color, 10).toString(16); + color = this.color instanceof fabric.Color + ? this.color + : new fabric.Color(this.color); + source = color.getSource(); - // Pad with leading zeros that may have been stripped off in conversion. - while (rgb.length < 6) rgb = '0' + rgb; + tintR = source[0] * this.opacity; + tintG = source[1] * this.opacity; + tintB = source[2] * this.opacity; - var cr = parseInt('0x' + rgb.substr(0, 2), 16); - var cg = parseInt('0x' + rgb.substr(2, 2), 16); - var cb = parseInt('0x' + rgb.substr(4, 2), 16); + alpha1 = 1 - this.opacity; for (i = 0; i < iLen; i+=4) { - a = data[i+3]; + r = data[i]; + g = data[i + 1]; + b = data[i + 2]; - if (a > 0){ - data[i] = cr; - data[i+1] = cg; - data[i+2] = cb; - } + // alpha compositing + data[i] = tintR + r * alpha1; + data[i + 1] = tintG + g * alpha1; + data[i + 2] = tintB + b * alpha1; } context.putImageData(imageData, 0, 0); @@ -68,7 +81,8 @@ */ toObject: function() { return extend(this.callSuper('toObject'), { - color: this.color + color: this.color, + opacity: this.opacity }); } }); diff --git a/test/unit/image_filters.js b/test/unit/image_filters.js index 9e3ec694..174ece92 100644 --- a/test/unit/image_filters.js +++ b/test/unit/image_filters.js @@ -570,10 +570,18 @@ var filter = new fabric.Image.filters.Tint(); equal(filter.type, 'Tint'); - equal(filter.color, 0); - var filter2 = new fabric.Image.filters.Tint({color: 122}); - equal(filter2.color, 122); + ok(filter.color instanceof fabric.Color, 'should inherit from fabric.Color'); + equal(filter.color, '#000000'); + equal(filter.opacity, 1); + + var filter2 = new fabric.Image.filters.Tint({color: 'rgba(0,0,255,0.5)', opacity: 0.2}); + equal(filter2.color, 'rgba(0,0,255,0.5)'); + equal(filter2.opacity, 0.2); + + var filter3 = new fabric.Image.filters.Tint({color: 'rgba(0,0,255,0.5)'}); + equal(filter3.color, 'rgba(0,0,255,0.5)'); + equal(filter3.opacity, 0.5); }); test('applyTo', function() { @@ -586,7 +594,11 @@ ok(typeof filter.toObject == 'function'); var object = filter.toObject(); - equal(JSON.stringify(object), '{"type":"Tint","color":0}'); + equal(JSON.stringify(object), '{"type":"Tint","color":"#000000","opacity":1}'); + + filter.color = '#FF00FF'; + filter.opacity = 0.2; + equal(JSON.stringify(filter.toObject()), '{"type":"Tint","color":"#FF00FF","opacity":0.2}'); }); test('toJSON', function() { @@ -594,15 +606,22 @@ ok(typeof filter.toJSON == 'function'); var json = filter.toJSON(); - equal(JSON.stringify(json), '{"type":"Tint","color":0}'); + equal(JSON.stringify(json), '{"type":"Tint","color":"#000000","opacity":1}'); + + filter.color = '#FF00FF'; + filter.opacity = 0.2; + equal(JSON.stringify(filter.toJSON()), '{"type":"Tint","color":"#FF00FF","opacity":0.2}'); }); test('fromObject', function() { var filter = new fabric.Image.filters.Tint(); var object = filter.toObject(); - deepEqual(fabric.Image.filters.Tint.fromObject(object), filter); + + filter.color = '#FF0000'; + filter.opacity = 0.8; + deepEqual(fabric.Image.filters.Tint.fromObject(filter.toObject()), filter); }); QUnit.module('fabric.Image.filters.Mask');