mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2024-12-29 09:22:22 -05:00
Implement Color, RGBColor & GrayColor.
This commit is contained in:
parent
bd5c906047
commit
66105dd4ac
3 changed files with 360 additions and 0 deletions
89
src/color/GrayColor.js
Normal file
89
src/color/GrayColor.js
Normal file
|
@ -0,0 +1,89 @@
|
|||
GrayColor = Color.extend({
|
||||
beans: true,
|
||||
|
||||
initialize: function() {
|
||||
if (arguments.length) {
|
||||
var arg = arguments[0];
|
||||
if (typeof arg == 'number') {
|
||||
this._gray = arg;
|
||||
this.alpha = arg.alpha ? arg.alpha : -1;
|
||||
} else if (arg instanceof Color) {
|
||||
this._gray = arg.gray;
|
||||
this.alpha = arg.alpha;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getType: function() {
|
||||
return this.alpha == -1 ? 'gray' : 'agray';
|
||||
},
|
||||
|
||||
getComponents: function() {
|
||||
return [this._gray, this._alpha];
|
||||
},
|
||||
|
||||
/**
|
||||
* A value between 0 and 1 that specifies the amount of red in the RGB color.
|
||||
*/
|
||||
getGray: function() {
|
||||
return this._gray;
|
||||
},
|
||||
|
||||
setGray: function(gray) {
|
||||
this._cssString = null;
|
||||
this._gray = gray;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the component color values of the RGBColor are the
|
||||
* same as those of the supplied one.
|
||||
*
|
||||
* @param obj the RGBColor to compare with
|
||||
* @return {@true if the RGBColor is the same}
|
||||
*/
|
||||
equals: function(color) {
|
||||
if (color instanceof GrayColor) {
|
||||
return this.gray == color.gray &&
|
||||
this.alpha == color.alpha;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
toString: function() {
|
||||
return '{ gray: ' + this.gray
|
||||
+ ((this.alpha != -1) ? ', alpha: ' + this.alpha : '')
|
||||
+ ' }';
|
||||
},
|
||||
|
||||
getCssString: function() {
|
||||
if (!this._cssString) {
|
||||
var component = Math.round((1 - this.gray) * 255) + ',';
|
||||
this._cssString = 'rgba('
|
||||
+ component + component + component
|
||||
+ ((this.alpha != -1) ? this.alpha : 1)
|
||||
+ ')';
|
||||
}
|
||||
return this._cssString;
|
||||
}
|
||||
}, new function() {
|
||||
var fields = { beans: true };
|
||||
|
||||
// Using the standard NTSC conversion formula that is used for
|
||||
// calculating the effective luminance of an RGB color:
|
||||
// http://www.mathworks.com/support/solutions/en/data/1-1ASCU/index.html?solution=1-1ASCU
|
||||
var componentWeights = {
|
||||
red: 0.2989,
|
||||
green: 0.5870,
|
||||
blue: 0.114
|
||||
};
|
||||
|
||||
Base.each(componentWeights, function(weight, key) {
|
||||
fields['get' + key.capitalize()] = function() {
|
||||
return 1 - this._gray;
|
||||
};
|
||||
fields['set' + key.capitalize()] = function(value) {
|
||||
this._gray = this._gray * (1 - weight) + weight * (1 - value);
|
||||
};
|
||||
});
|
||||
return fields;
|
||||
});
|
199
src/color/RGBColor.js
Normal file
199
src/color/RGBColor.js
Normal file
|
@ -0,0 +1,199 @@
|
|||
RGBColor = Color.extend(new function() {
|
||||
// TODO: convert hex codes to [r,g,b]?
|
||||
var namedColors = {
|
||||
lightpink: 'FFB6C1', pink: 'FFC0CB', crimson: 'DC143C',
|
||||
lavenderblush: 'FFF0F5', palevioletred: 'DB7093', hotpink: 'FF69B4',
|
||||
deeppink: 'FF1493', mediumvioletred: 'C71585', orchid: 'DA70D6',
|
||||
thistle: 'D8BFD8', plum: 'DDA0DD', violet: 'EE82EE', fuchsia: 'FF00FF',
|
||||
darkmagenta: '8B008B', purple: '800080', mediumorchid: 'BA55D3',
|
||||
darkviolet: '9400D3', darkorchid: '9932CC', indigo: '4B0082',
|
||||
blueviolet: '8A2BE2', mediumpurple: '9370DB', mediumslateblue: '7B68EE',
|
||||
slateblue: '6A5ACD', darkslateblue: '483D8B', ghostwhite: 'F8F8FF',
|
||||
lavender: 'E6E6FA', blue: '0000FF', mediumblue: '0000CD',
|
||||
darkblue: '00008B', navy: '000080', midnightblue: '191970',
|
||||
royalblue: '4169E1', cornflowerblue: '6495ED', lightsteelblue: 'B0C4DE',
|
||||
lightslategray: '778899', slategray: '708090', dodgerblue: '1E90FF',
|
||||
aliceblue: 'F0F8FF', steelblue: '4682B4', lightskyblue: '87CEFA',
|
||||
skyblue: '87CEEB', deepskyblue: '00BFFF', lightblue: 'ADD8E6',
|
||||
powderblue: 'B0E0E6', cadetblue: '5F9EA0', darkturquoise: '00CED1',
|
||||
azure: 'F0FFFF', lightcyan: 'E0FFFF', paleturquoise: 'AFEEEE',
|
||||
aqua: '00FFFF', darkcyan: '008B8B', teal: '008080', darkslategray: '2F4F4F',
|
||||
mediumturquoise: '48D1CC', lightseagreen: '20B2AA', turquoise: '40E0D0',
|
||||
aquamarine: '7FFFD4', mediumaquamarine: '66CDAA', mediumspringgreen: '00FA9A',
|
||||
mintcream: 'F5FFFA', springgreen: '00FF7F', mediumseagreen: '3CB371',
|
||||
seagreen: '2E8B57', honeydew: 'F0FFF0', darkseagreen: '8FBC8F',
|
||||
palegreen: '98FB98', lightgreen: '90EE90', limegreen: '32CD32',
|
||||
lime: '00FF00', forestgreen: '228B22', green: '008000', darkgreen: '006400',
|
||||
lawngreen: '7CFC00', chartreuse: '7FFF00', greenyellow: 'ADFF2F',
|
||||
darkolivegreen: '556B2F', yellowgreen: '9ACD32', olivedrab: '6B8E23',
|
||||
ivory: 'FFFFF0', beige: 'F5F5DC', lightyellow: 'FFFFE0',
|
||||
lightgoldenrodyellow: 'FAFAD2', yellow: 'FFFF00', olive: '808000',
|
||||
darkkhaki: 'BDB76B', palegoldenrod: 'EEE8AA', lemonchiffon: 'FFFACD',
|
||||
khaki: 'F0E68C', gold: 'FFD700', cornsilk: 'FFF8DC', goldenrod: 'DAA520',
|
||||
darkgoldenrod: 'B8860B', floralwhite: 'FFFAF0', oldlace: 'FDF5E6',
|
||||
wheat: 'F5DEB3', orange: 'FFA500', moccasin: 'FFE4B5', papayawhip: 'FFEFD5',
|
||||
blanchedalmond: 'FFEBCD', navajowhite: 'FFDEAD', antiquewhite: 'FAEBD7',
|
||||
tan: 'D2B48C', burlywood: 'DEB887', darkorange: 'FF8C00', bisque: 'FFE4C4',
|
||||
linen: 'FAF0E6', peru: 'CD853F', peachpuff: 'FFDAB9', sandybrown: 'F4A460',
|
||||
chocolate: 'D2691E', saddlebrown: '8B4513', seashell: 'FFF5EE',
|
||||
sienna: 'A0522D', lightsalmon: 'FFA07A', coral: 'FF7F50',
|
||||
orangered: 'FF4500', darksalmon: 'E9967A', tomato: 'FF6347',
|
||||
salmon: 'FA8072', mistyrose: 'FFE4E1', lightcoral: 'F08080', snow: 'FFFAFA',
|
||||
rosybrown: 'BC8F8F', indianred: 'CD5C5C', red: 'FF0000', brown: 'A52A2A',
|
||||
firebrick: 'B22222', darkred: '8B0000', maroon: '800000', white: 'FFFFFF',
|
||||
whitesmoke: 'F5F5F5', gainsboro: 'DCDCDC', lightgrey: 'D3D3D3',
|
||||
silver: 'C0C0C0', darkgray: 'A9A9A9', gray: '808080', dimgray: '696969',
|
||||
black: '000000'
|
||||
};
|
||||
|
||||
function stringToComponents(string) {
|
||||
return string.match(/^#[0-9a-f]{3,6}$/i)
|
||||
? hexToComponents(string)
|
||||
: namedToComponents(string);
|
||||
};
|
||||
|
||||
function hexToComponents(string) {
|
||||
var hex = string.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
|
||||
if (hex.length >= 4) {
|
||||
var rgb = [];
|
||||
for (var i = 1; i < 4; i++)
|
||||
rgb.push((hex[i].length == 1 ? hex[i] + hex[i] : hex[i]).toInt(16) / 255);
|
||||
return rgb;
|
||||
}
|
||||
};
|
||||
|
||||
function namedToComponents(name) {
|
||||
var hex = namedColors[name];
|
||||
if (!hex) throw Error('The named color "' + name + '" does not exist.');
|
||||
return hex && hexToComponents(hex);
|
||||
};
|
||||
|
||||
return {
|
||||
beans: true,
|
||||
|
||||
initialize: function() {
|
||||
if (arguments.length == 1) {
|
||||
var arg = arguments[0];
|
||||
if (typeof arg == 'string') {
|
||||
var components = stringToComponents(arg);
|
||||
this._red = components[0];
|
||||
this._green = components[1];
|
||||
this._blue = components[2];
|
||||
this.alpha = -1;
|
||||
} else if (Array.isArray(arg)) {
|
||||
this._red = arg[0];
|
||||
this._green = arg[1];
|
||||
this._blue = arg[2];
|
||||
this.alpha = (arg.length > 3) ? arg[3] : -1;
|
||||
} else if (arg.red !== undefined) {
|
||||
this._red = arg.red;
|
||||
this._blue = arg.blue;
|
||||
this._green = arg.green;
|
||||
this.alpha = arg.alpha ? arg.alpha : -1;
|
||||
} else if (arg.gray !== undefined) {
|
||||
this._red = this._green = this._blue = 1 - arg.gray;
|
||||
this.alpha = arg.alpha ? arg.alpha : -1;
|
||||
};
|
||||
} else if (arguments.length >= 3) {
|
||||
this._red = arguments[0];
|
||||
this._green = arguments[1];
|
||||
this._blue = arguments[2];
|
||||
this.alpha = (arguments.length > 3) ? arguments[3] : -1;
|
||||
}
|
||||
},
|
||||
|
||||
getType: function() {
|
||||
return this.alpha == -1 ? 'rgb' : 'argb';
|
||||
},
|
||||
|
||||
getComponents: function() {
|
||||
return [this._red, this._blue, this._green, this._alpha];
|
||||
},
|
||||
|
||||
/**
|
||||
* A value between 0 and 1 that specifies the amount of red in the RGB color.
|
||||
*/
|
||||
getRed: function() {
|
||||
return this._red;
|
||||
},
|
||||
|
||||
setRed: function(red) {
|
||||
this._cssString = null;
|
||||
this._red = red;
|
||||
},
|
||||
|
||||
/**
|
||||
* A value between 0 and 1 that specifies the amount of green in the RGB color.
|
||||
*/
|
||||
getGreen: function() {
|
||||
return this._green;
|
||||
},
|
||||
|
||||
setGreen: function(green) {
|
||||
this._cssString = null;
|
||||
this._green = green;
|
||||
},
|
||||
|
||||
/**
|
||||
* A value between 0 and 1 that specifies the amount of blue in the RGB color.
|
||||
*/
|
||||
getBlue: function() {
|
||||
return this._blue;
|
||||
},
|
||||
|
||||
setBlue: function(blue) {
|
||||
this._cssString = null;
|
||||
this._blue = blue;
|
||||
},
|
||||
|
||||
getGray: function() {
|
||||
// Using the standard NTSC conversion formula that is used for
|
||||
// calculating the effective luminance of an RGB color:
|
||||
// http://www.mathworks.com/support/solutions/en/data/1-1ASCU/index.html?product=IP&solution=1-1ASCU
|
||||
|
||||
return 1 - (this._red * 0.2989 + this._green * 0.5870
|
||||
+ this._blue * 0.114);
|
||||
},
|
||||
|
||||
setGray: function(gray) {
|
||||
this._red = this._green = this._blue = gray;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the component color values of the RGBColor are the
|
||||
* same as those of the supplied one.
|
||||
*
|
||||
* @param obj the RGBColor to compare with
|
||||
* @return {@true if the RGBColor is the same}
|
||||
*/
|
||||
equals: function(color) {
|
||||
if (color instanceof RGBColor) {
|
||||
return this.red == color.red &&
|
||||
this.green == color.green &&
|
||||
this.blue == color.blue &&
|
||||
this.alpha == color.alpha;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
toString: function() {
|
||||
return '{ red: ' + this.red
|
||||
+ ', green: ' + this.green
|
||||
+ ', blue: ' + this.blue
|
||||
+ ((this.alpha != -1) ? ', alpha: ' + this.alpha : '')
|
||||
+ ' }';
|
||||
},
|
||||
|
||||
getCssString: function() {
|
||||
if (!this._cssString) {
|
||||
this._cssString = 'rgba('
|
||||
+ (Math.round(this.red * 255)) + ', '
|
||||
+ (Math.round(this.green * 255)) + ', '
|
||||
+ (Math.round(this.blue * 255)) + ', '
|
||||
+ ((this.alpha != -1) ? this.alpha : 1)
|
||||
+ ')';
|
||||
}
|
||||
return this._cssString;
|
||||
}
|
||||
};
|
||||
});
|
72
test/tests/Color.js
Normal file
72
test/tests/Color.js
Normal file
|
@ -0,0 +1,72 @@
|
|||
module('RGB Color');
|
||||
|
||||
test('Set named color', function() {
|
||||
var doc = new Doc();
|
||||
var path = new Path();
|
||||
path.fillColor = 'red';
|
||||
compareRGBColors(path.fillColor, new RGBColor(1, 0, 0));
|
||||
equals(path.fillColor.getCssString(), 'rgba(255, 0, 0, 1)');
|
||||
});
|
||||
|
||||
test('Set color to hex', function() {
|
||||
var doc = new Doc();
|
||||
var path = new Path();
|
||||
path.fillColor = '#ff0000';
|
||||
compareRGBColors(path.fillColor, new RGBColor(1, 0, 0));
|
||||
equals(path.fillColor.getCssString(), 'rgba(255, 0, 0, 1)');
|
||||
|
||||
var path = new Path();
|
||||
path.fillColor = '#f00';
|
||||
compareRGBColors(path.fillColor, new RGBColor(1, 0, 0));
|
||||
equals(path.fillColor.getCssString(), 'rgba(255, 0, 0, 1)');
|
||||
});
|
||||
|
||||
test('Set color to object', function() {
|
||||
var doc = new Doc();
|
||||
var path = new Path();
|
||||
path.fillColor = { red: 1, green: 0, blue: 1};
|
||||
compareRGBColors(path.fillColor, new RGBColor(1, 0, 1));
|
||||
equals(path.fillColor.getCssString(), 'rgba(255, 0, 255, 1)');
|
||||
|
||||
var path = new Path();
|
||||
path.fillColor = { gray: 0.2 };
|
||||
compareRGBColors(path.fillColor, new RGBColor(0.8, 0.8, 0.8));
|
||||
equals(path.fillColor.getCssString(), 'rgba(204, 204, 204, 1)');
|
||||
});
|
||||
|
||||
test('Set color to array', function() {
|
||||
var doc = new Doc();
|
||||
var path = new Path();
|
||||
path.fillColor = [1, 0, 0];
|
||||
compareRGBColors(path.fillColor, new RGBColor(1, 0, 0));
|
||||
equals(path.fillColor.getCssString(), 'rgba(255, 0, 0, 1)');
|
||||
});
|
||||
|
||||
test('Get gray from RGBColor', function() {
|
||||
var color = new RGBColor(1, 0.5, 0.2);
|
||||
compareNumbers(color.gray, 0.38458251953125);
|
||||
|
||||
var color = new RGBColor(0.5, 0.2, 0.1);
|
||||
compareNumbers(color.gray, 0.72137451171875);
|
||||
});
|
||||
|
||||
test('Gray Color', function() {
|
||||
var color = new GrayColor(1);
|
||||
compareNumbers(color.gray, 1);
|
||||
compareNumbers(color.red, 1);
|
||||
|
||||
color.red = 0.5;
|
||||
compareNumbers(color.gray, '0.84999');
|
||||
|
||||
color.green = 0.2;
|
||||
compareNumbers(color.gray, '0.82051');
|
||||
});
|
||||
|
||||
test('Converting Colors', function() {
|
||||
var color = new RGBColor(1, 0.5, 0.2);
|
||||
compareNumbers(new GrayColor(color).gray, 0.38299560546875);
|
||||
|
||||
var color = new GrayColor(0.2);
|
||||
var rgbColor = new RGBColor(color);
|
||||
compareRGBColors(rgbColor, [ 0.8, 0.8, 0.8, 1 ]);
|
||||
});
|
Loading…
Reference in a new issue