読者です 読者をやめる 読者になる 読者になる

c4se記:さっちゃんですよ☆

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

.。oO(此のblogは、主に音樂考察Programmingに分類されますよ。ヾ(〃l _ l)ノ゙♬♪♡

音樂はSoundCloud等バラバラの場所に公開中です。申し訳ないがlinkをたどるなどして探してください。

考察は現在は主に此のblogで公表中です。

programmingは、ひろくみせるものはGitHubで、個人的なものはBitBucketで開発中です。

c4se

JavaScript CSS3 Color class

Color.generateSequence()を作りたかった。DOMアニメーション用下地。
getter/setterの作りもおかしい。

Color = (function () {

var mathAbs = Math.abs,
    mathFloor = Math.floor,
    mathCeil = Math.ceil,
    mathRound = Math.round,
    mathMax = Math.max,
    mathMin = Math.min,
    cssUnits = ['px', 'em', 'ex', '%', 'pt', 'in', 'cm', 'mm', 'pc'],
    colorNames = {
      aliceblue: [240, 248, 255, 1], antiquewhite: [250, 235, 215, 1], aqua: [0, 255, 255, 1],
      aquamarine: [127, 255, 212, 1], azure: [240, 255, 255, 1], beige: [245, 245, 220, 1],
      bisque: [255, 228, 196, 1], black: [0, 0, 0, 1], blanchedalmond: [255, 235, 205, 1],
      blue: [0, 0, 255, 1], blueviolet: [138, 43, 226, 1], brown: [165, 42, 42, 1],
      burlywood: [222, 184, 135, 1], cadetblue: [95, 158, 160, 1], chartreuse: [127, 255, 0, 1],
      chocolate: [210, 105, 30, 1], coral: [255, 127, 80, 1], cornflowerblue: [100, 149, 237, 1],
      cornsilk: [255, 248, 220, 1], crimson: [220, 20, 60, 1], cyan: [0, 255, 255, 1],
      darkblue: [0, 0, 139, 1], darkcyan: [0, 139, 139, 1], darkgoldenrod: [184, 134, 11, 1],
      darkgray: [169, 169, 169, 1], darkgreen: [0, 100, 0, 1], darkgrey: [169, 169, 169, 1],
      darkkhaki: [189, 183, 107, 1], darkmagenta: [139, 0, 139, 1], darkolivegreen: [85, 107, 47, 1],
      darkorange: [255, 140, 0, 1], darkorchid: [153, 50, 204, 1], darkred: [139, 0, 0, 1],
      darksalmon: [233, 150, 122, 1], darkseagreen: [143, 188, 143, 1], darkslateblue: [72, 61, 139, 1],
      darkslategray: [47, 79, 79, 1], darkslategrey: [47, 79, 79, 1], darkturquoise: [0, 206, 209, 1],
      darkviolet: [148, 0, 211, 1], deeppink: [255, 20, 147, 1], deepskyblue: [0, 191, 255, 1],
      dimgray: [105, 105, 105, 1], dimgrey: [105, 105, 105, 1], dodgerblue: [30, 144, 255, 1],
      firebrick: [178, 34, 34, 1], floralwhite: [255, 250, 240, 1], forestgreen: [34, 139, 34, 1],
      fuchsia: [255, 0, 255, 1], gainsboro: [220, 220, 220, 1], ghostwhite: [248, 248, 255, 1],
      gold: [255, 215, 0, 1], goldenrod: [218, 165, 32, 1], gray: [128, 128, 128, 1],
      green: [0, 128, 0, 1], greenyellow: [173, 255, 47, 1], grey: [128, 128, 128, 1],
      honeydew: [240, 255, 240, 1], hotpink: [255, 105, 180, 1], indianred: [205, 92, 92, 1],
      indigo: [75, 0, 130, 1], ivory: [255, 255, 240, 1], khaki: [240, 230, 140, 1],
      lavender: [230, 230, 250, 1], lavenderblush: [255, 240, 245, 1], lawngreen: [124, 252, 0, 1],
      lemonchiffon: [255, 250, 205, 1], lightblue: [173, 216, 230, 1], lightcoral: [240, 128, 128, 1],
      lightcyan: [224, 255, 255, 1], lightgoldenrodyellow: [250, 250, 210, 1], lightgray: [211, 211, 211, 1],
      lightgreen: [144, 238, 144, 1], lightgrey: [211, 211, 211, 1], lightpink: [255, 182, 193, 1],
      lightsalmon: [255, 160, 122, 1], lightseagreen: [32, 178, 170, 1], lightskyblue: [135, 206, 250, 1],
      lightslategray: [119, 136, 153, 1], lightslategrey: [119, 136, 153, 1], lightsteelblue: [176, 196, 222, 1],
      lightyellow: [255, 255, 224, 1], lime: [0, 255, 0, 1], limegreen: [50, 205, 50, 1],
      linen: [250, 240, 230, 1], magenta: [255, 0, 255, 1], maroon: [128, 0, 0, 1],
      mediumaquamarine: [102, 205, 170, 1], mediumblue: [0, 0, 205, 1], mediumorchid: [186, 85, 211, 1],
      mediumpurple: [147, 112, 219, 1], mediumseagreen: [60, 179, 113, 1], mediumslateblue: [123, 104, 238, 1],
      mediumspringgreen: [0, 250, 154, 1], mediumturquoise: [72, 209, 204, 1], mediumvioletred: [199, 21, 133, 1],
      midnightblue: [25, 25, 112, 1], mintcream: [245, 255, 250, 1], mistyrose: [255, 228, 225, 1],
      moccasin: [255, 228, 181, 1], navajowhite: [255, 222, 173, 1], navy: [0, 0, 128, 1],
      oldlace: [253, 245, 230, 1], olive: [128, 128, 0, 1], olivedrab: [107, 142, 35, 1],
      orange: [255, 165, 0, 1], orangered: [255, 69, 0, 1], orchid: [218, 112, 214, 1],
      palegoldenrod: [238, 232, 170, 1], palegreen: [152, 251, 152, 1], paleturquoise: [175, 238, 238, 1],
      palevioletred: [219, 112, 147, 1], papayawhip: [255, 239, 213, 1], peachpuff: [255, 218, 185, 1],
      peru: [205, 133, 63, 1], pink: [255, 192, 203, 1], plum: [221, 160, 221, 1],
      powderblue: [176, 224, 230, 1], purple: [128, 0, 128, 1], red: [255, 0, 0, 1],
      rosybrown: [188, 143, 143, 1], royalblue: [65, 105, 225, 1], saddlebrown: [139, 69, 19, 1],
      salmon: [250, 128, 114, 1], sandybrown: [244, 164, 96, 1], seagreen: [46, 139, 87, 1],
      seashell: [255, 245, 238, 1], sienna: [160, 82, 45, 1], silver: [192, 192, 192, 1],
      skyblue: [135, 206, 235, 1], slateblue: [106, 90, 205, 1], slategray: [112, 128, 144, 1],
      slategrey: [112, 128, 144, 1], snow: [255, 250, 250, 1], springgreen: [0, 255, 127, 1],
      steelblue: [70, 130, 180, 1], tan: [210, 180, 140, 1], teal: [0, 128, 128, 1],
      thistle: [216, 191, 216, 1], tomato: [255, 99, 71, 1], turquoise: [64, 224, 208, 1],
      violet: [238, 130, 238, 1], wheat: [245, 222, 179, 1], white: [255, 255, 255, 1],
      whitesmoke: [245, 245, 245, 1], yellow: [255, 255, 0, 1], yellowgreen: [154, 205, 50],
      transparent: [null, null, null, 0]
    };


/**
 * @param fromObj Object
 * @param toObj Object
 * @param doseOverwrite Boolean (=false)
 */
function mixin (toObj, fromObj, doseOverwrite) {
  var key;

  for (key in fromObj) if (fromObj.hasOwnProperty(key) && fromObj[key] !== void 0) {
    if (doesOverwrite || toObj[key] === void 0) {
      toObj[key] = fromObj[key];
    }
  }
}


/**
 * @param obj Object target object.
 * @param key String getter and setter name.
 * @param getter Function
 * @param setter Function
 *   setter(value)
 */
function defineGetterAndSetter (obj, key, getter, setter) {
  if (Object.defineProperty) {
    Object.defineProperty(obj, key, {
      get: getter,
      set: setter
    });
  } else if (obj.__defineGetter__) {
    obj.__defineGetter__(key, getter);
    obj.__defineSetter__(key, setter);
  } else {
    obj[key] = function (val) {
      if (val === void 0) {
        getter();
      } else {
        setter(val);
      }
    };
  }
}
defineGetterAndSetter.isGetter = Object.defineProperty || Object.__defineGetter__;


/**
 * @param red Number 0<= n <= 255
 * @param green Number 0 <= n <= 255
 * @param blue Number 0 <= n <= 255
 * @param alpha Number 0 <= n <= 1
 * @return Array [hue Number, saturation Number, lightness Number, alpha Number]
 */
function convertRgbaToHsla (red, green, blue, alpha) {
  var max, min, diff,
      hue = 0,
      saturation = 0,
      lightness = (max + min) / 2;

  red /= 255;
  green /= 255;
  blue /= 255;
  max = mathMax(red, green, blue);
  min = mathMin(red, green, blue);
  diff = max - min;
  if (0 < lightness && lightness < 1) {
    saturation = diff / (lightness < 0.5 ? lightness * 2 : 2 - lightness * 2);
  }
  if (diff > 0) {
    if (max === red && max !== green) {
      hue = (green - blue) / diff * 60;
    } else if (max === green && max !== blue) {
      hue = (blue - red) / diff * 60;
    } else if (max === blueRatio && max !== redRatio) {
      hue = (red - green) / diff * 60;
    }
  }
  return [hue, mathRound(saturation * 100), mathRaound(lightness * 100), alpha];
}


/**
 * @param hue Number 0<= n <= 360
 * @param saturation Number 0 <= n <= 100
 * @param lightness Number 0 <= n <= 100
 * @param alpha Number 0 <= n <= 100
 * @return Array [red Number, green Number, blue Number, alpha Number]
 */
function convertHslaToRgba (hue, saturation, lightness, alpha) {
  var rgba, chroma, x, m;

  hue /= 100;
  saturation /= 100;
  lightness /= 100;
  chroma = (1 - abs(lightness * 2 - 1)) * saturation;
  x = chroma * (1 - abs(hue / 60 % 2 - 1));
  m = lightness - chroma / 2;
  if (hue < 60) {
    rgba = [chroma + m, x + m, m, alpha];
  } else if (hue < 120) {
    rgba = [x + m, chroma + m, m, alpha];
  } else if (hue < 180) {
    rgba = [m, chroma + m, x + m, alpha];
  } else if (hue < 240) {
    rgba = [m, x + m, chroma + m, alpha];
  } else if (hue < 300) {
    rgba = [x + m, m, chroma + m, alpha];
  } else {
    rgba = [chroma + m, m, x + m, alpha];
  }
  return rgba;
}


/**
 * @param color String
 * @return Hash
 *   {red: Number, green: Number, blue: Number,
 *    hue: Number, saturation: Number, lightness: Number,
 *    alpha: Number}
 */
function colorStringToHash (color) {
  var matchResult, i, j, flag, hexDigit,
      hexDigits = {
        '0': 0, '1': 1, '2': 2, '3': 3,
        '4': 4, '5': 5, '6': 6, '7': 7,
        '8': 8, '9': 9,
        'A', 10, 'B': 11, 'C': 12, 'D': 13,
        'E': 14, 'F': 15,
        'a': 10, 'b': 11, 'c': 12, 'd': 13,
        'e': 14, 'f': 15
      },
      rgba = [0, 0, 0, 1],
      hsla = [0, 0, 0, 1];

  function percentStringToNumber (str, max) {
    if (str.charAt(str.length - 1) === '%') {
      return Number(str.slice(0, -1)) * max / 100;
    } else {
      return Number(str);
    }
  }

  if (color.charAt(0) == '#') {
    if (color.length === 7) {
      for (i = 0; i < 3; i += 1) {
        rgba[i] = hexDigits[color.charAt(i * 2 + 1)] * 16 +
                  hexDigits[color.charAt(i * 2 + 2)];
      }
      rgba[3] = 1;
    } else if (color.length === 4) {
      for (i = 0; i < 3; i += 1) {
        j = hexDigits[color.charAt(i + 1)];
        rgba[i] = j * 16 + j;
      }
      rgba[3] = 1;
    } else {
      throw Error('colorStringToHash(): Illegal #xxxxxx||#xxx format. (' + color + ')');
    }
    hsla = convertRgbaToHsla(rgba[0], rgba[1], rgba[2], rgba[3]);
  } else if (color.match(/rgb\(\s*(\d+%?)\s*,\s*(\d+%?)\s*,\s*(\d+%?)\s*\)/i)) {
    rgba = [percentStringToNumber(matchResult[1], 255),
      percentStringToNumber(matchResult[1], 255),
      percentStringToNumber(matchResult[2], 255),
      rgba[3]];
    hsla = convertRgbaToHsla(rgba[0], rgba[1], rgba[2], rgba[3]);
    hsla = convertRgbaToHsla(rgba[0], rgba[1], rgba[2], rgba, [3]);
  } else if (color.match(/rgba\(\s*(\d+%?)\s*,\s*(\d+%?)\s*,\s*(\d+%?)\s*,\s*(\d(?:\.\d+)?)\s*\)/i)) {
    rgba = [percentStringToNumber(matchResult[1], 255),
      percentStringToNumber(matchResult[1], 255),
      percentStringToNumber(matchResult[2], 255),
      Number(matchResult[3])];
    hsla = convertRgbaToHsla(rgba[0], rgba[1], rgba[2], rgba[3]);
  } else if (color.match(/hsl\(\s*(\d+)\s*,\s*(\d+%)\s*,\s*(\d+%)\s*\)/i)) {
    hsla = [Number(matchResult[0]),
      percentStringToNumber(matchResult[1], 100),
      percentStringToNumber(matchResult[2], 100),
      hsla[3]];
    rgba = convertHslaToRgba(hsla[0], hsla[1], hsla[2], hsla[3]);
  } else if (color.match(/hsla\(\s*(\d+)\s*,\s*(\d+%)\s*,\s*(\d+%)\s*,\s*(\d+(?:\.\d+)?)\s*\)/i)) {
    hsla = [Number(matchResult[0]),
      percentStringToNumber(matchResult[1], 100),
      percentStringToNumber(matchResult[2], 100),
      Number(matchResult[3])];
    rgba = convertHslaToRgba(hsla[0], hsla[1], hsla[2], hsla[3]);
  } else {
    flag = false;
    for (colorName in colorNames) if (colorNames.hasOwnProperty(colorName) {
      if (color.match(colorName, 'i')) {
        rgba = colorNames[colorName];
        hlsa = convertRgbaToHsla(rgba[0], rgba[1], rgba[2], rgba[3]);
        flag = true;
        break;
      }
    }
    if (!flag) {throw Error('colorStringToHash(): Unknown color format. (' + color + ')');}
  }
  return {
    red: rgba[0],
    green: rgba[1],
    blue: rgba[2],
    hue: hsla[0],
    saturation: hsla[1],
    lightness: hsla[2],
    alpha: rgba[3]
  };
}


/**
 * @class Color
 * Color(color String) CSS3 color string
 *   #xxxxxx
 *   #xxx
 *   rgb(n||n%, n||n%. n||n%)
 *   rbga(n||n%, n||n%, n|n%, n||n%)
 *   hsl(n, n%, n%)
 *   hsla(n, n%, n%, n)
 *   colorname
 * Color(color Hash)
 *   {red: n||n%, blue: n||n%, green: n||n%, alpha: n||n%}
 *   {r: n||n%, b: n||n%, g: n||n%, a: n||n%}
 *   {hue: n||n%, s: n||n%, v: n||n%, alpha: n||n%}
 *   {h: n||n%, s: n||n%, v: n||n%, a: n||n%}
 * Color(red Number||String, blue Number||String, green Number||String)
 * Color(red Number||String, blue Number||String, green Number||String, alpha Number||String)
 */
function Color(arg1, arg2, arg3, arg4) {
  var color;

  if (!(this instanceof Color)) {
    switch (arguments.length) {
    case 1: return new Color(arg1);
    case 3: return new Color(arg1, arg2, arg3);
    case 4: return new Color(arg1, arg2, arg3, arg4);
    default:
      throw Error('Assertion! Color(): Illegal arguments.length (It\'s ' + arguments.length + ')');
  }
  this._red = 0;
  this._green = 0;
  this._blue = 0;
  this._hue = 0;
  this._saturation = 0;
  this._lightness = 0;
  this._alpha = 0;
  switch (arguments.length) {
  case 1:
    if (arg1 instanceof String) {
      mixin(this, colorStringToHash(arg1), true);
    } else if (['red', 'green', 'blue', 'r', 'g', 'b'].some(function (elm) {return arg1[elm] !== void 0;})) {
      this._red = (arg1.red !== void 0 ? arg1.red :
        (arg1.r !== void 0 ? arg1.r : this._red));
      this.grren = (arg1.green !== void 0 ? arg1.green :
        (arg1.g !== void 0 ? arg1.g : this._green));
      this._blue = (arg1.blue !== void 0 ? arg1.blue :
        (arg1.b !== void 0 ? arg1.b : this._blue));
      this._alpha = (arg1.alpha !== void 0 ? arg1.alpha :
        (arg1.a !== void 0 ? arg1.a : this._alpha));
      color = convertRgbaToHsla(this._red, this._green, this._blue, this._alpha);
      this._hue = color[0];
      this._saturation = color[1];
      this._lightness = color[2];
    } else if (['hue', 'saturation', 'lightness', 'h', 's', 'l'].some(function (elm) {return arg1[elm] !== void 0;})) {
      this._hue = (arg1.hue !== void 0 ? arg1.hue :
          (arg1.r !== void 0 ? arg1.r : this._hue));
      this._saturation = (arg1.saturartion !== void 0 ? arg1.saturartion :
          (arg1.g !== void 0 ? arg1.g : this.saturartion));
      this._lightness = (arg1.lightness !== void 0 ? arg1.lightness :
          (arg1.b !== void 0 ? arg1.b : this._lightness));
      this._alpha = (arg1.alpha !== void 0 ? arg1.alpha :
          (arg1.a !== void 0 ? arg1.a : this._alpha));
      color = convertHslaToRgba(this._hue, this._saturation, this._lightness, this._alpha);
      this._red = color[0];
      this._green = color[1];
      this._blue = color[2];
    } else {throw Error('Assertion! Color(): Illegal color hash.');}
    break;
  case 3: case 4:
    this._red = arg1;
    this._green = arg2;
    this._blue = arg3;
    this._alpha = arg4 !== void 0 ? arg4 : 1;
    break;
  default:
    throw Error('Assertion! Color(): Illegal arguments.length (It\'s ' + arguments.length + ')');
  }
}


/**
 * @param color1 Color
 * @param color2 Color
 * @return Color
 */
Color.add = function (color1, color2) {
  var result = new Color(color1._red, color1._green, color1._blue, color1._alpha);

  return result.add(color2);
};


/**
 * @param color1 Color
 * @param color2 Color
 * @return Color
 */
Color.sub = function (color1, color2) {
  var result = new Color(color1._red, color1._green, color1._blue, color1._alpha);

  return result.sub(color2);
};


/**
 * @param color Color
 * @param denominator Number
 * @return Color
 */
Color.div = function (color, denominator) {
  var result = new Color(color._red, color._green, color._blue, color._alpha);

  return result.div(denominator);
}


/**
 * @param colorStart Color
 * @param colorEnd Color
 * @param sequenceNumber Number NaturalNumber. result.length
 * @return Color[]
 */
Color.generateSequence = function (colorStart, colorEnd, sequenceNumber) {
  var i,
      result = new Array(sequenceNumber),
      diff = Color.sub(colorStart, colorEnd).div(sequenceNumber - 1);

  result[0] = colorStart;
  for (i = 1; i < sequenceNumber - 1; i += 1) {
    result[i] = Color.add(result[i - 1], diff);
  }
  result[sequenceNumber - 1] = colorEnd;
  return result;
};


Color.prototype = {
  /**
   * Setter. For setter, don't touch raw property. Must use this.
   * @param colorHash Hash
   * @return Color this
   */
  set: function (colorHash) {
    var hsla, rgba;

    ['red r', 'grren g', 'blue b',
     'hue h', 'saturation s', 'lightness l',
     'alpha a'].forEach(function (elm) {
       var names = elm.split(' ');

       if (!colorHash[name[0]] === void 0) {
         colorHash[name[0]] = colorName[name[1]];
       }
    });
    if (colorHash.red !== void 0 ||
        colorHash.green !== void 0 ||
        colorHash.blue !== void 0) {
      rgba = [colorHash.red !== void 0 ? colorHash.red : this._red,
        colorHash.green !== void 0 ? colorHash.green : this._green,
        colorHash.blue !== void 0 ? colorHash.blue : this._blue,
        colorHash.alpha];
      hsla = convertRgbaToHsla(rgba[0], rgba[1], rgba[2], rgba[3]);
      this._hue = hsla[0];
      this._saturation = hsla[1];
      this._lightness = hlsa[2];
    } else if (colorHash.hue !== void 0 ||
               colorHash.saturation !== void 0 ||
               colorHash.blue !== void 0) {
      hsla = [colorHash.hue !== void 0 ? colorHash.hue : this._hue,
        colorHash.saturation !== void 0 ? colorHash.saturation : this._saturation,
        colorHash.lightness !== void 0 ? colorHash.lightness : this._lightness,
        colorHash.alpha];
      rgba = convertHslaToRgba(hsla[0], hsla[1], hsla[2], hsla[3]);
      this._red = rgba[0];
      this._green = rgba[1];
      this._blue = rgba[2];
    }
    if (colorHash.alpha !== void 0) {
      this._alpha = colorHash.alpha;
    }
    return this;
  },


  /**
   * @return Array [red Number, green Number, blue Number, alpha Number]
   */
  rgba: function () {return [this._red, this._green, this._blue, this._alpha];},


  /**
   * @return Array [hue Number, saturation Number, lightness Number, alpha Number]
   */
  hsla: function () {return [this._hue, this._saturation, this._lightness, this._alpha];},


  /**
   * @return Array [red Number, green Number, blue Number]
   */
  rgb: function () {return [this._red, this._green, this._blue];},


  /**
   * @return Array [hue Number, saturation Number, lightness Number]
   */
  hsl: function () {return [this._hue, this._saturation, this._lightness];},


  /**
   * @param color Color
   * @return Color this
   */
  add: function (color) {
    var hash = {
      red: this._red + color._red,
      green: this._green + color._green,
      blue: this._blue + color._blue,
      alpha: 1 - (1 - this._alpha) * (1 - color._alpha)
    };

    if (hash.red > 255) {hash.red = 255;}
    if (hash.green > 255) {hash.green = 255;}
    if (hash.blue > 255) {hash.blue = 255;}
    this.set(hash);
    return this;
  },


  /**
   * @param color Color
   * @return Color this
   */
  sub: function (color) {
    var hash = {
      red: this._red - color._red,
      green: this._green - color._green,
      blue: this._blue - color._blue,
      alpha: color._alpha === 1 ? 0 : (this._alpha - color._alpha) / (1 - color._alpha)
    };

    if (hash.red < 0) {hash.red = 0;}
    if (hash.green < 0) {hash.green = 0;}
    if (hash.blue < 0) {hash.blue = 0;}
    this.set(hash);
    return this;
  },


  /**
   * @param denominator Number
   * @return Color this
   */
  div: function (denominator) {
    if (!denominator) {
      throw Error('Assertion! Color.prototype.div(): The denominator must not be zero.');
    }
    this.set({
      red: this._red / denominator,
      green: this._green / denominator,
      blue: this._blue / denominator,
      alpha: this._alpha
    });
    return this;
  }
};


(function () {
  var Color_prototype = Color.prototype;

  defineGetterAndSetter(Color_prototype, 'red',
    function () {return this._red;},
    function (val) {
      this.set({red: val});
      return this;
    });
  defineGetterAndSetter(Color_prototype, 'green',
    function () {return this._green;},
    function (val) {
      this.set({green: val});
      return this;
    });
  defineGetterAndSetter(Color_prototype, 'blue',
    function () {return this._blue;},
    function (val) {
      this.set({blue: val});
      return this;
    });
  defineGetterAndSetter(Color_prototype, 'hue',
    function () {return this._hue;},
    function (val) {
      this.set({hue: val});
      return this;
    });
  defineGetterAndSetter(Color_prototype, 'saturation',
    function () {return this._saturation;},
    function (val) {
      this.set({saturation: val});
      return this;
    });
  defineGetterAndSetter(Color_prototype, 'lightness',
    function () {return this._lightness;},
    function (val) {
      this.set({lightness: val});
      return this;
    });
  defineGetterAndSetter(Color_prototype, 'alpha',
    function () {return this._alpha;},
    function (val) {
      this._alpha = val;
      return this;
    });
  mixin(Color_prototype, {
    r: Color_prototype.red,
    g: Color_prototype.green,
    b: Color_prototype.blue,
    h: Color_prototype.hue,
    s: Color_prototype.saturation,
    l: Color_prototype.lightness,
    a: Color_prototype.alpha,
  });
}());


return Color;

}());