Вход Регистрация
Файл: jcolor.js
Строк: 742
<?php
(function ($) {
  
'use strict';

  function 
clamp(valminmax) { return Math.max(Math.min(valmax), min); }
  function 
identity(val) { return val.toFixed(2); }
  function 
uchar(val) { return ((val 255) | 0) + ''; }
  function 
degree(val) { return ((val 360) | 0) + ''; }
  function 
percent(val) { return (val 100).toFixed(2) + '%'; }
  var 
base64encode window.btoa || function (str) {
    var 
result = [],
        
position = -1,
        
len str.length,
        
nan0nan1nan2enc = [ ,,, ];

    while (++
position len) {
      
nan0 str.charCodeAt(position);
      
nan1 str.charCodeAt(++position);
      
enc[0] = nan0 >> 2;
      
enc[1] = ((nan0 3) << 4) | (nan1 >> 4);
      if (
isNaN(nan1)) {
        
enc[2] = enc[3] = 64;
      } else {
        
nan2 str.charCodeAt(++position);
        
enc[2] = ((nan1 15) << 2) | (nan2 >> 6);
        
enc[3] = (isNaN(nan2)) ? 64 nan2 63;
      }
      
result.push(
          
alphabet.charAt(enc[0]),
          
alphabet.charAt(enc[1]),
          
alphabet.charAt(enc[2]),
          
alphabet.charAt(enc[3]));
    }
    return 
result.join('');
  };

  var 
componentMatchers = { r: /R/gg: /G/gb: /B/gh: /H/gs: /S/gl: /L/ga: /A/g, };
  var 
componentMap = { ruchargucharbucharhdegreespercentlpercentaidentity, };
  var 
isSafari = /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
  var 
isUnsupportedBrowser = /MSIE [1-8]/.test(navigator.userAgent);
  var 
supportsGradients = !(/MSIE 9.0/.test(navigator.userAgent));
  var 
supportsTransitions supportsGradients;
  var 
isTouchDevice 'ontouchstart' in document.documentElement || 'ontouchstart' in window;
  var 
alphabet 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
  var 
staticComponentValues = { r0g0b0h0s1l0.5a};
  var 
componentStops = { r2g2b2h7s2l3a};

  var 
LEFT_BUTTON 0;
  var 
TRANSITION_END isSafari 'webkitTransitionEnd' 'transitionend';
  var 
POINTER_DOWN_EVENT isTouchDevice 'touchstart' 'mousedown';
  var 
POINTER_MOVE_EVENT isTouchDevice 'touchmove' 'mousemove';
  var 
POINTER_UP_EVENT isTouchDevice 'touchend touchcancel' 'mouseup';
  var 
NEW_COLOR_EVENT 'newcolor';
  var 
EXPANDED_Z_INDEX 999999;

  function 
getGradientTemplate(componentspacestaticComponents) {
    var 
colorComponents staticComponents space.split('').map(function (component) {
      return 
componentMap[component](staticComponentValues[component]);
    }) : 
space.split('');
    var 
componentIndex space.indexOf(component);
    var 
colors = [];
    var 
componentStops[component];
    var 
i;

    
// Generate the color stops, e.g. "rgba(R, G, 0, A),rgba(R, G, 255, A)"
    
for (0n; ++i) {
      var 
frac / (1);
      
colorComponents[componentIndex] = componentMap[component](frac);
      var 
color supportsGradients ?
        
space '(' colorComponents.join().toUpperCase() + ')' :
        
'<stop stop-color="' space '(' colorComponents.join().toUpperCase() + ')" offset="' frac '"/>';
      
colors.push(color);
    }
    
colors colors.join(supportsGradients ',' '');

    
// The template function substitutes the color placeholders, e.g. R, G, A for the
    // color values specified in the color argument
    
return function (color) {
      var 
ret colors;
      for (var 
c in color) {
        
=== component || (ret ret.replace(componentMatchers[c], componentMap[c](color[c])));
      }
      if (
supportsGradients) {
        return 
'linear-gradient(to right, ' ret ')';
      } else {
        var 
svg =
          
'<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" ' +
              
'viewBox="0 0 1 1" preserveAspectRatio="none">' +
          
'<linearGradient id="the-gradient" gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="100%" y2="0%">' +
          
ret +
          
'</linearGradient>' +
          
'<rect x="0" y="0" width="1" height="1" fill="url(#the-gradient)" />' +
          
'</svg>';
        return 
'url(data:image/svg+xml;base64,' base64encode(svg) + ')';
      }
    };
  }

  function 
getRgb(c) {
    if (
'r' in c) { return c; }

    var 
rgb;
    var 
c.hc.sc.l;

    function 
hue2rgb(pqt) {
      if (
0) { += 1; }
      if (
1) { -= 1; }
      if (
6) { return + (p) * t; }
      if (
2) { return q; }
      if (
3) { return + (p) * (t) * 6; }
      return 
p;
    }

    if (
=== 0) {
      
l// achromatic
    
} else {
      var 
0.5 * (s) : s;
      var 
q;
      
hue2rgb(pq3);
      
hue2rgb(pqh);
      
hue2rgb(pq3);
    }

    var 
ret = { rrggb};
    
'a' in c && (ret.c.a);
    return 
ret;
  }

  function 
getHsl(c) {
    if (
'h' in c) { return c; }

    var 
c.rc.gc.b;
    var 
max Math.max(rgb), min Math.min(rgb);
    var 
hs= (max min) / 2;

    if (
max === min) {
      
0// achromatic
    
} else {
      var 
max min;
      
0.5 / (max min) : / (max min);
      switch (
max) {
      case 
r= (b) / + (0); break;
      case 
g= (r) / 2; break;
      case 
b= (g) / 4; break;
      }
      
/= 6;
    }

    var 
ret = { hhssl};
    
'a' in c && (ret.c.a);
    return 
ret;
  }

  
// COLOR CLASS

  
function Color(spacecolor) {
    var 
icomponents = {};

    
// Validate color space argument
    
space space.toLowerCase();
    if (!(/^(
rgb|hsl)a?$/i).test(space)) {
      throw 
'Color spaces must be any of the following: "rgb", "rgba", "hsl" or "hsla"';
    }

    
// Validate color argument
    
if (typeof color === 'string') {
      
color color.toLowerCase();
      if (/^
#[0-9a-f]{6}([0-9a-f]{2})?$/.test(color)) {
        
space.length === && color.length !== && (color += 'ff');  // Default alpha to fully opaque
        
for (1color.length+= 2) {
          
components[space[(1) / 2]] = parseInt(color.substr(i2), 16) / 255;
        }
      } else if (/^(
rgb|hsl)a?([ds,.%]+)$/.test(color)) {
        var 
parsedSpace color.match(/(rgb|hsl)a?/)[0];
        var 
componentsArray color.match(/[d.]+/g);
        if (/
rgb/.test(parsedSpace)) {
          
components.componentsArray[0] / 255;
          
components.componentsArray[1] / 255;
          
components.componentsArray[2] / 255;
        } else {
          
components.componentsArray[0] / 360;
          
components.componentsArray[1] / 100;
          
components.componentsArray[2] / 100;
        }
        
components.= +componentsArray[3];
      } else {
        throw 
'Color strings must be hexadecimal (e.g. "#00ff00", or "#00ff00ff") or CSS style (e.g. rgba(0,255,0,1))';
      }
    } else if ($.
isPlainObject(color)) {
      var 
sortedColorComponentKeys Object.keys(color).sort().join('');
      if (!(/^
a?(bgr|hls)$/i).test(sortedColorComponentKeys)) {
        throw 
'Color objects must contain either r, g and b keys, or h, s and l keys. The a key is optional.';
      }
      if (
space.split('').sort().join('') !== sortedColorComponentKeys) {
        
color = /rgb/.test('space') ? getRgb(color) : getHsl(color);
      }
      
components color;
    } else {
      throw 
'Unrecognized color format';
    }

    
// Make sure the color matches the color space. No-op if they are already the same
    
components = /rgb/.test(space) ? getRgb(components) : getHsl(components);
    
// Add an alpha channel if missing
    
isFinite(components.a) || (components.1);

    for (var 
key in components) {
      if (
components[key] < || components[key]) { throw 'Color component out of range: ' key; }
    }

    
this.getComponents = function () { return components; };
    
this.getComponent = function (componentKey) { return components[componentKey]; };
    
this.setComponent = function (componentKeyvalue) { components[componentKey] = value; };
    
this.getSpace = function () { return space; };
  }

  
Color.prototype.convertComponents = function (newSpace) {
    
newSpace newSpace || this.getSpace();
    var 
components = $.extend({}, this.getComponents());

    
// See if the components are already in the right space
    
if (new RegExp(newSpace).test(this.getSpace())) {
      
newSpace.length === && (delete components.a);
      return 
components;
    }

    
components = /rgb/.test(newSpace) ? getRgb(components) : getHsl(components);
    if (/
a/.test(newSpace)) {
      var 
this.getComponent('a');
      
components.typeof a === 'undefined' a;
    }

    return 
components;
  };

  
Color.prototype.componentsToString = function (componentsspace) {
    function 
pad(str) {
      return (
str.length === '0' '') + str;
    }
    var 
str '#';
    for (var 
0space.length; ++i) {
      
str += pad(Math.floor(255 components[space[i]]).toString(16));
    }
    return 
str;
  };

  
Color.prototype.toString = function (space) {
    
space space || this.getSpace();
    return 
this.componentsToString(this.convertComponents(space), space);
  };

  
Color.prototype.componentsToCssValuesString = function (componentsspace) {
    var 
componentArray = [];
    for (var 
0space.length; ++i) {
      var 
componentKey space[i];
      
componentArray.push(componentMap[componentKey](components[componentKey]));
    }
    return 
componentArray.join(', ');
  };

  
Color.prototype.toCssString = function (space) {
    
space space || this.getSpace();
    return 
space '(' this.componentsToCssValuesString(this.convertComponents(space), space) + ')';
  };

  
// COLORPICKER CLASS

  
function Colorpicker($eluserOptions) {
    var 
self this;
    var 
originalClasses $el.attr('class');
    var 
$originalChildren $el.children().detach();
    var 
originalText $el.text();
    
$el.addClass('colorpicker').empty();
    var 
$body = $('body');

    var 
options = $.extend({
      
color$el.css('color'),
      
colorSpace'hsla',
      
expandEvent'mousedown touchstart',
      
collapseEvent'',
      
staticComponentsfalse,
      
boundingElement$body,
      
modalfalse,
    }, 
userOptions);

    var 
color = new Color(options.colorSpaceoptions.color);

    
$el.addClass('componentcount-' color.getSpace().length).toggleClass('show-labels', !!options.labels);

    function 
addChild(className$parent) { return $('<div>').addClass(className).appendTo($parent); }
    var 
$maximizeWrapper addChild('maximize-wrapper'$el);
    var 
$innerMaximizeWrapper addChild('inner-maximize-wrapper'$maximizeWrapper);
    var 
$uiWrapper addChild('ui-wrapper'$innerMaximizeWrapper);
    var 
$displayWrapper addChild('display-wrapper'$uiWrapper);
    var 
$display addChild('display'$displayWrapper);
    var 
$sliderContainer addChild('slider-container'$uiWrapper);
    var 
sliders = $.map(color.getSpace().split(''), function (componentKey) {
      var 
$slider addChild('slider ' componentKey$sliderContainer);
      
addChild('handle'$slider).attr('data-component'componentKey);
      
$slider.data({
        
componentKeycomponentKey,
        
templategetGradientTemplate(componentKeycolor.getSpace(), options.staticComponents),
      });
      return 
$slider;
    });

    var 
$outputWrappercolorOutputFunction;
    if (
options.displayColor) {
      if (!(/^(
hex|css)$/.test(options.displayColor))) { throw 'Invalid displayColor value, should be "hex" or "css"'; }
      
$outputWrapper addChild('output-wrapper'$innerMaximizeWrapper);
      
colorOutputFunction = {
        
hexcolor.toString,
        
csscolor.toCssString,
      }[
options.displayColor].bind(coloroptions.displayColorSpace || options.colorSpace);
    }

    
// Listen to new colors, and update the UI accordingly
    
function onNewColor(evselfcomponentKeyvalue) {
      
componentKey && color.setComponent(componentKeyvalue);
      for (var 
0sliders.length; ++i) {
        var 
$slider sliders[i];
        
$slider
            
.css({
              
backgroundImage$slider.data('template')(color.getComponents()),
            })
            .
find('.handle').css({
              
left: (color.getComponent($slider.data('componentKey')) * 100) + '%',
            });
        
$display.css({ backgroundColorcolor.toCssString() });
        
options.displayColor && $outputWrapper.text(colorOutputFunction());
      }
    }
    
$el.on(NEW_COLOR_EVENTonNewColor);
    
setTimeout(onNewColor.bind(nullundefinedthis), 0);

    
// Expanding the colorpicker
    
var onClickOutside = function (ev) {
      $(
ev.target).closest($el).length || collapse();
    };
    var 
expandcollapse;
    
expand = function () {
      
$el.addClass('expanded').css({ zIndexEXPANDED_Z_INDEX });
      
options.modal && $body.addClass('colorpicker-modal');

      var 
height 0;
      
$innerMaximizeWrapper.children().each(function () { height += $(this).outerHeight(true); });
      
$innerMaximizeWrapper.css({ width$uiWrapper.width(), heightheight });
      $(
window).on(POINTER_DOWN_EVENTonClickOutside);
      
options.collapseEvent && $el.on(options.collapseEventcollapse);
      
$el.off(options.expandEventexpand);

      var 
boundingRect options.boundingElement[0].getBoundingClientRect();
      var 
uiWrapperRect $uiWrapper[0].getBoundingClientRect();
      var 
dX Math.min(0boundingRect.right uiWrapperRect.right 10);
      var 
dY Math.min(0boundingRect.bottom uiWrapperRect.bottom 10);
      
$el.css('transform''translate(' dX 'px, ' dY 'px)');
    };
    
collapse = function () {
      
supportsTransitions ?
        
$el.off(TRANSITION_END).one(TRANSITION_END, function () { $el.css({ zIndex'' }); }) :
        
$el.css({ zIndex'' });
      
$el.css({ zIndexEXPANDED_Z_INDEX });
      
$innerMaximizeWrapper.css({ width''height'' });
      
$el.removeClass('expanded');
      
options.modal && $body.removeClass('colorpicker-modal');

      $(
window).off(POINTER_DOWN_EVENTonClickOutside);
      
options.expandEvent && $el.on(options.expandEventexpand);
      
$el.css('transform''');
    };

    
options.expandEvent && $el.on(options.expandEventexpand);

    var 
triggerNewColor = function (ev) {
      var 
$target = $(ev.target);
      if (!
$target.hasClass('slider')) { return; }
      var 
offsetX isTouchDevice ?
          
ev.originalEvent.touches[0].clientX - $(ev.target).offset().left :
          $.
isNumeric(ev.offsetX) ? ev.offsetX ev.clientX - $(ev.target).offset().left;
      
$target.trigger(NEW_COLOR_EVENT, [
        
self$target.data('componentKey'), clamp(offsetX $target.outerWidth(), 01)
      ]);
      
ev.preventDefault();
      
ev.stopPropagation();
    };
    var 
onPointerUp = function () {
      $(
window).off(POINTER_MOVE_EVENTtriggerNewColor);
    };
    
$el.on(POINTER_DOWN_EVENT, function (ev) {
      var 
$target = $(ev.target);
      if (
ev.type === 'mousedown' && ev.button !== LEFT_BUTTON || !$target.hasClass('slider')) { return; }

      
triggerNewColor(ev);

      $(
window).on(POINTER_MOVE_EVENTtriggerNewColor);
      $(
window).one(POINTER_UP_EVENTonPointerUp);
    });

    
// Public functions
    
this.destroy = function () {
      $(
window).off(POINTER_UP_EVENTonPointerUp);
      $(
window).off(POINTER_MOVE_EVENTtriggerNewColor);
      $(
window).off(POINTER_DOWN_EVENTonClickOutside);
      
$el.off().empty().removeData('colorpicker')
          .
attr('class'originalClasses).html($originalChildren).text(originalText);
    };
    
this.toString = function () { return color.toString.apply(colorarguments); };
    
this.toCssString = function () { return color.toCssString.apply(colorarguments); };
    
this.toObject = function () { return color.convertComponents.apply(colorarguments); };
    
this.getColorSpace = function () { return color.getSpace(); };
    
this.on $el.on.bind($el);
    
this.off $el.off.bind($el);

    
$el.data('colorpicker'this);
    return 
this;
  }

  
// REGISTER PLUGIN

  
$.fn.colorpicker = function (options) {
    if (
isUnsupportedBrowser) { throw 'Colorpicker does not work with your browser'; }
    var 
$el this.eq(0);
    if (!
$el.length) { throw 'No element matched'; }
    return 
$el.data('colorpicker') || new Colorpicker($eloptions);
  };

}(
window.$));
?>
Онлайн: 2
Реклама