function ColorMatrix(m) { this._matrix = m?m.concat():ColorMatrix.IDENTITY_MATRIX.concat(); /** * Copies the supplied matrix to the internal matrix. * @param m Array **/ this.copyMatrix = function(m) { this._matrix = m.concat(); } /** * Ensures that the supplied matrix Array is of the correct length. It slices off extraneous elements, or * fills in missing elements with IDENTITY elements. * @param m Array * @return Fixed Array **/ this.fixMatrix = function(m) { if (m.length < ColorMatrix.LENGTH) { m = m.slice(0, m.length).concat(ColorMatrix.IDENTITY_MATRIX.slice(m.length,ColorMatrix.LENGTH)); } else if (m.length > ColorMatrix.LENGTH) { m = m.slice(0, ColorMatrix.LENGTH); } return m; } /** * Makes sure the incoming value in between a negative and positive limit value. * @param val The value to clean * @param limit The absolute value of the range. If the limit is 100, then the value is ensured to be between -100 and 100. * @return Number; the cleaned value. **/ this.cleanValue = function(val, limit) { return Math.min(limit, Math.max(-limit, val)); } /** * Core function for translating color adjustments to matrix arrays. The internal matrix is affected. * @param m Array **/ this.multiplyMatrix = function(m) { var col = []; for (var i=0; i<5; i++) { for (j=0; j<5; j++) { col[j] = this._matrix[j+i*5]; } for (var j=0; j<5; j++) { var val=0; for (var k=0; k<5; k++) { val += m[j+k*5]*col[k]; } this._matrix[j+i*5] = val; } } } /** * Adjusts the internal matrix array to reflect a brightness adjustment. * @param val The brightness, from -100 to 100. **/ this.adjustBrightness = function(val) { val = this.cleanValue(val,100); if (val == 0 || isNaN(val)) { return; } this.multiplyMatrix([ 1,0,0,0,val, 0,1,0,0,val, 0,0,1,0,val, 0,0,0,1,0, 0,0,0,0,1 ]); } /** * @param val The Contrast, from -100 to 100 **/ this.adjustContrast = function(val) { val = this.cleanValue(val,100); if (val == 0 || isNaN(val)) { return; } var x; if (val < 0) { x = 127 + (val / 100) * 127 } else { x = val % 1; if (x == 0) { x = ColorMatrix.DELTA_INDEX[val]; } else { //x = ColorMatrix.DELTA_INDEX[(val<<0)]; // this is how the IDE does it. x = ColorMatrix.DELTA_INDEX[(val<<0)]*(1-x)+ColorMatrix.DELTA_INDEX[(val<<0)+1]*x; // use linear interpolation for more granularity. } x = x*127+127; } this.multiplyMatrix([ x/127,0,0,0,0.5*(127-x), 0,x/127,0,0,0.5*(127-x), 0,0,x/127,0,0.5*(127-x), 0,0,0,1,0, 0,0,0,0,1 ]); } /** * @param val The Saturation, from -100 to 100 **/ this.adjustSaturation = function(val) { val = this.cleanValue(val,100); if (val == 0 || isNaN(val)) { return; } var x = 1+((val > 0) ? 3*val/100 : val/100); var lumR = 0.3086; var lumG = 0.6094; var lumB = 0.0820; this.multiplyMatrix([ lumR*(1-x)+x,lumG*(1-x),lumB*(1-x),0,0, lumR*(1-x),lumG*(1-x)+x,lumB*(1-x),0,0, lumR*(1-x),lumG*(1-x),lumB*(1-x)+x,0,0, 0,0,0,1,0, 0,0,0,0,1 ]); } /** * @param val The Hue, from -180 to 180 **/ this.adjustHue = function(val) { val = this.cleanValue(val,180)/180*Math.PI; if (val == 0 || isNaN(val)) { return; } var cosVal = Math.cos(val); var sinVal = Math.sin(val); var lumR = 0.213; var lumG = 0.715; var lumB = 0.072; this.multiplyMatrix([ lumR+cosVal*(1-lumR)+sinVal*(-lumR),lumG+cosVal*(-lumG)+sinVal*(-lumG),lumB+cosVal*(-lumB)+sinVal*(1-lumB),0,0, lumR+cosVal*(-lumR)+sinVal*(0.143),lumG+cosVal*(1-lumG)+sinVal*(0.140),lumB+cosVal*(-lumB)+sinVal*(-0.283),0,0, lumR+cosVal*(-lumR)+sinVal*(-(1-lumR)),lumG+cosVal*(-lumG)+sinVal*(lumG),lumB+cosVal*(1-lumB)+sinVal*(lumB),0,0, 0,0,0,1,0, 0,0,0,0,1 ]); } /** * Adjust all four properties at once * @param brightness (-100 - 100) * @param contrast (-100 - 100) * @param saturation (-100 - 100) * @param hue (-180 - 180) **/ this.adjustColor = function(brightness, contrast, saturation, hue) { this.adjustHue(hue); this.adjustContrast(contrast); this.adjustBrightness(brightness); this.adjustSaturation(saturation); } this.__defineGetter__("matrix", function() {return this._matrix.concat(); }); this.toString = function() { //return "ColorMatrix: " + this._matrix.toString(); var out = "ColorMatrix:\n"; var v; var iLen = this._matrix.length; var l = 4; for (var i = 0; i < iLen; i++) { v = this._matrix[i].toString(); if (v.length > l) { v = v.substr(0, l); } else { while (v.length < l) { v += " "; } } out += v; if (i % 5 == 4) { out += "\n"; } else { out += " "; } } return out; } } ColorMatrix._DELTA_INDEX = [ 0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11, 0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.20, 0.21, 0.22, 0.24, 0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42, 0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98, 1.0, 1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54, 1.60, 1.66, 1.72, 1.78, 1.84, 1.90, 1.96, 2.0, 2.12, 2.25, 2.37, 2.50, 2.62, 2.75, 2.87, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.3, 4.7, 4.9, 5.0, 5.5, 6.0, 6.5, 6.8, 7.0, 7.3, 7.5, 7.8, 8.0, 8.4, 8.7, 9.0, 9.4, 9.6, 9.8, 10.0 ]; ColorMatrix._IDENTITY_MATRIX = [ 1,0,0,0,0, 0,1,0,0,0, 0,0,1,0,0, 0,0,0,1,0, 0,0,0,0,1 ] ColorMatrix._LENGTH = ColorMatrix._IDENTITY_MATRIX.length; ColorMatrix.__defineGetter__("DELTA_INDEX", function() { return ColorMatrix._DELTA_INDEX; } ); ColorMatrix.__defineGetter__("IDENTITY_MATRIX", function() { return ColorMatrix._IDENTITY_MATRIX; } ); ColorMatrix.__defineGetter__("LENGTH", function() { return ColorMatrix._LENGTH; } ); var sel = fl.getDocumentDOM().selection; fl.outputPanel.clear(); var iLen = sel.length; var qualities = { low:1, medium:2, high:3 } for (var i = 0; i < iLen; i++) { var s = sel[i]; if (s.instanceType != "symbol") continue; // fl.trace("FILTERS FOR " + (s.name == "" ? "UNNAMED INSTANCE" : s.name) + " -------------------------------------"); var filters = s.filters; var jLen = filters.length; for (var j = 0; j < jLen; j++) { var f = filters[j]; // for (var p in f) { // fl.trace(p + " :: " + f[p]); // } var en = f.enabled ? "" : "//"; var q = qualities[f.quality]; if (f.color) { var colorInfo = getColorAndAlpha(f.color); } if (f.highlightColor) { var highlightColorInfo = getColorAndAlpha(f.highlightColor); } if (f.shadowColor) { var shadowColorInfo = getColorAndAlpha(f.shadowColor); } if (f.colorArray) { var colorArray = []; var alphaArray = []; var iLen = f.colorArray.length; for (var i = 0; i < iLen; i++) { var info = getColorAndAlpha(f.colorArray[i]); colorArray.push(info.color); alphaArray.push (info.alpha); } } var s = f.strength / 100; switch (f.name) { case "glowFilter": fl.trace(en + "new GlowFilter("+colorInfo.color+", "+colorInfo.alpha+", "+f.blurX+", "+f.blurY+", "+s+", "+q+", "+f.inner+", "+f.knockout+");"); break; case "dropShadowFilter": fl.trace(en + "new DropShadowFilter("+f.distance+", "+f.angle+", "+colorInfo.color+", "+colorInfo.alpha+", "+f.blurX+", "+f.blurY+", "+s+", "+q+", "+f.inner+", "+f.knockout+", "+f.hideObject+");"); break; case "blurFilter": fl.trace(en + "new BlurFilter("+f.blurX+", "+f.blurY+", "+q+");"); break; case "bevelFilter": fl.trace(en + "new BevelFilter("+f.distance+", "+f.angle+", "+highlightColorInfo.color+", "+highlightColorInfo.alpha+", "+shadowColorInfo.color+", "+shadowColorInfo.alpha+", "+f.blurX+", "+f.blurY+", "+f.strength+", "+q+", \""+f.type+"\", "+f.knockout+");"); break; case "gradientBevelFilter": fl.trace(en + "new GradientBevelFilter("+f.distance+", "+f.angle+", ["+colorArray+"], ["+alphaArray+"], ["+f.posArray+"], "+f.blurX+", "+f.blurY+", "+f.strength+", "+q+", \""+f.type+"\", "+f.knockout+");"); break; case "gradientGlowFilter": fl.trace(en + "new GradientGlowFilter("+f.distance+", "+f.angle+", ["+colorArray+"], ["+alphaArray+"], ["+f.posArray+"], "+f.blurX+", "+f.blurY+", "+f.strength+", "+q+", \""+f.type+"\", "+f.knockout+");"); break; case "adjustColorFilter": var m = new ColorMatrix(); m.adjustColor(f.brightness, f.contrast, f.saturation, f.hue); fl.trace(en + "new ColorMatrixFilter(["+m.matrix+"]);"); break; } } fl.trace("\n"); } /** * Returns an Object with two properties, color and alpha, as strings, based on the parsing of the color string coming in. The color string * will be something like "#FF9933" or "#FF993366". If it's a 32-bit color, the alpha channel is contained in the last two bytes * (66 in this case). **/ function getColorAndAlpha(color) { var colorInfo = {}; if (color.length == 9) { colorInfo.alpha = Math.round(parseInt(color.substr(7, 2), 16) / 0xFF * 100) / 100; colorInfo.color = color.substr(0, 7).replace(/^#/, "0x") } else if (color.length == 7) { colorInfo.alpha = 1; colorInfo.color = color.replace(/^#/, "0x") } else { fl.trace("Problem parsing color.") } return colorInfo; }