You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
278 lines
4.4 KiB
278 lines
4.4 KiB
9 years ago
|
|
||
|
/*!
|
||
|
* Stylus - HSLA
|
||
|
* Copyright (c) Automattic <developer.wordpress.com>
|
||
|
* MIT Licensed
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Module dependencies.
|
||
|
*/
|
||
|
|
||
|
var Node = require('./node')
|
||
|
, nodes = require('./');
|
||
|
|
||
|
/**
|
||
|
* Initialize a new `HSLA` with the given h,s,l,a component values.
|
||
|
*
|
||
|
* @param {Number} h
|
||
|
* @param {Number} s
|
||
|
* @param {Number} l
|
||
|
* @param {Number} a
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
var HSLA = exports = module.exports = function HSLA(h,s,l,a){
|
||
|
Node.call(this);
|
||
|
this.h = clampDegrees(h);
|
||
|
this.s = clampPercentage(s);
|
||
|
this.l = clampPercentage(l);
|
||
|
this.a = clampAlpha(a);
|
||
|
this.hsla = this;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Inherit from `Node.prototype`.
|
||
|
*/
|
||
|
|
||
|
HSLA.prototype.__proto__ = Node.prototype;
|
||
|
|
||
|
/**
|
||
|
* Return hsla(n,n,n,n).
|
||
|
*
|
||
|
* @return {String}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
HSLA.prototype.toString = function(){
|
||
|
return 'hsla('
|
||
|
+ this.h + ','
|
||
|
+ this.s.toFixed(0) + '%,'
|
||
|
+ this.l.toFixed(0) + '%,'
|
||
|
+ this.a + ')';
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Return a clone of this node.
|
||
|
*
|
||
|
* @return {Node}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
HSLA.prototype.clone = function(parent){
|
||
|
var clone = new HSLA(
|
||
|
this.h
|
||
|
, this.s
|
||
|
, this.l
|
||
|
, this.a);
|
||
|
clone.lineno = this.lineno;
|
||
|
clone.column = this.column;
|
||
|
clone.filename = this.filename;
|
||
|
return clone;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Return a JSON representation of this node.
|
||
|
*
|
||
|
* @return {Object}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
HSLA.prototype.toJSON = function(){
|
||
|
return {
|
||
|
__type: 'HSLA',
|
||
|
h: this.h,
|
||
|
s: this.s,
|
||
|
l: this.l,
|
||
|
a: this.a,
|
||
|
lineno: this.lineno,
|
||
|
column: this.column,
|
||
|
filename: this.filename
|
||
|
};
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Return rgba `RGBA` representation.
|
||
|
*
|
||
|
* @return {RGBA}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
HSLA.prototype.__defineGetter__('rgba', function(){
|
||
|
return nodes.RGBA.fromHSLA(this);
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* Return hash.
|
||
|
*
|
||
|
* @return {String}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
HSLA.prototype.__defineGetter__('hash', function(){
|
||
|
return this.rgba.toString();
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* Add h,s,l to the current component values.
|
||
|
*
|
||
|
* @param {Number} h
|
||
|
* @param {Number} s
|
||
|
* @param {Number} l
|
||
|
* @return {HSLA} new node
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
HSLA.prototype.add = function(h,s,l){
|
||
|
return new HSLA(
|
||
|
this.h + h
|
||
|
, this.s + s
|
||
|
, this.l + l
|
||
|
, this.a);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Subtract h,s,l from the current component values.
|
||
|
*
|
||
|
* @param {Number} h
|
||
|
* @param {Number} s
|
||
|
* @param {Number} l
|
||
|
* @return {HSLA} new node
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
HSLA.prototype.sub = function(h,s,l){
|
||
|
return this.add(-h, -s, -l);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Operate on `right` with the given `op`.
|
||
|
*
|
||
|
* @param {String} op
|
||
|
* @param {Node} right
|
||
|
* @return {Node}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
HSLA.prototype.operate = function(op, right){
|
||
|
switch (op) {
|
||
|
case '==':
|
||
|
case '!=':
|
||
|
case '<=':
|
||
|
case '>=':
|
||
|
case '<':
|
||
|
case '>':
|
||
|
case 'is a':
|
||
|
case '||':
|
||
|
case '&&':
|
||
|
return this.rgba.operate(op, right);
|
||
|
default:
|
||
|
return this.rgba.operate(op, right).hsla;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Return `HSLA` representation of the given `color`.
|
||
|
*
|
||
|
* @param {RGBA} color
|
||
|
* @return {HSLA}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
exports.fromRGBA = function(rgba){
|
||
|
var r = rgba.r / 255
|
||
|
, g = rgba.g / 255
|
||
|
, b = rgba.b / 255
|
||
|
, a = rgba.a;
|
||
|
|
||
|
var min = Math.min(r,g,b)
|
||
|
, max = Math.max(r,g,b)
|
||
|
, l = (max + min) / 2
|
||
|
, d = max - min
|
||
|
, h, s;
|
||
|
|
||
|
switch (max) {
|
||
|
case min: h = 0; break;
|
||
|
case r: h = 60 * (g-b) / d; break;
|
||
|
case g: h = 60 * (b-r) / d + 120; break;
|
||
|
case b: h = 60 * (r-g) / d + 240; break;
|
||
|
}
|
||
|
|
||
|
if (max == min) {
|
||
|
s = 0;
|
||
|
} else if (l < .5) {
|
||
|
s = d / (2 * l);
|
||
|
} else {
|
||
|
s = d / (2 - 2 * l);
|
||
|
}
|
||
|
|
||
|
h %= 360;
|
||
|
s *= 100;
|
||
|
l *= 100;
|
||
|
|
||
|
return new HSLA(h,s,l,a);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Adjust lightness by `percent`.
|
||
|
*
|
||
|
* @param {Number} percent
|
||
|
* @return {HSLA} for chaining
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
HSLA.prototype.adjustLightness = function(percent){
|
||
|
this.l = clampPercentage(this.l + this.l * (percent / 100));
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Adjust hue by `deg`.
|
||
|
*
|
||
|
* @param {Number} deg
|
||
|
* @return {HSLA} for chaining
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
HSLA.prototype.adjustHue = function(deg){
|
||
|
this.h = clampDegrees(this.h + deg);
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Clamp degree `n` >= 0 and <= 360.
|
||
|
*
|
||
|
* @param {Number} n
|
||
|
* @return {Number}
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function clampDegrees(n) {
|
||
|
n = n % 360;
|
||
|
return n >= 0 ? n : 360 + n;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Clamp percentage `n` >= 0 and <= 100.
|
||
|
*
|
||
|
* @param {Number} n
|
||
|
* @return {Number}
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function clampPercentage(n) {
|
||
|
return Math.max(0, Math.min(n, 100));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Clamp alpha `n` >= 0 and <= 1.
|
||
|
*
|
||
|
* @param {Number} n
|
||
|
* @return {Number}
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function clampAlpha(n) {
|
||
|
return Math.max(0, Math.min(n, 1));
|
||
|
}
|