@minix-iot/ui
Version:
基于Vue的移动端轻量级UI组件库
130 lines (96 loc) • 3.39 kB
JavaScript
export class Color {
static WHITE = new Color([255,255,255],1)
static BLACK = new Color([0,0,0],1)
static REG_HEX = /^#([a-f0-9]{6})([a-f0-9]{2})?$/i;
static REG_HEX_ABBR = /^#([a-f0-9]{3,4})$/i;
static FromHex(color){
const parseNormal = color =>{
const matches = color.match(Color.REG_HEX);
const channels = [0, 0, 0];
const colorString = matches[1];
for (let i = 0; i < 3; i++) {
channels[i] = parseInt(colorString.slice(i * 2, i * 2 + 2), 16);
}
const alpha = matches[2] ? parseFloat(matches[2], 16) / 255 : NaN;
return { channels, alpha };
}
const parseAbbr = color =>{
const matches = color.match(Color.REG_HEX_ABBR);
const match = matches[1];
const channels = [0, 0, 0];
for (let i = 0; i < 3; i++) {
channels[i] = parseInt(match[i] + match[i], 16);
}
const alpha = match[4] ? parseFloat(match[4], 16) / 255 : NaN;
return { channels, alpha };
}
if(!color.startsWith('#')){
return new Color(null, NaN)
}
const {channels, alpha} = color.length > 5 ? parseNormal(color) : parseAbbr(color)
return new Color(channels,alpha)
}
static Mix(color1,color2,weight){
const p = weight === undefined ? 0.5 : weight;
const w = 2 * p - 1;
const a = (color1.a || 1) - (color2.a || 1);
const w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2;
const w2 = 1 - w1;
const r = w1 * color1.r + w2 * color2.r
const g = w1 * color1.g + w2 * color2.g
const b = w1 * color1.b + w2 * color2.b
const alpha = color1.a * p + color2.a * (1-p)
return new Color([r,g,b],alpha)
}
static Shift(color, weight) {
return weight > 0 ? Color.Shade(color, weight) : Color.Tint(color, -weight);
}
static Tint(color, weight) {
return Color.Mix(Color.WHITE, color, weight);
}
static Shade(color, weight) {
return Color.Mix(Color.BLACK, color, weight);
}
constructor(channels,alpha){
this._channels = channels;
this._alpha = alpha;
}
get r(){
return this._channels[0]
}
get g(){
return this._channels[1]
}
get b(){
return this._channels[2]
}
get a(){
return this._alpha
}
get luminosity() {
const rgb = this._channels;
const lum = [];
for (const [i, element] of rgb.entries()) {
const chan = element / 255;
lum[i] = chan <= 0.039_28 ? chan / 12.92 : ((chan + 0.055) / 1.055) ** 2.4;
}
return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];
}
get isDark() {
return this.luminosity < 0.5;
}
get isLight() {
return !this.isDark;
}
get isNone(){
return !this._channels || !this._channels.length
}
toString(){
if(this.isNone){
return ''
}
return Number.isNaN(this._alpha)
? `rgb(${this._channels.map(x=>Math.round(x)).join(',')})`
:`rgba(${[this._channels,this._alpha].map(x=>Math.round(x)).join(',')})`
}
}