lettuce
Version:
Lettuce JS, Mini Mobile Framework for Romantic with DSL.
567 lines (522 loc) • 20.6 kB
JavaScript
/*
* MelonJS Game Engine
* Copyright (C) 2011 - 2013, Olivier Biot, Jason Oster
* http://www.melonjs.org
*/
(function () {
var cssToRGB = {
// CSS1
"black" : [ 0, 0, 0 ],
"silver" : [ 192, 192, 129 ],
"gray" : [ 128, 128, 128 ],
"white" : [ 255, 255, 255 ],
"maroon" : [ 128, 0, 0 ],
"red" : [ 255, 0, 0 ],
"purple" : [ 128, 0, 128 ],
"fuchsia" : [ 255, 0, 255 ],
"green" : [ 0, 128, 0 ],
"lime" : [ 0, 255, 0 ],
"olive" : [ 128, 128, 0 ],
"yellow" : [ 255, 255, 0 ],
"navy" : [ 0, 0, 128 ],
"blue" : [ 0, 0, 255 ],
"teal" : [ 0, 128, 128 ],
"aqua" : [ 0, 255, 255 ],
// CSS2
"orange" : [ 255, 165, 0 ],
// CSS3
"aliceblue" : [ 240, 248, 245 ],
"antiquewhite" : [ 250, 235, 215 ],
"aquamarine" : [ 127, 255, 212 ],
"azure" : [ 240, 255, 255 ],
"beige" : [ 245, 245, 220 ],
"bisque" : [ 255, 228, 196 ],
"blanchedalmond" : [ 255, 235, 205 ],
"blueviolet" : [ 138, 43, 226 ],
"brown" : [ 165, 42, 42 ],
"burlywood" : [ 222, 184, 35 ],
"cadetblue" : [ 95, 158, 160 ],
"chartreuse" : [ 127, 255, 0 ],
"chocolate" : [ 210, 105, 30 ],
"coral" : [ 255, 127, 80 ],
"cornflowerblue" : [ 100, 149, 237 ],
"cornsilk" : [ 255, 248, 220 ],
"crimson" : [ 220, 20, 60 ],
"darkblue" : [ 0, 0, 139 ],
"darkcyan" : [ 0, 139, 139 ],
"darkgoldenrod" : [ 184, 134, 11 ],
"darkgray[*]" : [ 169, 169, 169 ],
"darkgreen" : [ 0, 100, 0 ],
"darkgrey[*]" : [ 169, 169, 169 ],
"darkkhaki" : [ 189, 183, 107 ],
"darkmagenta" : [ 139, 0, 139 ],
"darkolivegreen" : [ 85, 107, 47 ],
"darkorange" : [ 255, 140, 0 ],
"darkorchid" : [ 153, 50, 204 ],
"darkred" : [ 139, 0, 0 ],
"darksalmon" : [ 233, 150, 122 ],
"darkseagreen" : [ 143, 188, 143 ],
"darkslateblue" : [ 72, 61, 139 ],
"darkslategray" : [ 47, 79, 79 ],
"darkslategrey" : [ 47, 79, 79 ],
"darkturquoise" : [ 0, 206, 209 ],
"darkviolet" : [ 148, 0, 211 ],
"deeppink" : [ 255, 20, 147 ],
"deepskyblue" : [ 0, 191, 255 ],
"dimgray" : [ 105, 105, 105 ],
"dimgrey" : [ 105, 105, 105 ],
"dodgerblue" : [ 30, 144, 255 ],
"firebrick" : [ 178, 34, 34 ],
"floralwhite" : [ 255, 250, 240 ],
"forestgreen" : [ 34, 139, 34 ],
"gainsboro" : [ 220, 220, 220 ],
"ghostwhite" : [ 248, 248, 255 ],
"gold" : [ 255, 215, 0 ],
"goldenrod" : [ 218, 165, 32 ],
"greenyellow" : [ 173, 255, 47 ],
"grey" : [ 128, 128, 128 ],
"honeydew" : [ 240, 255, 240 ],
"hotpink" : [ 255, 105, 180 ],
"indianred" : [ 205, 92, 92 ],
"indigo" : [ 75, 0, 130 ],
"ivory" : [ 255, 255, 240 ],
"khaki" : [ 240, 230, 140 ],
"lavender" : [ 230, 230, 250 ],
"lavenderblush" : [ 255, 240, 245 ],
"lawngreen" : [ 124, 252, 0 ],
"lemonchiffon" : [ 255, 250, 205 ],
"lightblue" : [ 173, 216, 230 ],
"lightcoral" : [ 240, 128, 128 ],
"lightcyan" : [ 224, 255, 255 ],
"lightgoldenrodyellow" : [ 250, 250, 210 ],
"lightgray" : [ 211, 211, 211 ],
"lightgreen" : [ 144, 238, 144 ],
"lightgrey" : [ 211, 211, 211 ],
"lightpink" : [ 255, 182, 193 ],
"lightsalmon" : [ 255, 160, 122 ],
"lightseagreen" : [ 32, 178, 170 ],
"lightskyblue" : [ 135, 206, 250 ],
"lightslategray" : [ 119, 136, 153 ],
"lightslategrey" : [ 119, 136, 153 ],
"lightsteelblue" : [ 176, 196, 222 ],
"lightyellow" : [ 255, 255, 224 ],
"limegreen" : [ 50, 205, 50 ],
"linen" : [ 250, 240, 230 ],
"mediumaquamarine" : [ 102, 205, 170 ],
"mediumblue" : [ 0, 0, 205 ],
"mediumorchid" : [ 186, 85, 211 ],
"mediumpurple" : [ 147, 112, 219 ],
"mediumseagreen" : [ 60, 179, 113 ],
"mediumslateblue" : [ 123, 104, 238 ],
"mediumspringgreen" : [ 0, 250, 154 ],
"mediumturquoise" : [ 72, 209, 204 ],
"mediumvioletred" : [ 199, 21, 133 ],
"midnightblue" : [ 25, 25, 112 ],
"mintcream" : [ 245, 255, 250 ],
"mistyrose" : [ 255, 228, 225 ],
"moccasin" : [ 255, 228, 181 ],
"navajowhite" : [ 255, 222, 173 ],
"oldlace" : [ 253, 245, 230 ],
"olivedrab" : [ 107, 142, 35 ],
"orangered" : [ 255, 69, 0 ],
"orchid" : [ 218, 112, 214 ],
"palegoldenrod" : [ 238, 232, 170 ],
"palegreen" : [ 152, 251, 152 ],
"paleturquoise" : [ 175, 238, 238 ],
"palevioletred" : [ 219, 112, 147 ],
"papayawhip" : [ 255, 239, 213 ],
"peachpuff" : [ 255, 218, 185 ],
"peru" : [ 205, 133, 63 ],
"pink" : [ 255, 192, 203 ],
"plum" : [ 221, 160, 221 ],
"powderblue" : [ 176, 224, 230 ],
"rosybrown" : [ 188, 143, 143 ],
"royalblue" : [ 65, 105, 225 ],
"saddlebrown" : [ 139, 69, 19 ],
"salmon" : [ 250, 128, 114 ],
"sandybrown" : [ 244, 164, 96 ],
"seagreen" : [ 46, 139, 87 ],
"seashell" : [ 255, 245, 238 ],
"sienna" : [ 160, 82, 45 ],
"skyblue" : [ 135, 206, 235 ],
"slateblue" : [ 106, 90, 205 ],
"slategray" : [ 112, 128, 144 ],
"slategrey" : [ 112, 128, 144 ],
"snow" : [ 255, 250, 250 ],
"springgreen" : [ 0, 255, 127 ],
"steelblue" : [ 70, 130, 180 ],
"tan" : [ 210, 180, 140 ],
"thistle" : [ 216, 191, 216 ],
"tomato" : [ 255, 99, 71 ],
"turquoise" : [ 64, 224, 208 ],
"violet" : [ 238, 130, 238 ],
"wheat" : [ 245, 222, 179 ],
"whitesmoke" : [ 245, 245, 245 ],
"yellowgreen" : [ 154, 205, 50 ]
};
/**
* A color manipulation object.
* @class
* @extends Object
* @memberOf me
* @constructor
* @param {Float32Array|Number} [r=0] red component or array of color components
* @param {Number} [g=0] green component
* @param {Number} [b=0] blue component
* @param {Number} [alpha=1.0] alpha value
*/
me.Color = Object.extend(
/** @scope me.Color.prototype */
{
/** @ignore */
init : function (r, g, b, alpha) {
/**
* Color components in a Float32Array suitable for WebGL
* @name glArray
* @memberOf me.Color
* @type {Float32Array}
* @readonly
*/
if (typeof (this.glArray) === "undefined") {
this.glArray = new Float32Array([ 0.0, 0.0, 0.0, 1.0 ]);
}
return this.setColor(r, g, b, alpha);
},
/**
* Set this color to the specified value.
* @name setColor
* @memberOf me.Color
* @function
* @param {Float32Array|Number} r red component [0 .. 255] or array of color components
* @param {Number} g green component [0 .. 255]
* @param {Number} b blue component [0 .. 255]
* @param {Number} [alpha=1.0] alpha value [0.0 .. 1.0]
* @return {me.Color} Reference to this object for method chaining
*/
setColor : function (r, g, b, alpha) {
if (r instanceof Float32Array) {
return this.setGLColor(r);
}
this.r = r;
this.g = g;
this.b = b;
this.alpha = alpha;
return this;
},
/**
* Set this color to the specified value.
* @name setGLColor
* @memberOf me.Color
* @function
* @param {Float32Array} glArray WebGL color components
* @return {me.Color} Reference to this object for method chaining
*/
setGLColor : function (glArray) {
this.glArray[0] = (glArray[0] || 0).clamp(0, 1);
this.glArray[1] = (glArray[1] || 0).clamp(0, 1);
this.glArray[2] = (glArray[2] || 0).clamp(0, 1);
this.glArray[3] = typeof(glArray[3]) === "undefined" ? 1.0 : (+glArray[3]).clamp(0, 1);
return this;
},
/**
* Create a new copy of this color object.
* @name clone
* @memberOf me.Color
* @function
* @return {me.Color} Reference to the newly cloned object
*/
clone : function () {
return me.pool.pull("me.Color", this.glArray);
},
/**
* Copy a color object or CSS color into this one.
* @name copy
* @memberOf me.Color
* @function
* @param {me.Color|String} color
* @return {me.Color} Reference to this object for method chaining
*/
copy : function (color) {
return (
(color instanceof me.Color) ?
this.setGLColor(color.toGL()) :
this.parseCSS(color)
);
},
/**
* Blend this color with the given one using addition.
* @name add
* @memberOf me.Color
* @function
* @param {me.Color} color
* @return {me.Color} Reference to this object for method chaining
*/
add : function (color) {
this.glArray[0] = (this.glArray[0] + color.glArray[0]).clamp(0, 1);
this.glArray[1] = (this.glArray[1] + color.glArray[1]).clamp(0, 1);
this.glArray[2] = (this.glArray[2] + color.glArray[2]).clamp(0, 1);
this.glArray[3] = (this.glArray[3] + color.glArray[3]) / 2;
return this;
},
/**
* Darken this color value by 0..1
* @name darken
* @memberOf me.Color
* @function
* @param {Number} scale
* @return {me.Color} Reference to this object for method chaining
*/
darken : function (scale) {
scale = scale.clamp(0, 1);
this.glArray[0] *= scale;
this.glArray[1] *= scale;
this.glArray[2] *= scale;
return this;
},
/**
* Lighten this color value by 0..1
* @name lighten
* @memberOf me.Color
* @function
* @param {Number} scale
* @return {me.Color} Reference to this object for method chaining
*/
lighten : function (scale) {
scale = scale.clamp(0, 1);
this.glArray[0] = (this.glArray[0] + (1 - this.glArray[0]) * scale).clamp(0, 1);
this.glArray[1] = (this.glArray[1] + (1 - this.glArray[1]) * scale).clamp(0, 1);
this.glArray[2] = (this.glArray[2] + (1 - this.glArray[2]) * scale).clamp(0, 1);
return this;
},
/**
* Generate random r,g,b values for this color object
* @name random
* @memberOf me.Color
* @function
* @return {me.Color} Reference to this object for method chaining
*/
random : function () {
return this.setColor(
Math.random() * 256,
Math.random() * 256,
Math.random() * 256,
this.alpha
);
},
/**
* Return true if the r,g,b,a values of this color are equal with the
* given one.
* @name equals
* @memberOf me.Color
* @function
* @param {me.Color} color
* @return {Boolean}
*/
equals : function (color) {
return (
(this.glArray[0] === color.glArray[0]) &&
(this.glArray[1] === color.glArray[1]) &&
(this.glArray[2] === color.glArray[2]) &&
(this.glArray[3] === color.glArray[3])
);
},
/**
* Parse a CSS color string and set this color to the corresponding
* r,g,b values
* @name parseCSS
* @memberOf me.Color
* @function
* @param {String} color
* @return {me.Color} Reference to this object for method chaining
*/
parseCSS : function (cssColor) {
// TODO : Memoize this function by caching its input
if (!(cssColor in cssToRGB)) {
return this.parseRGB(cssColor);
}
return this.setColor.apply(this, cssToRGB[cssColor]);
},
/**
* Parse an RGB or RGBA CSS color string
* @name parseRGB
* @memberOf me.Color
* @function
* @param {String} color
* @return {me.Color} Reference to this object for method chaining
*/
parseRGB : function (rgbColor) {
// TODO : Memoize this function by caching its input
if (typeof(rgbColor) === "string") {
var start;
if (rgbColor.substring(0, 4) === "rgba") {
start = 5;
}
else if (rgbColor.substring(0, 3) === "rgb") {
start = 4;
}
else {
return this.parseHex(rgbColor);
}
var color = rgbColor.slice(start, -1).split(/\s*,\s*/);
return this.setColor.apply(this, color);
} else {
throw new me.Color.Error(
"invalid parameter (not a string)"
);
}
},
/**
* Parse a Hex color ("#RGB" or "#RRGGBB" format) and set this color to
* the corresponding r,g,b values
* @name parseHex
* @memberOf me.Color
* @function
* @param {String} color
* @return {me.Color} Reference to this object for method chaining
*/
parseHex : function (hexColor) {
// TODO : Memoize this function by caching its input
if (typeof(hexColor) === "string") {
// Remove the # if present
if (hexColor.charAt(0) === "#") {
hexColor = hexColor.substring(1, hexColor.length);
}
var r, g, b;
if (hexColor.length < 6) {
// 3 char shortcut is used, double each char
r = parseInt(hexColor.charAt(0) + hexColor.charAt(0), 16);
g = parseInt(hexColor.charAt(1) + hexColor.charAt(1), 16);
b = parseInt(hexColor.charAt(2) + hexColor.charAt(2), 16);
}
else {
r = parseInt(hexColor.substring(0, 2), 16);
g = parseInt(hexColor.substring(2, 4), 16);
b = parseInt(hexColor.substring(4, 6), 16);
}
return this.setColor(r, g, b);
} else {
throw new me.Color.Error(
"invalid parameter (not a string)"
);
}
},
/**
* Returns the private glArray
* @ignore
*/
toGL : function () {
return this.glArray;
},
/**
* Get the color in "#RRGGBB" format
* @name toHex
* @memberOf me.Color
* @function
* @return {String}
*/
toHex : function () {
// TODO : Memoize this function by caching its result until any of
// the r,g,b,a values are changed
return "#" + this.r.toHex() + this.g.toHex() + this.b.toHex();
},
/**
* Get the color in "rgb(R,G,B)" format
* @name toRGB
* @memberOf me.Color
* @function
* @return {String}
*/
toRGB : function () {
// TODO : Memoize this function by caching its result until any of
// the r,g,b,a values are changed
return "rgb(" +
this.r + "," +
this.g + "," +
this.b +
")";
},
/**
* Get the color in "rgba(R,G,B,A)" format
* @name toRGBA
* @memberOf me.Color
* @function
* @return {String}
*/
toRGBA : function () {
// TODO : Memoize this function by caching its result until any of
// the r,g,b,a values are changed
return "rgba(" +
this.r + "," +
this.g + "," +
this.b + "," +
this.alpha +
")";
}
});
/**
* Color Red Component
* @type Number
* @name r
* @readonly
* @memberOf me.Color
*/
Object.defineProperty(me.Color.prototype, "r", {
get : function () { return ~~(this.glArray[0] * 255); },
set : function (value) { this.glArray[0] = (~~value || 0).clamp(0, 255) / 255.0; },
enumerable : true,
configurable : true
});
/**
* Color Green Component
* @type Number
* @name g
* @readonly
* @memberOf me.Color
*/
Object.defineProperty(me.Color.prototype, "g", {
get : function () { return ~~(this.glArray[1] * 255); },
set : function (value) { this.glArray[1] = (~~value || 0).clamp(0, 255) / 255.0; },
enumerable : true,
configurable : true
});
/**
* Color Blue Component
* @type Number
* @name b
* @readonly
* @memberOf me.Color
*/
Object.defineProperty(me.Color.prototype, "b", {
get : function () { return ~~(this.glArray[2] * 255); },
set : function (value) { this.glArray[2] = (~~value || 0).clamp(0, 255) / 255.0; },
enumerable : true,
configurable : true
});
/**
* Color Alpha Component
* @type Number
* @name alpha
* @readonly
* @memberOf me.Color
*/
Object.defineProperty(me.Color.prototype, "alpha", {
get : function () { return this.glArray[3]; },
set : function (value) { this.glArray[3] = typeof(value) === "undefined" ? 1.0 : (+value).clamp(0, 1); },
enumerable : true,
configurable : true
});
/**
* Base class for me.Color exception handling.
* @name Error
* @class
* @memberOf me.Vector2d
* @constructor
* @param {String} msg Error message.
*/
me.Color.Error = me.Error.extend({
init : function (msg) {
this._super(me.Error, "init", [ msg ]);
this.name = "me.Color.Error";
}
});
})();