|
| 1 | +(function(global) { |
| 2 | + |
| 3 | + 'use strict'; |
| 4 | + |
| 5 | + var fabric = global.fabric || (global.fabric = { }), |
| 6 | + filters = fabric.Image.filters, |
| 7 | + createClass = fabric.util.createClass; |
| 8 | + |
| 9 | + /** |
| 10 | + * Vibrance filter class |
| 11 | + * @class fabric.Image.filters.Vibrance |
| 12 | + * @memberOf fabric.Image.filters |
| 13 | + * @extends fabric.Image.filters.BaseFilter |
| 14 | + * @see {@link fabric.Image.filters.Vibrance#initialize} for constructor definition |
| 15 | + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} |
| 16 | + * @example |
| 17 | + * var filter = new fabric.Image.filters.Vibrance({ |
| 18 | + * vibrance: 1 |
| 19 | + * }); |
| 20 | + * object.filters.push(filter); |
| 21 | + * object.applyFilters(); |
| 22 | + */ |
| 23 | + filters.Vibrance = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Vibrance.prototype */ { |
| 24 | + |
| 25 | + /** |
| 26 | + * Filter type |
| 27 | + * @param {String} type |
| 28 | + * @default |
| 29 | + */ |
| 30 | + type: 'Vibrance', |
| 31 | + |
| 32 | + fragmentSource: 'precision highp float;\n' + |
| 33 | + 'uniform sampler2D uTexture;\n' + |
| 34 | + 'uniform float uVibrance;\n' + |
| 35 | + 'varying vec2 vTexCoord;\n' + |
| 36 | + 'void main() {\n' + |
| 37 | + 'vec4 color = texture2D(uTexture, vTexCoord);\n' + |
| 38 | + 'float max = max(color.r, max(color.g, color.b));\n' + |
| 39 | + 'float avg = (color.r + color.g + color.b) / 3.0;\n' + |
| 40 | + 'float amt = (abs(max - avg) * 2.0) * uVibrance;\n' + |
| 41 | + 'color.r += max != color.r ? (max - color.r) * amt : 0.00;\n' + |
| 42 | + 'color.g += max != color.g ? (max - color.g) * amt : 0.00;\n' + |
| 43 | + 'color.b += max != color.b ? (max - color.b) * amt : 0.00;\n' + |
| 44 | + 'gl_FragColor = color;\n' + |
| 45 | + '}', |
| 46 | + |
| 47 | + /** |
| 48 | + * Vibrance value, from -1 to 1. |
| 49 | + * Increases/decreases the saturation of more muted colors with less effect on saturated colors. |
| 50 | + * A value of 0 has no effect. |
| 51 | + * |
| 52 | + * @param {Number} vibrance |
| 53 | + * @default |
| 54 | + */ |
| 55 | + vibrance: 0, |
| 56 | + |
| 57 | + mainParameter: 'vibrance', |
| 58 | + |
| 59 | + /** |
| 60 | + * Constructor |
| 61 | + * @memberOf fabric.Image.filters.Vibrance.prototype |
| 62 | + * @param {Object} [options] Options object |
| 63 | + * @param {Number} [options.vibrance=0] Vibrance value for the image (between -1 and 1) |
| 64 | + */ |
| 65 | + |
| 66 | + /** |
| 67 | + * Apply the Vibrance operation to a Uint8ClampedArray representing the pixels of an image. |
| 68 | + * |
| 69 | + * @param {Object} options |
| 70 | + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. |
| 71 | + */ |
| 72 | + applyTo2d: function(options) { |
| 73 | + if (this.vibrance === 0) { |
| 74 | + return; |
| 75 | + } |
| 76 | + var imageData = options.imageData, |
| 77 | + data = imageData.data, len = data.length, |
| 78 | + adjust = -this.vibrance, i, max, avg, amt; |
| 79 | + |
| 80 | + for (i = 0; i < len; i += 4) { |
| 81 | + max = Math.max(data[i], data[i + 1], data[i + 2]); |
| 82 | + avg = (data[i] + data[i + 1] + data[i + 2]) / 3; |
| 83 | + amt = ((Math.abs(max - avg) * 2 / 255) * adjust); |
| 84 | + data[i] += max !== data[i] ? (max - data[i]) * amt : 0; |
| 85 | + data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * amt : 0; |
| 86 | + data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * amt : 0; |
| 87 | + } |
| 88 | + }, |
| 89 | + |
| 90 | + /** |
| 91 | + * Return WebGL uniform locations for this filter's shader. |
| 92 | + * |
| 93 | + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. |
| 94 | + * @param {WebGLShaderProgram} program This filter's compiled shader program. |
| 95 | + */ |
| 96 | + getUniformLocations: function(gl, program) { |
| 97 | + return { |
| 98 | + uVibrance: gl.getUniformLocation(program, 'uVibrance'), |
| 99 | + }; |
| 100 | + }, |
| 101 | + |
| 102 | + /** |
| 103 | + * Send data from this filter to its shader program's uniforms. |
| 104 | + * |
| 105 | + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. |
| 106 | + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects |
| 107 | + */ |
| 108 | + sendUniformData: function(gl, uniformLocations) { |
| 109 | + gl.uniform1f(uniformLocations.uVibrance, -this.vibrance); |
| 110 | + }, |
| 111 | + }); |
| 112 | + |
| 113 | + /** |
| 114 | + * Returns filter instance from an object representation |
| 115 | + * @static |
| 116 | + * @param {Object} object Object to create an instance from |
| 117 | + * @param {Function} [callback] to be invoked after filter creation |
| 118 | + * @return {fabric.Image.filters.Vibrance} Instance of fabric.Image.filters.Vibrance |
| 119 | + */ |
| 120 | + fabric.Image.filters.Vibrance.fromObject = fabric.Image.filters.BaseFilter.fromObject; |
| 121 | + |
| 122 | +})(typeof exports !== 'undefined' ? exports : this); |
0 commit comments