jasonkarns
5/14/2012 - 2:26 AM

Parse RGB colors

Parse RGB colors

describe('RGB',function(){
  beforeEach(function(){
    this.addMatchers({
      toEqualRGB: function(expected) {
        return (this.actual.r === expected.r &&
                this.actual.g === expected.g &&
                this.actual.b === expected.b);
      }
    });
  });

  describe('constructor', function(){
    it('works',function(){
      spyOn(color, 'RGB').andCallThrough();
      var rgb = new color.RGB();
      
      expect(color.RGB).toHaveBeenCalled();
      expect(rgb instanceof color.RGB).toBeTruthy();
    });
    
    it('accepts r,g,b params as numbers', function(){
      var rgb = new color.RGB(12, 34, 56);
      expect(rgb).toEqualRGB({r:12, g:34, b:56});
    });
    
    it('rounds fractional r,g,b params to integers', function(){
      var rgb = new color.RGB(12.4, 34.5, 56.6);
      expect(rgb).toEqualRGB({r:12, g:35, b:57});
    });

    it('accepts r,g,b params strings', function(){
      var rgb = new color.RGB('12', '34', '56');
      expect(rgb).toEqualRGB({r:12, g:34, b:56});
    });
    
    it('accepts an rgb hex string', function(){
      var rgb = new color.RGB('123456');
      expect(rgb).toEqualRGB({r:18, g:52, b:86});
    });
    
    it('accepts an {r,g,b} object', function(){
      var rgb = new color.RGB({r:12, g:34, b:56});
      expect(rgb).toEqualRGB({r:12, g:34, b:56});
    });
  });
  
/*
  describe('new-less function', function(){
    it('calls constructor', function(){
      spyOn(color, 'RGB').andCallThrough();
      var rgb = color.RGB();
      
      expect(color.RGB).toHaveBeenCalled();
      expect(rgb instanceof color.RGB).toBeTruthy();    
    });
  });
*/  
  describe('parse', function(){
    it('returns an RGB instance', function(){
      var rgb = color.RGB.parse('123456');
      expect(rgb instanceof color.RGB).toBeTruthy();
    });
    it('from an RGB HEX string', function(){
      var rgb = color.RGB.parse('123456');
      expect(rgb).toEqualRGB({r:18, g:52, b:86});
    });
  });
  
  describe('grayscale', function(){
    it('converts rgb to grayscale', function(){
      var gray = color.RGB.parse('123456').grayscale();
      expect(gray).toEqualRGB({r:46, g:46, b:46});
    });
  });
  
  describe('toString', function(){
    it('prints HEX code', function(){
      var rgb = color.RGB.parse('123456').toString();
      expect(rgb).toBe('123456');
    });
    
    it('prints 6 digits', function(){
      var rgb = color.RGB.parse('03C506').toString();
      expect(rgb).toBe('03C506');
    });
    
    it('prints in uppercase', function(){
      var rgb = color.RGB.parse('F3C5A6').toString();
      expect(rgb).toBe('F3C5A6');
    });
  });
});
var color = {
  RGB : function(){
//    if (!(this instanceof color.RGB)) {
//        return new color.RGB.apply(this, arguments);
//    }
    var rgb;
    
    if(arguments.length === 1){
      rgb = (typeof arguments[0] === 'string')? color.RGB.parse(arguments[0]) : arguments[0];
        
    } else if(arguments.length === 3){
      if(typeof arguments[0] === 'number' && typeof arguments[1] === 'number' && typeof arguments[2] === 'number' ){
        rgb = {r: arguments[0], g: arguments[1], b: arguments[2]};
      } else if(typeof arguments[0] === 'string' && typeof arguments[1] === 'string' && typeof arguments[2] === 'string' ){
        rgb = {r: parseInt(arguments[0], 10), g: parseInt(arguments[1], 10), b: parseInt(arguments[2], 10)};
      }
    }
    
    if(rgb){
      this.r = Math.round(rgb.r);
      this.g = Math.round(rgb.g);
      this.b = Math.round(rgb.b);
    }
  }
};

color.RGB.parse = function(hex){
  return new color.RGB({
    r: parseInt(hex.substring(0, 2), 16),
    g: parseInt(hex.substring(2, 4), 16),
    b: parseInt(hex.substring(4, 6), 16)
  });
};

color.RGB.prototype.grayscale = function(){
//  var gray = 0.2126 * this.r + 0.7152 * this.g + 0.0722 * this.b;
  var gray = 0.3 * this.r + 0.59 * this.g + 0.11 * this.b;

  return new color.RGB({r: gray, g: gray, b: gray});
};

color.RGB.prototype.toString = function(){
  function toHex(num){
    return ("0" + num.toString(16).toUpperCase()).substr(-2);
  }
  return (toHex(this.r) + toHex(this.g) + toHex(this.b));
};