| 5 | | * http://www.gnu.org/licenses/gpl.html |
| | 5 | * http://www.gnu.org/licenses/gpl.html |
| | 6 | * |
| | 7 | * Note: Due to the in-activity of Fabrastic Github repo |
| | 8 | * [https://github.com/mattfarina/farbtastic/issues] |
| | 9 | * and JQuery depreciate the following methods, |
| | 10 | * replace new methods for old ones at WP milestone: 6.3 |
| | 11 | * Details are described here: |
| | 12 | * [https://core.trac.wordpress.org/ticket/57946] |
| | 13 | * a. bind() |
| | 14 | * b. unbind() |
| | 15 | * c. mousedown() |
| | 16 | * |
| 19 | | $._farbtastic = function (container, callback) { |
| 20 | | // Store farbtastic object |
| 21 | | var fb = this; |
| | 36 | // Insert markup |
| | 37 | $( container ).html( |
| | 38 | '<div class="farbtastic">' + |
| | 39 | '<div class="color"></div>' + |
| | 40 | '<div class="wheel"></div>' + |
| | 41 | '<div class="overlay"></div>' + |
| | 42 | '<div class="h-marker marker"></div>' + |
| | 43 | '<div class="sl-marker marker"></div>' + |
| | 44 | '</div>' |
| | 45 | ); |
| | 46 | var e = $( '.farbtastic', container ); |
| | 47 | fb.wheel = $( '.wheel', container ).get( 0 ); |
| | 48 | // Dimensions |
| | 49 | fb.radius = 84; |
| | 50 | fb.square = 100; |
| | 51 | fb.width = 194; |
| 23 | | // Insert markup |
| 24 | | $(container).html('<div class="farbtastic"><div class="color"></div><div class="wheel"></div><div class="overlay"></div><div class="h-marker marker"></div><div class="sl-marker marker"></div></div>'); |
| 25 | | var e = $('.farbtastic', container); |
| 26 | | fb.wheel = $('.wheel', container).get(0); |
| 27 | | // Dimensions |
| 28 | | fb.radius = 84; |
| 29 | | fb.square = 100; |
| 30 | | fb.width = 194; |
| | 53 | // Fix background PNGs in IE6 |
| | 54 | if ( navigator.userAgent.match( /MSIE [0-6]\./ ) ) { |
| | 55 | $( '*', e ).each( function () { |
| | 56 | if ( this.currentStyle.backgroundImage !== 'none' ) { |
| | 57 | var image = this.currentStyle.backgroundImage; |
| | 58 | image = this.currentStyle.backgroundImage.substring( |
| | 59 | 5, |
| | 60 | image.length - 2 |
| | 61 | ); |
| | 62 | $( this ).css( { |
| | 63 | backgroundImage: 'none', |
| | 64 | filter: |
| | 65 | 'progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src="' + |
| | 66 | image + |
| | 67 | '")', |
| | 68 | } ); |
| | 69 | } |
| | 70 | } ); |
| | 71 | } |
| | 72 | /** |
| | 73 | * Link to the given element(s) or callback. |
| | 74 | */ |
| | 75 | fb.linkTo = function ( callback ) { |
| | 76 | // Unbind previous nodes |
| | 77 | if ( typeof fb.callback == 'object' ) { |
| | 78 | $( fb.callback ).off( 'keyup', fb.updateValue ); |
| | 79 | } |
| 32 | | // Fix background PNGs in IE6 |
| 33 | | if (navigator.appVersion.match(/MSIE [0-6]\./)) { |
| 34 | | $('*', e).each(function () { |
| 35 | | if (this.currentStyle.backgroundImage != 'none') { |
| 36 | | var image = this.currentStyle.backgroundImage; |
| 37 | | image = this.currentStyle.backgroundImage.substring(5, image.length - 2); |
| 38 | | $(this).css({ |
| 39 | | 'backgroundImage': 'none', |
| 40 | | 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')" |
| 41 | | }); |
| 42 | | } |
| 43 | | }); |
| 44 | | } |
| | 81 | // Reset color |
| | 82 | fb.color = null; |
| 46 | | /** |
| 47 | | * Link to the given element(s) or callback. |
| 48 | | */ |
| 49 | | fb.linkTo = function (callback) { |
| 50 | | // Unbind previous nodes |
| 51 | | if (typeof fb.callback == 'object') { |
| 52 | | $(fb.callback).unbind('keyup', fb.updateValue); |
| 53 | | } |
| | 84 | // Bind callback or elements |
| | 85 | if ( typeof callback == 'function' ) { |
| | 86 | fb.callback = callback; |
| | 87 | } else if ( |
| | 88 | typeof callback == 'object' || |
| | 89 | typeof callback == 'string' |
| | 90 | ) { |
| | 91 | fb.callback = $( callback ); |
| | 92 | fb.callback.on( 'keyup', fb.updateValue ); |
| | 93 | if ( fb.callback.get( 0 ).value ) { |
| | 94 | fb.setColor( fb.callback.get( 0 ).value ); |
| | 95 | } |
| | 96 | } |
| | 97 | return this; |
| | 98 | }; |
| 58 | | // Bind callback or elements |
| 59 | | if (typeof callback == 'function') { |
| 60 | | fb.callback = callback; |
| 61 | | } |
| 62 | | else if (typeof callback == 'object' || typeof callback == 'string') { |
| 63 | | fb.callback = $(callback); |
| 64 | | fb.callback.bind('keyup', fb.updateValue); |
| 65 | | if (fb.callback.get(0).value) { |
| 66 | | fb.setColor(fb.callback.get(0).value); |
| 67 | | } |
| 68 | | } |
| 69 | | return this; |
| 70 | | }; |
| 71 | | fb.updateValue = function (event) { |
| 72 | | if (this.value && this.value != fb.color) { |
| 73 | | fb.setColor(this.value); |
| 74 | | } |
| 75 | | }; |
| | 106 | /** |
| | 107 | * Change color with HTML syntax #123456 |
| | 108 | */ |
| | 109 | fb.setColor = function ( color ) { |
| | 110 | var unpack = fb.unpack( color ); |
| | 111 | if ( fb.color != color && unpack ) { |
| | 112 | fb.color = color; |
| | 113 | fb.rgb = unpack; |
| | 114 | fb.hsl = fb.RGBToHSL( fb.rgb ); |
| | 115 | fb.updateDisplay(); |
| | 116 | } |
| | 117 | return this; |
| | 118 | }; |
| 77 | | /** |
| 78 | | * Change color with HTML syntax #123456 |
| 79 | | */ |
| 80 | | fb.setColor = function (color) { |
| 81 | | var unpack = fb.unpack(color); |
| 82 | | if (fb.color != color && unpack) { |
| 83 | | fb.color = color; |
| 84 | | fb.rgb = unpack; |
| 85 | | fb.hsl = fb.RGBToHSL(fb.rgb); |
| 86 | | fb.updateDisplay(); |
| 87 | | } |
| 88 | | return this; |
| 89 | | }; |
| | 120 | /** |
| | 121 | * Change color with HSL triplet [0..1, 0..1, 0..1] |
| | 122 | */ |
| | 123 | fb.setHSL = function ( hsl ) { |
| | 124 | fb.hsl = hsl; |
| | 125 | fb.rgb = fb.HSLToRGB( hsl ); |
| | 126 | fb.color = fb.pack( fb.rgb ); |
| | 127 | fb.updateDisplay(); |
| | 128 | return this; |
| | 129 | }; |
| 91 | | /** |
| 92 | | * Change color with HSL triplet [0..1, 0..1, 0..1] |
| 93 | | */ |
| 94 | | fb.setHSL = function (hsl) { |
| 95 | | fb.hsl = hsl; |
| 96 | | fb.rgb = fb.HSLToRGB(hsl); |
| 97 | | fb.color = fb.pack(fb.rgb); |
| 98 | | fb.updateDisplay(); |
| 99 | | return this; |
| 100 | | }; |
| | 131 | /** |
| | 132 | * Retrieve the coordinates of the given event relative to the center |
| | 133 | * of the widget. |
| | 134 | */ |
| | 135 | fb.widgetCoords = function ( event ) { |
| | 136 | var offset = $( fb.wheel ).offset(); |
| | 137 | return { |
| | 138 | x: event.pageX - offset.left - fb.width / 2, |
| | 139 | y: event.pageY - offset.top - fb.width / 2, |
| | 140 | }; |
| | 141 | }; |
| 127 | | // Process |
| 128 | | fb.mousemove(event); |
| 129 | | return false; |
| 130 | | }; |
| | 173 | // Set new HSL parameters |
| | 174 | if ( fb.circleDrag ) { |
| | 175 | var hue = Math.atan2( pos.x, -pos.y ) / 6.28; |
| | 176 | if ( hue < 0 ) hue += 1; |
| | 177 | fb.setHSL( [ hue, fb.hsl[ 1 ], fb.hsl[ 2 ] ] ); |
| | 178 | } else { |
| | 179 | var sat = Math.max( |
| | 180 | 0, |
| | 181 | Math.min( 1, -( pos.x / fb.square ) + 0.5 ) |
| | 182 | ); |
| | 183 | var lum = Math.max( |
| | 184 | 0, |
| | 185 | Math.min( 1, -( pos.y / fb.square ) + 0.5 ) |
| | 186 | ); |
| | 187 | fb.setHSL( [ fb.hsl[ 0 ], sat, lum ] ); |
| | 188 | } |
| | 189 | return false; |
| | 190 | }; |
| 139 | | // Set new HSL parameters |
| 140 | | if (fb.circleDrag) { |
| 141 | | var hue = Math.atan2(pos.x, -pos.y) / 6.28; |
| 142 | | if (hue < 0) hue += 1; |
| 143 | | fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]); |
| 144 | | } |
| 145 | | else { |
| 146 | | var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5)); |
| 147 | | var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5)); |
| 148 | | fb.setHSL([fb.hsl[0], sat, lum]); |
| 149 | | } |
| 150 | | return false; |
| 151 | | }; |
| | 202 | /** |
| | 203 | * Update the markers and styles |
| | 204 | */ |
| | 205 | fb.updateDisplay = function () { |
| | 206 | // Markers |
| | 207 | var angle = fb.hsl[ 0 ] * 6.28; |
| | 208 | $( '.h-marker', e ).css( { |
| | 209 | left: |
| | 210 | Math.round( Math.sin( angle ) * fb.radius + fb.width / 2 ) + |
| | 211 | 'px', |
| | 212 | top: |
| | 213 | Math.round( |
| | 214 | -Math.cos( angle ) * fb.radius + fb.width / 2 |
| | 215 | ) + 'px', |
| | 216 | } ); |
| 163 | | /** |
| 164 | | * Update the markers and styles |
| 165 | | */ |
| 166 | | fb.updateDisplay = function () { |
| 167 | | // Markers |
| 168 | | var angle = fb.hsl[0] * 6.28; |
| 169 | | $('.h-marker', e).css({ |
| 170 | | left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px', |
| 171 | | top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px' |
| 172 | | }); |
| | 229 | // Saturation/Luminance gradient |
| | 230 | $( '.color', e ).css( |
| | 231 | 'backgroundColor', |
| | 232 | fb.pack( fb.HSLToRGB( [ fb.hsl[ 0 ], 1, 0.5 ] ) ) |
| | 233 | ); |
| 174 | | $('.sl-marker', e).css({ |
| 175 | | left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px', |
| 176 | | top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px' |
| 177 | | }); |
| | 235 | // Linked elements or callback |
| | 236 | if ( typeof fb.callback == 'object' ) { |
| | 237 | // Set background/foreground color |
| | 238 | $( fb.callback ).css( { |
| | 239 | backgroundColor: fb.color, |
| | 240 | color: fb.hsl[ 2 ] > 0.5 ? '#000' : '#fff', |
| | 241 | } ); |
| 182 | | // Linked elements or callback |
| 183 | | if (typeof fb.callback == 'object') { |
| 184 | | // Set background/foreground color |
| 185 | | $(fb.callback).css({ |
| 186 | | backgroundColor: fb.color, |
| 187 | | color: fb.hsl[2] > 0.5 ? '#000' : '#fff' |
| 188 | | }); |
| | 254 | /* Various color utility functions */ |
| | 255 | fb.pack = function ( rgb ) { |
| | 256 | var r = Math.round( rgb[ 0 ] * 255 ); |
| | 257 | var g = Math.round( rgb[ 1 ] * 255 ); |
| | 258 | var b = Math.round( rgb[ 2 ] * 255 ); |
| | 259 | return ( |
| | 260 | '#' + |
| | 261 | ( r < 16 ? '0' : '' ) + |
| | 262 | r.toString( 16 ) + |
| | 263 | ( g < 16 ? '0' : '' ) + |
| | 264 | g.toString( 16 ) + |
| | 265 | ( b < 16 ? '0' : '' ) + |
| | 266 | b.toString( 16 ) |
| | 267 | ); |
| | 268 | }; |
| 190 | | // Change linked value |
| 191 | | $(fb.callback).each(function() { |
| 192 | | if (this.value && this.value != fb.color) { |
| 193 | | this.value = fb.color; |
| 194 | | } |
| 195 | | }); |
| 196 | | } |
| 197 | | else if (typeof fb.callback == 'function') { |
| 198 | | fb.callback.call(fb, fb.color); |
| 199 | | } |
| 200 | | }; |
| | 270 | fb.unpack = function ( color ) { |
| | 271 | if ( color.length == 7 ) { |
| | 272 | return [ |
| | 273 | parseInt( '0x' + color.substring( 1, 3 ) ) / 255, |
| | 274 | parseInt( '0x' + color.substring( 3, 5 ) ) / 255, |
| | 275 | parseInt( '0x' + color.substring( 5, 7 ) ) / 255, |
| | 276 | ]; |
| | 277 | } else if ( color.length == 4 ) { |
| | 278 | return [ |
| | 279 | parseInt( '0x' + color.substring( 1, 2 ) ) / 15, |
| | 280 | parseInt( '0x' + color.substring( 2, 3 ) ) / 15, |
| | 281 | parseInt( '0x' + color.substring( 3, 4 ) ) / 15, |
| | 282 | ]; |
| | 283 | } |
| | 284 | }; |
| 202 | | /* Various color utility functions */ |
| 203 | | fb.pack = function (rgb) { |
| 204 | | var r = Math.round(rgb[0] * 255); |
| 205 | | var g = Math.round(rgb[1] * 255); |
| 206 | | var b = Math.round(rgb[2] * 255); |
| 207 | | return '#' + (r < 16 ? '0' : '') + r.toString(16) + |
| 208 | | (g < 16 ? '0' : '') + g.toString(16) + |
| 209 | | (b < 16 ? '0' : '') + b.toString(16); |
| 210 | | }; |
| | 286 | fb.HSLToRGB = function ( hsl ) { |
| | 287 | var m1, m2, r, g, b; |
| | 288 | var h = hsl[ 0 ], |
| | 289 | s = hsl[ 1 ], |
| | 290 | l = hsl[ 2 ]; |
| | 291 | m2 = l <= 0.5 ? l * ( s + 1 ) : l + s - l * s; |
| | 292 | m1 = l * 2 - m2; |
| | 293 | return [ |
| | 294 | this.hueToRGB( m1, m2, h + 0.33333 ), |
| | 295 | this.hueToRGB( m1, m2, h ), |
| | 296 | this.hueToRGB( m1, m2, h - 0.33333 ), |
| | 297 | ]; |
| | 298 | }; |
| 212 | | fb.unpack = function (color) { |
| 213 | | if (color.length == 7) { |
| 214 | | return [parseInt('0x' + color.substring(1, 3)) / 255, |
| 215 | | parseInt('0x' + color.substring(3, 5)) / 255, |
| 216 | | parseInt('0x' + color.substring(5, 7)) / 255]; |
| 217 | | } |
| 218 | | else if (color.length == 4) { |
| 219 | | return [parseInt('0x' + color.substring(1, 2)) / 15, |
| 220 | | parseInt('0x' + color.substring(2, 3)) / 15, |
| 221 | | parseInt('0x' + color.substring(3, 4)) / 15]; |
| 222 | | } |
| 223 | | }; |
| | 300 | fb.hueToRGB = function ( m1, m2, h ) { |
| | 301 | h = h < 0 ? h + 1 : h > 1 ? h - 1 : h; |
| | 302 | if ( h * 6 < 1 ) return m1 + ( m2 - m1 ) * h * 6; |
| | 303 | if ( h * 2 < 1 ) return m2; |
| | 304 | if ( h * 3 < 2 ) return m1 + ( m2 - m1 ) * ( 0.66666 - h ) * 6; |
| | 305 | return m1; |
| | 306 | }; |
| 225 | | fb.HSLToRGB = function (hsl) { |
| 226 | | var m1, m2, r, g, b; |
| 227 | | var h = hsl[0], s = hsl[1], l = hsl[2]; |
| 228 | | m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s; |
| 229 | | m1 = l * 2 - m2; |
| 230 | | return [this.hueToRGB(m1, m2, h+0.33333), |
| 231 | | this.hueToRGB(m1, m2, h), |
| 232 | | this.hueToRGB(m1, m2, h-0.33333)]; |
| 233 | | }; |
| | 308 | fb.RGBToHSL = function ( rgb ) { |
| | 309 | var min, max, delta, h, s, l; |
| | 310 | var r = rgb[ 0 ], |
| | 311 | g = rgb[ 1 ], |
| | 312 | b = rgb[ 2 ]; |
| | 313 | min = Math.min( r, Math.min( g, b ) ); |
| | 314 | max = Math.max( r, Math.max( g, b ) ); |
| | 315 | delta = max - min; |
| | 316 | l = ( min + max ) / 2; |
| | 317 | s = 0; |
| | 318 | if ( l > 0 && l < 1 ) { |
| | 319 | s = delta / ( l < 0.5 ? 2 * l : 2 - 2 * l ); |
| | 320 | } |
| | 321 | h = 0; |
| | 322 | if ( delta > 0 ) { |
| | 323 | if ( max == r && max != g ) h += ( g - b ) / delta; |
| | 324 | if ( max == g && max != b ) h += 2 + ( b - r ) / delta; |
| | 325 | if ( max == b && max != r ) h += 4 + ( r - g ) / delta; |
| | 326 | h /= 6; |
| | 327 | } |
| | 328 | return [ h, s, l ]; |
| | 329 | }; |
| 235 | | fb.hueToRGB = function (m1, m2, h) { |
| 236 | | h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h); |
| 237 | | if (h * 6 < 1) return m1 + (m2 - m1) * h * 6; |
| 238 | | if (h * 2 < 1) return m2; |
| 239 | | if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6; |
| 240 | | return m1; |
| 241 | | }; |
| | 331 | // Install mousedown handler (the others are set on the document on-demand) |
| | 332 | $( '*', e ).on( 'mousedown', fb.mousedown ); |
| 243 | | fb.RGBToHSL = function (rgb) { |
| 244 | | var min, max, delta, h, s, l; |
| 245 | | var r = rgb[0], g = rgb[1], b = rgb[2]; |
| 246 | | min = Math.min(r, Math.min(g, b)); |
| 247 | | max = Math.max(r, Math.max(g, b)); |
| 248 | | delta = max - min; |
| 249 | | l = (min + max) / 2; |
| 250 | | s = 0; |
| 251 | | if (l > 0 && l < 1) { |
| 252 | | s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l)); |
| 253 | | } |
| 254 | | h = 0; |
| 255 | | if (delta > 0) { |
| 256 | | if (max == r && max != g) h += (g - b) / delta; |
| 257 | | if (max == g && max != b) h += (2 + (b - r) / delta); |
| 258 | | if (max == b && max != r) h += (4 + (r - g) / delta); |
| 259 | | h /= 6; |
| 260 | | } |
| 261 | | return [h, s, l]; |
| 262 | | }; |
| | 334 | // Init color |
| | 335 | fb.setColor( '#000000' ); |