All files / src/components/u-table-view.vue Color.js

11.59% Statements 8/69
0% Branches 0/44
0% Functions 0/12
11.94% Lines 8/67

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152  7x   7x   7x       7x     7x     7x     7x                                                                                                                                                                                                                                                                   7x      
// rgb色值范围
const RGB_RANGE_REG = /^(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)$/;
// alpha范围
const ALPHA_RANGE_REG = /^(1.?0?|0.?[0-9]*)$/;
// 16进制
const HEX_REG = /^#([0-9a-fA-F]{3,8})$/;
 
// rgb
const RGB_REG
  = /^[rR][gG][Bb][\(]([\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)[\s]*,){2}[\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)[\s]*[\)]{1}$/;
// rgba
const RGBA_REG
  = /^[rR][gG][Bb][Aa][\(]([\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)[\s]*,){3}[\s]*(1.?0?|0.?[0-9]*)[\s]*[\)]{1}$/;
// hsl
const HSL_REG
  = /^[hH][Ss][Ll][\(]([\s]*(2[0-9][0-9]|360|3[0-5][0-9]|[01]?[0-9][0-9]?)[\s]*,)([\s]*((100|[0-9][0-9]?)%|0)[\s]*,)([\s]*((100|[0-9][0-9]?)%|0)[\s]*)[\)]$/;
// hsla
const HSLA_REG
  = /^[hH][Ss][Ll][Aa][\(]([\s]*(2[0-9][0-9]|360|3[0-5][0-9]|[01]?[0-9][0-9]?)[\s]*,)([\s]*((100|[0-9][0-9]?)%|0)[\s]*,){2}([\s]*(1.?0?|0.?[0-9]*)[\s]*)[\)]$/;
 
function isString(value) {
    return Object.prototype.toString.call(value) === '[object String]';
}
 
class Color {
    // r, g, b, a
    constructor(r = 0, g = 0, b = 0, a = 1) {
        if (
            !RGB_RANGE_REG.test(r)
        || !RGB_RANGE_REG.test(g)
        || !RGB_RANGE_REG.test(b)
        || !ALPHA_RANGE_REG.test(a)
        ) {
            throw new SyntaxError('Invalid params');
        }
        this.r = r;
        this.g = g;
        this.b = b;
        this.a = a;
    }
 
    toHEX() {
        let opacityStr = '';
        if (this.a !== 1) {
            opacityStr = Color.opacity2Hex(this.a);
        }
        return `#${this.r.toString(16).padStart(2, '0')}${this.g.toString(16).padStart(2, '0')}${this.b
            .toString(16)
            .padStart(2, '0')}${opacityStr}`;
    }
 
    // excel中的颜色格式为#AARRGGBB
    toARGBHEX() {
        let opacityStr = '';
        if (this.a !== 1) {
            opacityStr = Color.opacity2Hex(this.a);
        }
        return `#${opacityStr}${this.r.toString(16).padStart(2, '0')}${this.g.toString(16).padStart(2, '0')}${this.b
            .toString(16)
            .padStart(2, '0')}`;
    }
 
    static fromRGB(value) {
        if (!value) {
            return new Color();
        }
        // 不符合16进制规则
        if (!RGB_REG.test(value)) {
            throw new SyntaxError('Unexpected params of rgb function');
        }
        value = value.trim().slice(4, -1);
        const arr = value.split(',').map((num) => +num);
        return new Color(...arr);
    }
 
    static fromRGBA(value) {
        if (!value) {
            return new Color();
        }
        // 不符合16进制规则
        if (!RGBA_REG.test(value)) {
            throw new SyntaxError('Unexpected params of rgba function');
        }
        value = value.trim().slice(5, -1);
        const arr = value.split(',').map((num) => +num);
        return new Color(...arr);
    }
 
    /** @TODO: fromHSL */
    static parse(value) {
    // value不存在的情况下返回默认color实例
        if (!value) {
            return new Color();
        }
        if (!isString(value)) {
            throw new SyntaxError('Invalid: params should be a string');
        }
        // 颜色类型
        const colorType = Color.checkFormat(value);
        if (!colorType) {
            // 不属于16进制/rgb(a)/hsl(a)/内置颜色
            throw new SyntaxError('Invalid params');
        }
        return Color[`from${colorType}`](value);
    }
 
    static checkFormat(value) {
        if (!isString(value)) {
            throw new SyntaxError('Invalid: params should be a string');
        }
        value = value.trim();
        if (HEX_REG.test(value))
            return 'HEX';
        else if (RGB_REG.test(value))
            return 'RGB';
        else if (RGBA_REG.test(value))
            return 'RGBA';
        else if (HSL_REG.test(value))
            return 'HSL';
        else if (HSLA_REG.test(value))
            return 'HSLA';
    }
 
    static str2Color(value) {
        let color = null;
        try {
            color = Color.parse(value);
        } catch (e) {
            console.warn(e);
        }
        return color || new Color();
    }
 
    /**
   * 透明度转十六进制
   * @param {*} opacity
   * @returns
   */
    static opacity2Hex(opacity) {
        if (!ALPHA_RANGE_REG.test(opacity)) {
            throw new SyntaxError('Invalid params');
        }
        const num = Math.round(255 * opacity);
        // 十进制转十六进制,缺位补0
        return num.toString(16).padStart(2, '0');
    }
}
 
Color.TYPES = ['HEX', 'RGBA', 'RGB', 'HSLA', 'HSL', 'HSVA', 'HSV', 'NAME'];
 
export default Color;