2015-07-18 21:10:27 -04:00
var FFZ = window . FrankerFaceZ ,
hue2rgb = function ( p , q , t ) {
if ( t < 0 ) t += 1 ;
if ( t > 1 ) t -= 1 ;
if ( t < 1 / 6 )
return p + ( q - p ) * 6 * t ;
if ( t < 1 / 2 )
return q ;
if ( t < 2 / 3 )
return p + ( q - p ) * ( 2 / 3 - t ) * 6 ;
return p ;
} ;
// ---------------------
// Settings
// ---------------------
FFZ . settings _info . fix _color = {
type : "select" ,
options : {
'-1' : "Disabled" ,
0 : "Default Colors" ,
1 : "Luv Adjustment" ,
2 : "HSL Adjustment (Depreciated)" ,
3 : "HSV Adjustment (Depreciated)" ,
4 : "RGB Adjustment (Depreciated)"
} ,
value : '1' ,
category : "Chat Appearance" ,
no _bttv : true ,
name : "Username Colors - Brightness" ,
help : "Ensure that username colors contrast with the background enough to be readable." ,
process _value : function ( val ) {
// Load legacy setting.
if ( val === false )
return '0' ;
else if ( val === true )
return '1' ;
return val ;
} ,
on _update : function ( val ) {
document . body . classList . toggle ( "ffz-chat-colors-gray" , ! this . has _bttv && ( val === '-1' ) ) ;
if ( ! this . has _bttv && val !== '-1' )
this . _rebuild _colors ( ) ;
}
} ;
2015-07-29 01:03:10 -04:00
FFZ . settings _info . luv _contrast = {
type : "button" ,
value : 4.5 ,
category : "Chat Appearance" ,
no _bttv : true ,
name : "Username Colors - Luv Minimum Contrast" ,
help : "Set the minimum contrast ratio used by Luv Adjustment to ensure colors are readable." ,
2015-07-18 21:10:27 -04:00
2015-07-29 01:03:10 -04:00
method : function ( ) {
var old _val = this . settings . luv _contrast ,
new _val = prompt ( "Luv Adjustment Minimum Contrast Ratio\n\nPlease enter a new value for the minimum contrast ratio required between username colors and the background. The default is: 4.5" , old _val ) ;
if ( new _val === null || new _val === undefined )
return ;
var parsed = parseFloat ( new _val ) ;
if ( parsed === NaN || parsed < 1 )
parsed = 4.5 ;
this . settings . set ( "luv_contrast" , parsed ) ;
} ,
on _update : function ( val ) {
this . _rebuild _contrast ( ) ;
if ( ! this . has _bttv && this . settings . fix _color == '1' )
this . _rebuild _colors ( ) ;
}
} ;
2015-07-18 21:10:27 -04:00
FFZ . settings _info . color _blind = {
type : "select" ,
options : {
0 : "Disabled" ,
protanope : "Protanope" ,
deuteranope : "Deuteranope" ,
tritanope : "Tritanope"
} ,
value : '0' ,
category : "Chat Appearance" ,
no _bttv : true ,
name : "Username Colors - Color Blindness" ,
help : "Adjust username colors in an attempt to make them more distinct for people with color blindness." ,
on _update : function ( val ) {
if ( ! this . has _bttv && this . settings . fix _color !== '-1' )
this . _rebuild _colors ( ) ;
}
} ;
// --------------------
// Initialization
// --------------------
FFZ . prototype . setup _colors = function ( ) {
this . _colors = { } ;
2015-07-29 01:03:10 -04:00
this . _rebuild _contrast ( ) ;
2015-07-31 17:44:20 -04:00
this . _update _colors ( ) ;
// Events for rebuilding colors.
var Layout = App . _ _container _ _ . lookup ( 'controller:layout' ) ,
Settings = App . _ _container _ _ . lookup ( 'controller:settings' ) ;
2015-07-18 21:10:27 -04:00
2015-07-31 17:44:20 -04:00
if ( Layout )
Layout . addObserver ( "isTheatreMode" , this . _update _colors . bind ( this , true ) ) ;
if ( Settings )
Settings . addObserver ( "model.darkMode" , this . _update _colors . bind ( this , true ) )
this . _color _old _darkness = ( Layout && Layout . get ( 'isTheatreMode' ) ) || ( Settings && Settings . get ( 'model.darkMode' ) ) ;
2015-07-18 21:10:27 -04:00
}
// -----------------------
// Color Handling Classes
// -----------------------
FFZ . Color = { } ;
FFZ . Color . CVDMatrix = {
protanope : [ // reds are greatly reduced (1% men)
0.0 , 2.02344 , - 2.52581 ,
0.0 , 1.0 , 0.0 ,
0.0 , 0.0 , 1.0
] ,
deuteranope : [ // greens are greatly reduced (1% men)
1.0 , 0.0 , 0.0 ,
0.494207 , 0.0 , 1.24827 ,
0.0 , 0.0 , 1.0
] ,
tritanope : [ // blues are greatly reduced (0.003% population)
1.0 , 0.0 , 0.0 ,
0.0 , 1.0 , 0.0 ,
- 0.395913 , 0.801109 , 0.0
]
}
var RGBColor = FFZ . Color . RGB = function ( r , g , b ) {
this . r = r || 0 ; this . g = g || 0 ; this . b = b || 0 ;
} ;
var HSVColor = FFZ . Color . HSV = function ( h , s , v ) {
this . h = h || 0 ; this . s = s || 0 ; this . v = v || 0 ;
} ;
var HSLColor = FFZ . Color . HSL = function ( h , s , l ) {
this . h = h || 0 ; this . s = s || 0 ; this . l = l || 0 ;
} ;
var XYZColor = FFZ . Color . XYZ = function ( x , y , z ) {
this . x = x || 0 ; this . y = y || 0 ; this . z = z || 0 ;
} ;
var LUVColor = FFZ . Color . LUV = function ( l , u , v ) {
this . l = l || 0 ; this . u = u || 0 ; this . v = v || 0 ;
} ;
// RGB Colors
RGBColor . prototype . eq = function ( rgb ) {
return rgb . r === this . r && rgb . g === this . g && rgb . b === this . b ;
}
RGBColor . fromHex = function ( code ) {
var raw = parseInt ( code . charAt ( 0 ) === '#' ? code . substr ( 1 ) : code , 16 ) ;
return new RGBColor (
( raw >> 16 ) , // Red
( raw >> 8 & 0x00FF ) , // Green
( raw & 0x0000FF ) // Blue
)
}
RGBColor . fromHSV = function ( h , s , v ) {
var r , g , b ,
i = Math . floor ( h * 6 ) ,
f = h * 6 - i ,
p = v * ( 1 - s ) ,
q = v * ( 1 - f * s ) ,
t = v * ( 1 - ( 1 - f ) * s ) ;
switch ( i % 6 ) {
case 0 : r = v , g = t , b = p ; break ;
case 1 : r = q , g = v , b = p ; break ;
case 2 : r = p , g = v , b = t ; break ;
case 3 : r = p , g = q , b = v ; break ;
case 4 : r = t , g = p , b = v ; break ;
case 5 : r = v , g = p , b = q ;
}
return new RGBColor (
Math . round ( Math . min ( Math . max ( 0 , r * 255 ) , 255 ) ) ,
Math . round ( Math . min ( Math . max ( 0 , g * 255 ) , 255 ) ) ,
Math . round ( Math . min ( Math . max ( 0 , b * 255 ) , 255 ) )
) ;
}
RGBColor . fromXYZ = function ( x , y , z ) {
var R = 3.240479 * x - 1.537150 * y - 0.498535 * z ,
G = - 0.969256 * x + 1.875992 * y + 0.041556 * z ,
B = 0.055648 * x - 0.204043 * y + 1.057311 * z ;
// Make sure we end up in a real color space
return new RGBColor (
Math . max ( 0 , Math . min ( 255 , 255 * XYZColor . channelConverter ( R ) ) ) ,
Math . max ( 0 , Math . min ( 255 , 255 * XYZColor . channelConverter ( G ) ) ) ,
Math . max ( 0 , Math . min ( 255 , 255 * XYZColor . channelConverter ( B ) ) )
) ;
}
RGBColor . fromHSL = function ( h , s , l ) {
if ( s === 0 ) {
var v = Math . round ( Math . min ( Math . max ( 0 , 255 * l ) , 255 ) ) ;
return new RGBColor ( v , v , v ) ;
}
var q = l < 0.5 ? l * ( 1 + s ) : l + s - l * s ,
p = 2 * l - q ;
return new RGBColor (
Math . round ( Math . min ( Math . max ( 0 , 255 * hue2rgb ( p , q , h + 1 / 3 ) ) , 255 ) ) ,
Math . round ( Math . min ( Math . max ( 0 , 255 * hue2rgb ( p , q , h ) ) , 255 ) ) ,
Math . round ( Math . min ( Math . max ( 0 , 255 * hue2rgb ( p , q , h - 1 / 3 ) ) , 255 ) )
) ;
}
RGBColor . prototype . toHSV = function ( ) { return HSVColor . fromRGB ( this . r , this . g , this . b ) ; }
RGBColor . prototype . toHSL = function ( ) { return HSLColor . fromRGB ( this . r , this . g , this . b ) ; }
RGBColor . prototype . toCSS = function ( ) { return "rgb(" + Math . round ( this . r ) + "," + Math . round ( this . g ) + "," + Math . round ( this . b ) + ")" ; }
RGBColor . prototype . toXYZ = function ( ) { return XYZColor . fromRGB ( this . r , this . g , this . b ) ; }
RGBColor . prototype . toLUV = function ( ) { return this . toXYZ ( ) . toLUV ( ) ; }
2015-07-31 17:44:20 -04:00
RGBColor . prototype . toHex = function ( ) {
var rgb = this . b | ( this . g << 8 ) | ( this . r << 16 ) ;
return '#' + ( 0x1000000 + rgb ) . toString ( 16 ) . slice ( 1 ) ;
}
2015-07-18 21:10:27 -04:00
RGBColor . prototype . luminance = function ( ) {
var rgb = [ this . r / 255 , this . g / 255 , this . b / 255 ] ;
for ( var i = 0 , l = rgb . length ; i < l ; i ++ ) {
if ( rgb [ i ] <= 0.03928 ) {
rgb [ i ] = rgb [ i ] / 12.92 ;
} else {
rgb [ i ] = Math . pow ( ( ( rgb [ i ] + 0.055 ) / 1.055 ) , 2.4 ) ;
}
}
return ( 0.2126 * rgb [ 0 ] ) + ( 0.7152 * rgb [ 1 ] ) + ( 0.0722 * rgb [ 2 ] ) ;
}
RGBColor . prototype . brighten = function ( amount ) {
amount = typeof amount === "number" ? amount : 1 ;
amount = Math . round ( 255 * ( amount / 100 ) ) ;
return new RGBColor (
Math . max ( 0 , Math . min ( 255 , this . r + amount ) ) ,
Math . max ( 0 , Math . min ( 255 , this . g + amount ) ) ,
Math . max ( 0 , Math . min ( 255 , this . b + amount ) )
) ;
}
RGBColor . prototype . daltonize = function ( type , amount ) {
amount = typeof amount === "number" ? amount : 1.0 ;
var cvd ;
if ( typeof type === "string" ) {
if ( FFZ . Color . CVDMatrix . hasOwnProperty ( type ) )
cvd = FFZ . Color . CVDMatrix [ type ] ;
else
throw "Invalid CVD matrix." ;
} else
cvd = type ;
var cvd _a = cvd [ 0 ] , cvd _b = cvd [ 1 ] , cvd _c = cvd [ 2 ] ,
cvd _d = cvd [ 3 ] , cvd _e = cvd [ 4 ] , cvd _f = cvd [ 5 ] ,
cvd _g = cvd [ 6 ] , cvd _h = cvd [ 7 ] , cvd _i = cvd [ 8 ] ,
L , M , S , l , m , s , R , G , B , RR , GG , BB ;
// RGB to LMS matrix conversion
L = ( 17.8824 * this . r ) + ( 43.5161 * this . g ) + ( 4.11935 * this . b ) ;
M = ( 3.45565 * this . r ) + ( 27.1554 * this . g ) + ( 3.86714 * this . b ) ;
S = ( 0.0299566 * this . r ) + ( 0.184309 * this . g ) + ( 1.46709 * this . b ) ;
// Simulate color blindness
l = ( cvd _a * L ) + ( cvd _b * M ) + ( cvd _c * S ) ;
m = ( cvd _d * L ) + ( cvd _e * M ) + ( cvd _f * S ) ;
s = ( cvd _g * L ) + ( cvd _h * M ) + ( cvd _i * S ) ;
// LMS to RGB matrix conversion
R = ( 0.0809444479 * l ) + ( - 0.130504409 * m ) + ( 0.116721066 * s ) ;
G = ( - 0.0102485335 * l ) + ( 0.0540193266 * m ) + ( - 0.113614708 * s ) ;
B = ( - 0.000365296938 * l ) + ( - 0.00412161469 * m ) + ( 0.693511405 * s ) ;
// Isolate invisible colors to color vision deficiency (calculate error matrix)
R = this . r - R ;
G = this . g - G ;
B = this . b - B ;
// Shift colors towards visible spectrum (apply error modifications)
RR = ( 0.0 * R ) + ( 0.0 * G ) + ( 0.0 * B ) ;
GG = ( 0.7 * R ) + ( 1.0 * G ) + ( 0.0 * B ) ;
BB = ( 0.7 * R ) + ( 0.0 * G ) + ( 1.0 * B ) ;
// Add compensation to original values
R = Math . min ( Math . max ( 0 , RR + this . r ) , 255 ) ;
G = Math . min ( Math . max ( 0 , GG + this . g ) , 255 ) ;
B = Math . min ( Math . max ( 0 , BB + this . b ) , 255 ) ;
return new RGBColor ( R , G , B ) ;
}
RGBColor . prototype . _r = function ( r ) { return new RGBColor ( r , this . g , this . b ) ; }
RGBColor . prototype . _g = function ( g ) { return new RGBColor ( this . r , g , this . b ) ; }
RGBColor . prototype . _b = function ( b ) { return new RGBColor ( this . r , this . g , b ) ; }
// HSL Colors
HSLColor . prototype . eq = function ( hsl ) {
return hsl . h === this . h && hsl . s === this . s && hsl . l === this . l ;
}
HSLColor . fromRGB = function ( r , g , b ) {
r /= 255 ; g /= 255 ; b /= 255 ;
var max = Math . max ( r , g , b ) ,
min = Math . min ( r , g , b ) ,
h , s , l = Math . min ( Math . max ( 0 , ( max + min ) / 2 ) , 1 ) ,
d = Math . min ( Math . max ( 0 , max - min ) , 1 ) ;
if ( d === 0 )
h = s = 0 ;
else {
s = l > 0.5 ? d / ( 2 - max - min ) : d / ( max + min ) ;
switch ( max ) {
case r :
h = ( g - b ) / d + ( g < b ? 6 : 0 ) ;
break ;
case g :
h = ( b - r ) / d + 2 ;
break ;
case b :
h = ( r - g ) / d + 4 ;
}
h /= 6 ;
}
return new HSLColor ( h , s , l ) ;
}
HSLColor . prototype . toRGB = function ( ) { return RGBColor . fromHSL ( this . h , this . s , this . l ) ; }
HSLColor . prototype . toCSS = function ( ) { return "hsl(" + Math . round ( this . h * 360 ) + "," + Math . round ( this . s * 100 ) + "%," + Math . round ( this . l * 100 ) + "%)" ; }
2015-07-31 17:44:20 -04:00
HSLColor . prototype . toHex = function ( ) { return RGBColor . fromHSL ( this . h , this . s , this . l ) . toHex ( ) ; }
2015-07-18 21:10:27 -04:00
HSLColor . prototype . toHSV = function ( ) { return RGBColor . fromHSL ( this . h , this . s , this . l ) . toHSV ( ) ; }
HSLColor . prototype . toXYZ = function ( ) { return RGBColor . fromHSL ( this . h , this . s , this . l ) . toXYZ ( ) ; }
HSLColor . prototype . toLUV = function ( ) { return RGBColor . fromHSL ( this . h , this . s , this . l ) . toLUV ( ) ; }
HSLColor . prototype . _h = function ( h ) { return new HSLColor ( h , this . s , this . l ) ; }
HSLColor . prototype . _s = function ( s ) { return new HSLColor ( this . h , s , this . l ) ; }
HSLColor . prototype . _l = function ( l ) { return new HSLColor ( this . h , this . s , l ) ; }
// HSV Colors
HSVColor . prototype . eq = function ( hsv ) { return hsv . h === this . h && hsv . s === this . s && hsv . v === this . v ; }
HSVColor . fromRGB = function ( r , g , b ) {
r /= 255 ; g /= 255 ; b /= 255 ;
var max = Math . max ( r , g , b ) ,
min = Math . min ( r , g , b ) ,
d = Math . min ( Math . max ( 0 , max - min ) , 1 ) ,
h ,
s = max === 0 ? 0 : d / max ,
v = max ;
if ( d === 0 )
h = 0 ;
else {
switch ( max ) {
case r :
h = ( g - b ) / d + ( g < b ? 6 : 0 ) ;
break ;
case g :
h = ( b - r ) / d + 2 ;
break ;
case b :
h = ( r - g ) / d + 4 ;
}
h /= 6 ;
}
return new HSVColor ( h , s , v ) ;
}
HSVColor . prototype . toRGB = function ( ) { return RGBColor . fromHSV ( this . h , this . s , this . v ) ; }
HSVColor . prototype . toHSL = function ( ) { return RGBColor . fromHSV ( this . h , this . s , this . v ) . toHSL ( ) ; }
HSVColor . prototype . toXYZ = function ( ) { return RGBColor . fromHSV ( this . h , this . s , this . v ) . toXYZ ( ) ; }
HSVColor . prototype . toLUV = function ( ) { return RGBColor . fromHSV ( this . h , this . s , this . v ) . toLUV ( ) ; }
HSVColor . prototype . _h = function ( h ) { return new HSVColor ( h , this . s , this . v ) ; }
HSVColor . prototype . _s = function ( s ) { return new HSVColor ( this . h , s , this . v ) ; }
HSVColor . prototype . _v = function ( v ) { return new HSVColor ( this . h , this . s , v ) ; }
// XYZ Colors
RGBColor . channelConverter = function ( channel ) {
// http://www.brucelindbloom.com/Eqn_RGB_to_XYZ.html
// This converts rgb 8bit to rgb linear, lazy because the other algorithm is really really dumb
return Math . pow ( channel , 2.2 ) ;
// CSS Colors Level 4 says 0.03928, Bruce Lindbloom who cared to write all algos says 0.04045, used bruce because whynawt
return ( channel <= 0.04045 ) ? channel / 12.92 : Math . pow ( ( channel + 0.055 ) / 1.055 , 2.4 ) ;
} ;
XYZColor . channelConverter = function ( channel ) {
// Using lazy conversion in the other direction as well
return Math . pow ( channel , 1 / 2.2 ) ;
// I'm honestly not sure about 0.0031308, I've only seen it referenced on Bruce Lindbloom's site
return ( channel <= 0.0031308 ) ? channel * 12.92 : Math . pow ( 1.055 * channel , 1 / 2.4 ) - 0.055 ;
} ;
XYZColor . prototype . eq = function ( xyz ) { return xyz . x === this . x && xyz . y === this . y && xyz . z === this . z ; }
XYZColor . fromRGB = function ( r , g , b ) {
var R = RGBColor . channelConverter ( r / 255 ) ,
G = RGBColor . channelConverter ( g / 255 ) ,
B = RGBColor . channelConverter ( b / 255 ) ;
return new XYZColor (
0.412453 * R + 0.357580 * G + 0.180423 * B ,
0.212671 * R + 0.715160 * G + 0.072169 * B ,
0.019334 * R + 0.119193 * G + 0.950227 * B
) ;
}
XYZColor . fromLUV = function ( l , u , v ) {
var deltaGammaFactor = 1 / ( XYZColor . WHITE . x + 15 * XYZColor . WHITE . y + 3 * XYZColor . WHITE . z ) ;
var uDeltaGamma = 4 * XYZColor . WHITE . x * deltaGammaFactor ;
var vDeltagamma = 9 * XYZColor . WHITE . y * deltaGammaFactor ;
// XYZColor.EPSILON * XYZColor.KAPPA = 8
var Y = ( l > 8 ) ? Math . pow ( ( l + 16 ) / 116 , 3 ) : l / XYZColor . KAPPA ;
var a = 1 / 3 * ( ( ( 52 * l ) / ( u + 13 * l * uDeltaGamma ) ) - 1 ) ;
var b = - 5 * Y ;
var c = - 1 / 3 ;
var d = Y * ( ( ( 39 * l ) / ( v + 13 * l * vDeltagamma ) ) - 5 ) ;
var X = ( d - b ) / ( a - c ) ;
var Z = X * a + b ;
return new XYZColor ( X , Y , Z ) ;
}
XYZColor . prototype . toRGB = function ( ) { return RGBColor . fromXYZ ( this . x , this . y , this . z ) ; }
XYZColor . prototype . toLUV = function ( ) { return LUVColor . fromXYZ ( this . x , this . y , this . z ) ; }
XYZColor . prototype . toHSL = function ( ) { return RGBColor . fromXYZ ( this . x , this . y , this . z ) . toHSL ( ) ; }
XYZColor . prototype . toHSV = function ( ) { return RGBColor . fromXYZ ( this . x , this . y , this . z ) . toHSV ( ) ; }
XYZColor . prototype . _x = function ( x ) { return new XYZColor ( x , this . y , this . z ) ; }
XYZColor . prototype . _y = function ( y ) { return new XYZColor ( this . x , y , this . z ) ; }
XYZColor . prototype . _z = function ( z ) { return new XYZColor ( this . x , this . y , z ) ; }
// LUV Colors
XYZColor . EPSILON = Math . pow ( 6 / 29 , 3 ) ;
XYZColor . KAPPA = Math . pow ( 29 / 3 , 3 ) ;
XYZColor . WHITE = ( new RGBColor ( 255 , 255 , 255 ) ) . toXYZ ( ) ;
LUVColor . prototype . eq = function ( luv ) { return luv . l === this . l && luv . u === this . u && luv . v === this . v ; }
LUVColor . fromXYZ = function ( X , Y , Z ) {
var deltaGammaFactor = 1 / ( XYZColor . WHITE . x + 15 * XYZColor . WHITE . y + 3 * XYZColor . WHITE . z ) ;
var uDeltaGamma = 4 * XYZColor . WHITE . x * deltaGammaFactor ;
var vDeltagamma = 9 * XYZColor . WHITE . y * deltaGammaFactor ;
var yGamma = Y / XYZColor . WHITE . y ;
var deltaDivider = ( X + 15 * Y + 3 * Z ) ;
if ( deltaDivider === 0 ) {
deltaDivider = 1 ;
}
var deltaFactor = 1 / deltaDivider ;
var uDelta = 4 * X * deltaFactor ;
var vDelta = 9 * Y * deltaFactor ;
var L = ( yGamma > XYZColor . EPSILON ) ? 116 * Math . pow ( yGamma , 1 / 3 ) - 16 : XYZColor . KAPPA * yGamma ;
var u = 13 * L * ( uDelta - uDeltaGamma ) ;
var v = 13 * L * ( vDelta - vDeltagamma ) ;
return new LUVColor ( L , u , v ) ;
}
LUVColor . prototype . toXYZ = function ( ) { return XYZColor . fromLUV ( this . l , this . u , this . v ) ; }
LUVColor . prototype . toRGB = function ( ) { return XYZColor . fromLUV ( this . l , this . u , this . v ) . toRGB ( ) ; }
LUVColor . prototype . toHSL = function ( ) { return XYZColor . fromLUV ( this . l , this . u , this . v ) . toHSL ( ) ; }
LUVColor . prototype . toHSV = function ( ) { return XYZColor . fromLUV ( this . l , this . u , this . v ) . toHSV ( ) ; }
LUVColor . prototype . _l = function ( l ) { return new LUVColor ( l , this . u , this . v ) ; }
LUVColor . prototype . _u = function ( u ) { return new LUVColor ( this . l , u , this . v ) ; }
LUVColor . prototype . _v = function ( v ) { return new LUVColor ( this . l , this . u , v ) ; }
// --------------------
// Rebuild Colors
// --------------------
2015-07-29 01:03:10 -04:00
FFZ . prototype . _rebuild _contrast = function ( ) {
this . _luv _required _bright = new XYZColor ( 0 , ( this . settings . luv _contrast * ( new RGBColor ( 35 , 35 , 35 ) . toXYZ ( ) . y + 0.05 ) - 0.05 ) , 0 ) . toLUV ( ) . l ;
this . _luv _required _dark = new XYZColor ( 0 , ( ( new RGBColor ( 217 , 217 , 217 ) . toXYZ ( ) . y + 0.05 ) / this . settings . luv _contrast - 0.05 ) , 0 ) . toLUV ( ) . l ;
}
2015-07-18 21:10:27 -04:00
FFZ . prototype . _rebuild _colors = function ( ) {
2015-07-31 17:44:20 -04:00
if ( this . has _bttv )
2015-07-18 21:10:27 -04:00
return ;
2015-07-31 17:44:20 -04:00
// With update colors, we'll automatically process the colors we care about.
2015-07-18 21:10:27 -04:00
this . _colors = { } ;
2015-07-31 17:44:20 -04:00
this . _update _colors ( ) ;
}
FFZ . prototype . _update _colors = function ( darkness _only ) {
// Update the lines. ALL of them.
var Layout = App . _ _container _ _ . lookup ( 'controller:layout' ) ,
Settings = App . _ _container _ _ . lookup ( 'controller:settings' ) ,
is _dark = ( Layout && Layout . get ( 'isTheatreMode' ) ) || ( Settings && Settings . get ( 'model.darkMode' ) ) ;
if ( darkness _only && this . _color _old _darkness === is _dark )
return ;
this . _color _old _darkness = is _dark ;
var colored _bits = document . querySelectorAll ( '.chat-line .has-color' ) ;
for ( var i = 0 , l = colored _bits . length ; i < l ; i ++ ) {
var bit = colored _bits [ i ] ,
color = bit . getAttribute ( 'data-color' ) ,
colors = color && this . _handle _color ( color ) ;
if ( ! colors )
continue ;
bit . style . color = is _dark ? colors [ 1 ] : colors [ 0 ] ;
}
2015-07-18 21:10:27 -04:00
}
FFZ . prototype . _handle _color = function ( color ) {
if ( ! color || this . _colors . hasOwnProperty ( color ) )
2015-07-31 17:44:20 -04:00
return this . _colors [ color ] ;
2015-07-18 21:10:27 -04:00
var rgb = RGBColor . fromHex ( color ) ,
light _color = color ,
2015-07-31 17:44:20 -04:00
dark _color = color ;
2015-07-18 21:10:27 -04:00
// Color Blindness Handling
if ( this . settings . color _blind !== '0' ) {
var new _color = rgb . daltonize ( this . settings . color _blind ) ;
if ( ! rgb . eq ( new _color ) ) {
rgb = new _color ;
2015-07-31 17:44:20 -04:00
light _color = dark _color = rgb . toHex ( ) ;
2015-07-18 21:10:27 -04:00
}
}
// Color Processing - RGB
if ( this . settings . fix _color === '4' ) {
var lum = rgb . luminance ( ) ;
if ( lum > 0.3 ) {
var s = 127 , nc = rgb ;
while ( s -- ) {
nc = nc . brighten ( - 1 ) ;
if ( nc . luminance ( ) <= 0.3 )
break ;
}
2015-07-31 17:44:20 -04:00
light _color = nc . toHex ( ) ;
2015-07-18 21:10:27 -04:00
}
if ( lum < 0.15 ) {
var s = 127 , nc = rgb ;
while ( s -- ) {
nc = nc . brighten ( ) ;
if ( nc . luminance ( ) >= 0.15 )
break ;
}
2015-07-31 17:44:20 -04:00
dark _color = nc . toHex ( ) ;
2015-07-18 21:10:27 -04:00
}
}
// Color Processing - HSL
if ( this . settings . fix _color === '2' ) {
var hsl = rgb . toHSL ( ) ;
2015-07-31 17:44:20 -04:00
light _color = hsl . _l ( Math . min ( Math . max ( 0 , 0.7 * hsl . l ) , 1 ) ) . toHex ( ) ;
dark _color = hsl . _l ( Math . min ( Math . max ( 0 , 0.3 + ( 0.7 * hsl . l ) ) , 1 ) ) . toHex ( ) ;
2015-07-18 21:10:27 -04:00
}
// Color Processing - HSV
if ( this . settings . fix _color === '3' ) {
var hsv = rgb . toHSV ( ) ;
if ( hsv . s === 0 ) {
// Black and White
2015-07-31 17:44:20 -04:00
light _color = hsv . _v ( Math . min ( Math . max ( 0.5 , 0.5 * hsv . v ) , 1 ) ) . toRGB ( ) . toHex ( ) ;
dark _color = hsv . _v ( Math . min ( Math . max ( 0.5 , 0.5 + ( 0.5 * hsv . v ) ) , 1 ) ) . toRGB ( ) . toHex ( ) ;
2015-07-18 21:10:27 -04:00
} else {
2015-07-31 17:44:20 -04:00
light _color = RGBColor . fromHSV ( hsv . h , Math . min ( Math . max ( 0.7 , 0.7 + ( 0.3 * hsv . s ) ) , 1 ) , Math . min ( 0.7 , hsv . v ) ) . toHex ( ) ;
dark _color = RGBColor . fromHSV ( hsv . h , Math . min ( 0.7 , hsv . s ) , Math . min ( Math . max ( 0.7 , 0.7 + ( 0.3 * hsv . v ) ) , 1 ) ) . toHex ( ) ;
2015-07-18 21:10:27 -04:00
}
}
// Color Processing - LUV
if ( this . settings . fix _color === '1' ) {
var luv = rgb . toLUV ( ) ;
2015-07-31 17:44:20 -04:00
if ( luv . l > this . _luv _required _dark )
light _color = luv . _l ( this . _luv _required _dark ) . toRGB ( ) . toHex ( ) ;
2015-07-18 21:10:27 -04:00
2015-07-31 17:44:20 -04:00
if ( luv . l < this . _luv _required _bright )
dark _color = luv . _l ( this . _luv _required _bright ) . toRGB ( ) . toHex ( ) ;
2015-07-18 21:10:27 -04:00
}
2015-07-31 17:44:20 -04:00
var out = this . _colors [ color ] = [ light _color , dark _color ] ;
return out ;
2015-07-18 21:10:27 -04:00
}