Initial commit of akmon project
This commit is contained in:
680
uni_modules/lime-color/common/color.uts
Normal file
680
uni_modules/lime-color/common/color.uts
Normal file
@@ -0,0 +1,680 @@
|
||||
// @ts-nocheck
|
||||
import { numberInputToObject, rgbaToHex, rgbToHex, rgbToHsl, rgbToHsv } from './conversion';
|
||||
import { names } from './css-color-names';
|
||||
import { inputToRGB } from './format-input';
|
||||
import { HSL, HSLA, HSV, HSVA, HSBA, RGB, RGBA, RGBAString, LColorInfo, LColorFormats, LColorOptions, LColorInput } from '../utssdk/interface.uts';
|
||||
import { bound01, boundAlpha, clamp01, toBoolean, isNumber } from './util';
|
||||
|
||||
export class TinyColor {
|
||||
r : number;
|
||||
g : number;
|
||||
b : number;
|
||||
a : number;
|
||||
/** 用于创建 limeColor 实例的格式 */
|
||||
format ?: LColorFormats;
|
||||
/** 传递给构造函数以创建 limeColor 实例的输入 */
|
||||
originalInput : LColorInput;
|
||||
/** 颜色已被成功解析 */
|
||||
isValid : boolean;
|
||||
|
||||
gradientType ?: string;
|
||||
|
||||
/** rounded alpha */
|
||||
roundA : number;
|
||||
// #ifdef APP
|
||||
reversedNames : Map<string, string>;
|
||||
// #endif
|
||||
constructor(color : LColorInput = '', opts : LColorOptions = {} as LColorOptions) {
|
||||
let _color : any = color
|
||||
// if(color instanceof TinyColor){
|
||||
// return color as TinyColor
|
||||
// }
|
||||
if (isNumber(color)) {
|
||||
_color = numberInputToObject(color as number);
|
||||
}
|
||||
this.originalInput = _color;
|
||||
const rgb = inputToRGB(_color);
|
||||
this.r = rgb.r;
|
||||
this.g = rgb.g;
|
||||
this.b = rgb.b;
|
||||
this.a = rgb.a;
|
||||
this.roundA = Math.round(100 * this.a) / 100;
|
||||
this.format = opts.format ?? rgb.format;
|
||||
this.gradientType = opts.gradientType;
|
||||
|
||||
// 不要让范围在 [0,255] 中的值返回成 [0,1]。
|
||||
// 这里可能会失去一些精度,但可以解决原来
|
||||
// .5 被解释为总数的半数,而不是1的一半的问题
|
||||
// 如果本来应该是128,那么这个已经在 inputToRgb 中处理过了 if (this.r < 1) {
|
||||
if (this.r < 1) {
|
||||
this.r = Math.round(this.r);
|
||||
}
|
||||
|
||||
if (this.g < 1) {
|
||||
this.g = Math.round(this.g);
|
||||
}
|
||||
|
||||
if (this.b < 1) {
|
||||
this.b = Math.round(this.b);
|
||||
}
|
||||
|
||||
this.isValid = rgb.ok ?? false;
|
||||
|
||||
// #ifdef APP
|
||||
this.reversedNames = new Map<string, string>()
|
||||
names.forEach((value : string, key : string) => {
|
||||
this.reversedNames.set(value, key)
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
/**
|
||||
* 判断当前颜色是否为暗色。
|
||||
* @returns 一个布尔值,表示当前颜色是否为暗色。
|
||||
*/
|
||||
isDark() : boolean {
|
||||
return this.getBrightness() < 128;
|
||||
}
|
||||
/**
|
||||
* 判断当前颜色是否为亮色。
|
||||
* @returns 一个布尔值,表示当前颜色是否为亮色。
|
||||
*/
|
||||
isLight() : boolean {
|
||||
return !this.isDark();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算当前颜色的亮度值。
|
||||
* 亮度值是根据 RGB 颜色空间中的红、绿、蓝三个通道的值计算得出的,计算公式为:(r * 299 + g * 587 + b * 114) / 1000。
|
||||
* @returns 返回颜色的感知亮度,范围从0-255。
|
||||
*/
|
||||
getBrightness() : number {
|
||||
// http://www.w3.org/TR/AERT#color-contrast
|
||||
const rgb = this.toRgb();
|
||||
return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
|
||||
}
|
||||
/**
|
||||
* 计算当前颜色的相对亮度值。
|
||||
* 相对亮度值是根据 RGB 颜色空间中的红、绿、蓝三个通道的值计算得出的,计算公式为:0.2126 * R + 0.7152 * G + 0.0722 * B。
|
||||
* @returns 返回颜色的感知亮度,范围从0-1。
|
||||
*/
|
||||
getLuminance() : number {
|
||||
// http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
|
||||
const rgb = this.toRgb();
|
||||
let R : number;
|
||||
let G : number;
|
||||
let B : number;
|
||||
const RsRGB : number = rgb.r / 255;
|
||||
const GsRGB : number = rgb.g / 255;
|
||||
const BsRGB : number = rgb.b / 255;
|
||||
|
||||
if (RsRGB <= 0.03928) {
|
||||
R = RsRGB / 12.92;
|
||||
} else {
|
||||
// eslint-disable-next-line prefer-exponentiation-operator
|
||||
R = Math.pow((RsRGB + 0.055) / 1.055, 2.4);
|
||||
}
|
||||
|
||||
if (GsRGB <= 0.03928) {
|
||||
G = GsRGB / 12.92;
|
||||
} else {
|
||||
// eslint-disable-next-line prefer-exponentiation-operator
|
||||
G = Math.pow((GsRGB + 0.055) / 1.055, 2.4);
|
||||
}
|
||||
|
||||
if (BsRGB <= 0.03928) {
|
||||
B = BsRGB / 12.92;
|
||||
} else {
|
||||
// eslint-disable-next-line prefer-exponentiation-operator
|
||||
B = Math.pow((BsRGB + 0.055) / 1.055, 2.4);
|
||||
}
|
||||
|
||||
return 0.2126 * R + 0.7152 * G + 0.0722 * B;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前颜色的透明度值。
|
||||
* 透明度值的范围是 0 到 1,其中 0 表示完全透明,1 表示完全不透明。
|
||||
* @returns 一个数字,表示当前颜色的透明度值。
|
||||
*/
|
||||
getAlpha() : number {
|
||||
return this.a;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前颜色的透明度值。
|
||||
* @param alpha - 要设置的透明度值。透明度值的范围是 0 到 1,其中 0 表示完全透明,1 表示完全不透明。
|
||||
* @returns 一个 `TinyColor` 对象,表示设置透明度后的颜色。
|
||||
*/
|
||||
setAlpha(alpha ?: string) : TinyColor
|
||||
setAlpha(alpha ?: number) : TinyColor
|
||||
setAlpha(alpha ?: any) : TinyColor {
|
||||
this.a = boundAlpha(alpha);
|
||||
this.roundA = Math.round(100 * this.a) / 100;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* 判断当前颜色是否为单色。
|
||||
* 单色是指颜色的饱和度(S)为 0 的颜色,这些颜色只有明度(L)变化,没有颜色变化。
|
||||
* @returns 一个布尔值,表示当前颜色是否为单色。
|
||||
*/
|
||||
isMonochrome() : boolean {
|
||||
const { s } = this.toHsl();
|
||||
return s == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将当前颜色转换为 HSV(色相、饱和度、亮度)颜色空间。
|
||||
* @returns 一个对象,包含四个属性:`h`(色相)、`s`(饱和度)、`v`(亮度)和 `a`(透明度)。
|
||||
*/
|
||||
toHsv() : HSVA {
|
||||
const hsv = rgbToHsv(this.r, this.g, this.b);
|
||||
return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this.a } as HSVA;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将当前颜色转换为 HSV(色相、饱和度、亮度)颜色空间的字符串表示。
|
||||
* @returns 一个字符串,表示当前颜色的 HSV 或 HSVA 格式 hsva(xxx, xxx, xxx, xx)。
|
||||
*/
|
||||
toHsvString() : string {
|
||||
const hsv = rgbToHsv(this.r, this.g, this.b);
|
||||
const h = Math.round(hsv.h * 360);
|
||||
const s = Math.round(hsv.s * 100);
|
||||
const v = Math.round(hsv.v * 100);
|
||||
return this.a == 1 ? `hsv(${h}, ${s}%, ${v}%)` : `hsva(${h}, ${s}%, ${v}%, ${this.roundA})`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将当前颜色对象转换为HSBA颜色空间,即Hue(色相)、Saturation(饱和度)、Brightness(亮度)和Alpha(透明度
|
||||
* @returns {HSBA} 返回一个HSBA对象,表示当前颜色对象在HSBA颜色空间中的值
|
||||
*/
|
||||
toHsb() : HSBA {
|
||||
const hsv = rgbToHsv(this.r, this.g, this.b);
|
||||
return { h: hsv.h * 360, s: hsv.s, b: hsv.v, a: this.a } as HSBA;
|
||||
}
|
||||
/**
|
||||
* 将当前颜色对象转换为CSS风格的HSB或HSVA字符串
|
||||
* @returns {string} 返回一个CSS风格的HSB或HSVA字符串,表示当前颜色对象的颜色值
|
||||
*/
|
||||
toHsbString() : string {
|
||||
const hsb = this.toHsb();
|
||||
const h = Math.round(hsb.h);
|
||||
const s = Math.round(hsb.s * 100);
|
||||
const b = Math.round(hsb.b * 100);
|
||||
return this.a == 1
|
||||
? `hsb(${h}, ${s}%, ${b}%)`
|
||||
: `hsva(${h}, ${s}%, ${b}%, ${this.roundA})`;
|
||||
}
|
||||
/**
|
||||
* 将当前颜色转换为 HSL(色相、饱和度、明度)颜色空间。
|
||||
* @returns 一个对象,包含四个属性:`h`(色相)、`s`(饱和度)、`l`(明度)和 `a`(透明度)。
|
||||
*/
|
||||
toHsl() : HSLA {
|
||||
const hsl = rgbToHsl(this.r, this.g, this.b);
|
||||
return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this.a } as HSLA;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将当前颜色转换为 HSL(色相、饱和度、明度)颜色空间的字符串表示。
|
||||
* @returns 一个字符串,表示当前颜色的 HSL 或 HSLA 格式 hsla(xxx, xxx, xxx, xx)。
|
||||
*/
|
||||
toHslString() : string {
|
||||
const hsl = rgbToHsl(this.r, this.g, this.b);
|
||||
const h = Math.round(hsl.h * 360);
|
||||
const s = Math.round(hsl.s * 100);
|
||||
const l = Math.round(hsl.l * 100);
|
||||
return this.a == 1 ? `hsl(${h}, ${s}%, ${l}%)` : `hsla(${h}, ${s}%, ${l}%, ${this.roundA})`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将当前颜色转换为十六进制颜色表示。
|
||||
* @param allow3Char 是否允许返回简写的十六进制颜色表示(如果可能)。默认值为 `false`。
|
||||
* @returns 一个字符串,表示当前颜色的十六进制格式。
|
||||
*/
|
||||
toHex(allow3Char = false) : string {
|
||||
return rgbToHex(this.r, this.g, this.b, allow3Char);
|
||||
}
|
||||
/**
|
||||
* 将当前颜色转换为带有井号(`#`)前缀的十六进制颜色表示。
|
||||
* @param allow3Char 是否允许返回简写的十六进制颜色表示(如果可能)。默认值为 `false`。
|
||||
* @returns 一个字符串,表示当前颜色的带有井号前缀的十六进制格式。
|
||||
*/
|
||||
toHexString(allow3Char = false) : string {
|
||||
return '#' + this.toHex(allow3Char);
|
||||
}
|
||||
/**
|
||||
* 返回颜色的八位十六进制值.
|
||||
* @param allow4Char 如果可能的话,将十六进制值缩短为4个字符
|
||||
*/
|
||||
toHex8(allow4Char = false) : string {
|
||||
return rgbaToHex(this.r, this.g, this.b, this.a, allow4Char);
|
||||
}
|
||||
/**
|
||||
* 返回颜色的八位十六进制值,并且值前面带有#符号.
|
||||
* @param allow4Char 如果可能的话,将十六进制值缩短为4个字符
|
||||
*/
|
||||
toHex8String(allow4Char = false) : string {
|
||||
return '#' + this.toHex8(allow4Char);
|
||||
}
|
||||
/**
|
||||
* 根据颜色的透明度(Alpha值)返回较短的十六进制值,并且值前面带有#符号。
|
||||
* @param allowShortChar 如果可能的话,将十六进制值缩短至3个或4个字符
|
||||
*/
|
||||
toHexShortString(allowShortChar = false) : string {
|
||||
return this.a == 1 ? this.toHexString(allowShortChar) : this.toHex8String(allowShortChar);
|
||||
}
|
||||
/**
|
||||
* 将当前颜色转换为 RGB(红、绿、蓝)颜色空间的对象表示。
|
||||
* @returns 一个包含 `r`、`g`、`b` 和 `a` 属性的对象,表示当前颜色的 RGB 格式。
|
||||
*/
|
||||
toRgb() : RGBA {
|
||||
return {
|
||||
r: Math.round(this.r),
|
||||
g: Math.round(this.g),
|
||||
b: Math.round(this.b),
|
||||
a: this.a,
|
||||
} as RGBA;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将当前颜色对象转换为CSS风格的RGB或RGBA字符串
|
||||
* @returns {string} 返回一个CSS风格的RGB或RGBA字符串,表示当前颜色对象的颜色值
|
||||
*/
|
||||
toRgbString() : string {
|
||||
const r = Math.round(this.r);
|
||||
const g = Math.round(this.g);
|
||||
const b = Math.round(this.b);
|
||||
return this.a == 1 ? `rgb(${r}, ${g}, ${b})` : `rgba(${r}, ${g}, ${b}, ${this.roundA})`;
|
||||
}
|
||||
/**
|
||||
* 将当前颜色转换为百分比表示的 RGB(红、绿、蓝)颜色空间的对象表示。
|
||||
* @returns 一个包含 `r`、`g`、`b` 和 `a` 属性的对象,表示当前颜色的百分比表示的 RGB 格式。
|
||||
*/
|
||||
toPercentageRgb() : RGBAString {
|
||||
// 定义一个格式化函数,将颜色值转换为百分比表示
|
||||
const fmt = (x : number) : string => `${Math.round(bound01(x, 255) * 100)}%`;
|
||||
// 返回一个RGBA对象,其中颜色值已转换为百分比表示
|
||||
return {
|
||||
r: fmt(this.r),
|
||||
g: fmt(this.g),
|
||||
b: fmt(this.b),
|
||||
a: this.a,
|
||||
} as RGBAString;
|
||||
}
|
||||
/**
|
||||
* 将RGBA相对值插值为一个字符串,颜色值以百分比表示。
|
||||
*/
|
||||
toPercentageRgbString() : string {
|
||||
// 定义一个四舍五入函数,将颜色值转换为百分比表示的整数
|
||||
const rnd = (x : number) : number => Math.round(bound01(x, 255) * 100);
|
||||
// 根据alpha值返回不同的字符串表示
|
||||
return this.a == 1
|
||||
? `rgb(${rnd(this.r)}%, ${rnd(this.g)}%, ${rnd(this.b)}%)`
|
||||
: `rgba(${rnd(this.r)}%, ${rnd(this.g)}%, ${rnd(this.b)}%, ${this.roundA})`;
|
||||
}
|
||||
/**
|
||||
* 返回这个颜色的'真实'名称,不存在返回null
|
||||
*/
|
||||
toName() : string | null {
|
||||
if (this.a == 0) {
|
||||
return 'transparent';
|
||||
}
|
||||
|
||||
if (this.a < 1) {
|
||||
return null;
|
||||
}
|
||||
const hex = this.toHexString()//'#' + rgbToHex(this.r, this.g, this.b, false);
|
||||
|
||||
// #ifndef APP
|
||||
const _names = Array.from(names.entries())
|
||||
for (let [key, value] of _names) {
|
||||
if (hex == value) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
// #endif
|
||||
|
||||
// #ifdef APP
|
||||
return this.reversedNames.get(hex)
|
||||
// #endif
|
||||
}
|
||||
/**
|
||||
* 将颜色转换为字符串表示。
|
||||
*
|
||||
* @param format - 用于显示字符串表示的格式。
|
||||
*/
|
||||
// toString<T extends 'name'>(format : T) : string;
|
||||
// toString<T extends LColorFormats>(format ?: T) : string;
|
||||
|
||||
// #ifdef APP-ANDROID
|
||||
override toString() : string {
|
||||
return this.toString(null)
|
||||
}
|
||||
// #endif
|
||||
toString(format ?: LColorFormats) : string {
|
||||
const formatSet = toBoolean(format);
|
||||
let _format = format ?? this.format;
|
||||
|
||||
let formattedString : string | null = null;
|
||||
const hasAlpha = this.a < 1 && this.a >= 0;
|
||||
const needsAlphaFormat = !formatSet && hasAlpha && (_format != null && _format.startsWith('hex') || _format == 'name');
|
||||
|
||||
if (needsAlphaFormat) {
|
||||
// 特殊情况:透明度,所有其他非透明度格式都会在有透明度时返回rgba。
|
||||
// 当透明度为0时,返回"transparent"。
|
||||
if (_format == 'name' && this.a == 0) {
|
||||
return this.toName() ?? 'transparent';
|
||||
}
|
||||
return this.toRgbString();
|
||||
}
|
||||
|
||||
if (_format == 'rgb') {
|
||||
formattedString = this.toRgbString();
|
||||
}
|
||||
|
||||
if (_format == 'prgb') {
|
||||
formattedString = this.toPercentageRgbString();
|
||||
}
|
||||
|
||||
if (_format == 'hex' || _format == 'hex6') {
|
||||
formattedString = this.toHexString();
|
||||
}
|
||||
|
||||
if (_format == 'hex3') {
|
||||
formattedString = this.toHexString(true);
|
||||
}
|
||||
|
||||
if (_format == 'hex4') {
|
||||
formattedString = this.toHex8String(true);
|
||||
}
|
||||
|
||||
if (_format == 'hex8') {
|
||||
formattedString = this.toHex8String();
|
||||
}
|
||||
|
||||
if (_format == 'name') {
|
||||
formattedString = this.toName();
|
||||
}
|
||||
|
||||
if (_format == 'hsl') {
|
||||
formattedString = this.toHslString();
|
||||
}
|
||||
|
||||
if (_format == 'hsv') {
|
||||
formattedString = this.toHsvString();
|
||||
}
|
||||
if (_format == 'hsb') {
|
||||
formattedString = this.toHsbString();
|
||||
}
|
||||
return formattedString ?? this.toHexString();
|
||||
}
|
||||
toNumber() : number {
|
||||
return (Math.round(this.r) << 16) + (Math.round(this.g) << 8) + Math.round(this.b);
|
||||
}
|
||||
clone() : TinyColor {
|
||||
return new TinyColor(this.toString());
|
||||
}
|
||||
/**
|
||||
* 将颜色变浅指定的量。提供100将始终返回白色。
|
||||
* @param amount - 有效值介于1-100之间
|
||||
*/
|
||||
lighten(amount = 10) : TinyColor {
|
||||
const hsl = this.toHsl();
|
||||
hsl.l += amount / 100;
|
||||
hsl.l = clamp01(hsl.l);
|
||||
return new TinyColor(hsl, { format: this.format } as LColorOptions);
|
||||
}
|
||||
/**
|
||||
* 将颜色变亮一定的量,范围从0到100。
|
||||
* @param amount - 有效值在1-100之间
|
||||
*/
|
||||
brighten(amount = 10) : TinyColor {
|
||||
const rgb = this.toRgb();
|
||||
rgb.r = Math.max(0, Math.min(255, rgb.r - Math.round(255 * -(amount / 100))));
|
||||
rgb.g = Math.max(0, Math.min(255, rgb.g - Math.round(255 * -(amount / 100))));
|
||||
rgb.b = Math.max(0, Math.min(255, rgb.b - Math.round(255 * -(amount / 100))));
|
||||
return new TinyColor(rgb, { format: this.format } as LColorOptions);
|
||||
}
|
||||
/**
|
||||
* 将颜色变暗一定的量,范围从0到100。
|
||||
* 提供100将始终返回黑色。
|
||||
* @param amount - 有效值在1-100之间
|
||||
*/
|
||||
darken(amount = 10) : TinyColor {
|
||||
const hsl = this.toHsl();
|
||||
hsl.l -= amount / 100;
|
||||
hsl.l = clamp01(hsl.l);
|
||||
return new TinyColor(hsl, { format: this.format } as LColorOptions);
|
||||
}
|
||||
/**
|
||||
* 将颜色与纯白色混合,范围从0到100。
|
||||
* 提供0将什么都不做,提供100将始终返回白色。
|
||||
* @param amount - 有效值在1-100之间
|
||||
*/
|
||||
tint(amount = 10) : TinyColor {
|
||||
return this.mix('white', amount);
|
||||
}
|
||||
/**
|
||||
* 将颜色与纯黑色混合,范围从0到100。
|
||||
* 提供0将什么都不做,提供100将始终返回黑色。
|
||||
* @param amount - 有效值在1-100之间
|
||||
*/
|
||||
shade(amount = 10) : TinyColor {
|
||||
return this.mix('black', amount);
|
||||
}
|
||||
/**
|
||||
* 将颜色的饱和度降低一定的量,范围从0到100。
|
||||
* 提供100与调用greyscale相同
|
||||
* @param amount - 有效值在1-100之间
|
||||
*/
|
||||
desaturate(amount = 10) : TinyColor {
|
||||
const hsl = this.toHsl();
|
||||
hsl.s -= amount / 100;
|
||||
hsl.s = clamp01(hsl.s);
|
||||
return new TinyColor(hsl, { format: this.format } as LColorOptions);
|
||||
}
|
||||
/**
|
||||
* 将颜色饱和度提高一定数量,范围从 0 到 100。
|
||||
* @param amount - 有效值介于 1 到 100 之间。
|
||||
*/
|
||||
saturate(amount = 10) : TinyColor {
|
||||
const hsl = this.toHsl();
|
||||
hsl.s += amount / 100;
|
||||
hsl.s = clamp01(hsl.s);
|
||||
return new TinyColor(hsl, { format: this.format } as LColorOptions);
|
||||
}
|
||||
/**
|
||||
* 将颜色完全去饱和为灰度。
|
||||
* 等同于调用 `desaturate(100)`。
|
||||
*/
|
||||
greyscale() : TinyColor {
|
||||
return this.desaturate(100);
|
||||
}
|
||||
/**
|
||||
* spin 方法接收一个正数或负数作为参数,表示色相的变化量,变化范围在 [-360, 360] 之间。
|
||||
* 如果提供的值超出此范围,它将被限制在此范围内。
|
||||
*/
|
||||
spin(amount : number) : TinyColor {
|
||||
const hsl = this.toHsl();
|
||||
const hue = (hsl.h + amount) % 360;
|
||||
hsl.h = hue < 0 ? 360 + hue : hue;
|
||||
return new TinyColor(hsl, { format: this.format } as LColorOptions);
|
||||
}
|
||||
/**
|
||||
* 将当前颜色与另一种颜色按给定的比例混合,范围从0到100。
|
||||
* 0表示不混合(返回当前颜色)
|
||||
*/
|
||||
mix(color : LColorInput, amount = 50) : TinyColor {
|
||||
const rgb1 = this.toRgb();
|
||||
const rgb2 = new TinyColor(color).toRgb();
|
||||
|
||||
const p = amount / 100;
|
||||
const rgba = {
|
||||
r: (rgb2.r - rgb1.r) * p + rgb1.r,
|
||||
g: (rgb2.g - rgb1.g) * p + rgb1.g,
|
||||
b: (rgb2.b - rgb1.b) * p + rgb1.b,
|
||||
a: (rgb2.a - rgb1.a) * p + rgb1.a,
|
||||
};
|
||||
|
||||
return new TinyColor(rgba, { format: this.format } as LColorOptions);
|
||||
}
|
||||
/**
|
||||
* 生成一组与当前颜色相似的颜色。
|
||||
* 这些颜色在色相环上是相邻的,形成一个类似于彩虹的颜色序列。
|
||||
* @param results - 要生成的相似颜色的数量,默认值为 6。
|
||||
* @param slices - 将色相环划分为多少个部分,默认值为 30。
|
||||
* @returns 一个包含当前颜色及其相似颜色的 TinyColor 对象数组。
|
||||
*/
|
||||
analogous(results = 6, slices = 30) : TinyColor[] {
|
||||
const hsl = this.toHsl();
|
||||
const part = 360 / slices;
|
||||
const ret : TinyColor[] = [this];
|
||||
let _results = results
|
||||
// for (hsl.h = (hsl.h - ((part * results) >> 1) + 720) % 360; --results;) {
|
||||
// hsl.h = (hsl.h + part) % 360;
|
||||
// ret.push(new TinyColor(hsl));
|
||||
// }
|
||||
hsl.h = (hsl.h - ((part * _results) >> 1) + 720) % 360;
|
||||
while (_results > 0) {
|
||||
hsl.h = (hsl.h + part) % 360;
|
||||
ret.push(new TinyColor(hsl));
|
||||
_results--;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* 计算当前颜色的补色。
|
||||
* 补色是指在色相环上相对位置的颜色,它们的色相差为 180°。
|
||||
* taken from https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js
|
||||
* @returns 一个 TinyColor 对象,表示当前颜色的补色。
|
||||
*/
|
||||
complement() : TinyColor {
|
||||
const hsl = this.toHsl();
|
||||
hsl.h = (hsl.h + 180) % 360;
|
||||
return new TinyColor(hsl, { format: this.format } as LColorOptions);
|
||||
}
|
||||
/**
|
||||
* 生成一组与当前颜色具有相同色相和饱和度的颜色。
|
||||
* 这些颜色的亮度值不同,形成一个单色调的颜色序列。
|
||||
* @param results - 要生成的单色调颜色的数量,默认值为 6。
|
||||
* @returns 一个包含当前颜色及其单色调颜色的 TinyColor 对象数组。
|
||||
*/
|
||||
monochromatic(results = 6) : TinyColor[] {
|
||||
const hsv = this.toHsv();
|
||||
const { h } = hsv;
|
||||
const { s } = hsv;
|
||||
let { v } = hsv;
|
||||
const res : TinyColor[] = [];
|
||||
const modification = 1 / results;
|
||||
let _results = results
|
||||
// while (results--) {
|
||||
// res.push(new TinyColor({ h, s, v }));
|
||||
// v = (v + modification) % 1;
|
||||
// }
|
||||
while (_results > 0) {
|
||||
res.push(new TinyColor({ h, s, v }));
|
||||
v = (v + modification) % 1;
|
||||
_results--
|
||||
}
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* 生成当前颜色的分裂补色。
|
||||
* 分裂补色是指在色相环上位于当前颜色的两侧的颜色,它们的色相差为 180°。
|
||||
* @returns 一个包含当前颜色及其分裂补色的 TinyColor 对象数组。
|
||||
*/
|
||||
splitcomplement() : TinyColor[] {
|
||||
const hsl = this.toHsl();
|
||||
const { h } = hsl;
|
||||
return [
|
||||
this,
|
||||
new TinyColor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l }),
|
||||
new TinyColor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l }),
|
||||
] as TinyColor[];
|
||||
}
|
||||
/**
|
||||
* 计算当前颜色在给定背景颜色上的显示效果。
|
||||
* @param background - 背景颜色,可以是任何 LColorInput 类型的值。
|
||||
* @returns 一个 TinyColor 对象,表示当前颜色在给定背景颜色上的显示效果。
|
||||
*/
|
||||
onBackground(background : LColorInput) : TinyColor {
|
||||
const fg = this.toRgb();
|
||||
const bg = new TinyColor(background).toRgb();
|
||||
const alpha = fg.a + bg.a * (1 - fg.a);
|
||||
|
||||
return new TinyColor({
|
||||
r: (fg.r * fg.a + bg.r * bg.a * (1 - fg.a)) / alpha,
|
||||
g: (fg.g * fg.a + bg.g * bg.a * (1 - fg.a)) / alpha,
|
||||
b: (fg.b * fg.a + bg.b * bg.a * (1 - fg.a)) / alpha,
|
||||
a: alpha,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 生成当前颜色的三色调。
|
||||
* 三色调是指在色相环上位于当前颜色的两侧的颜色,它们的色相差为 120°。
|
||||
* 这是 `polyad(3)` 方法的别名。
|
||||
* @returns 一个包含当前颜色及其三色调颜色的 TinyColor 对象数组。
|
||||
*/
|
||||
triad() : TinyColor[] {
|
||||
return this.polyad(3);
|
||||
}
|
||||
/**
|
||||
* 生成当前颜色的四色调。
|
||||
* 四色调是指在色相环上位于当前颜色的两侧的颜色,它们的色相差为 90°。
|
||||
* 这是 `polyad(4)` 方法的别名。
|
||||
* @returns 一个包含当前颜色及其四色调颜色的 TinyColor 对象数组。
|
||||
*/
|
||||
tetrad() : TinyColor[] {
|
||||
return this.polyad(4);
|
||||
}
|
||||
/**
|
||||
* 生成当前颜色的 n 色调。
|
||||
* n 色调是指在色相环上位于当前颜色的两侧的颜色,它们的色相差为 360° / n。
|
||||
* Get polyad colors, like (for 1, 2, 3, 4, 5, 6, 7, 8, etc...)
|
||||
* monad, dyad, triad, tetrad, pentad, hexad, heptad, octad, etc...
|
||||
* @param n - 一个整数,表示要生成的色调数量。
|
||||
* @returns 一个包含当前颜色及其 n 色调颜色的 TinyColor 对象数组。
|
||||
*/
|
||||
polyad(n : number) : TinyColor[] {
|
||||
const hsl = this.toHsl();
|
||||
const { h } = hsl;
|
||||
|
||||
const result : TinyColor[] = [this];
|
||||
const increment = 360 / n;
|
||||
for (let i = 1; i < n; i++) {
|
||||
result.push(new TinyColor({ h: (h + i * increment) % 360, s: hsl.s, l: hsl.l }));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* 比较当前颜色与给定颜色是否相等。
|
||||
* @param color - 一个 LColorInput 类型的值,表示要比较的颜色。
|
||||
* @returns 一个布尔值,表示当前颜色与给定颜色是否相等。
|
||||
*/
|
||||
|
||||
// #ifndef APP-ANDROID
|
||||
equals(other ?: LColorInput) : boolean {
|
||||
if (other == null) {
|
||||
return false
|
||||
} else if (other instanceof TinyColor) {
|
||||
return this.toRgbString() == (other as TinyColor).toRgbString()
|
||||
}
|
||||
return this.toRgbString() == new TinyColor(other).toRgbString();
|
||||
}
|
||||
// #endif
|
||||
// #ifdef APP-ANDROID
|
||||
override equals(other ?: LColorInput) : boolean {
|
||||
if (other == null) {
|
||||
return false
|
||||
} else if (other instanceof TinyColor) {
|
||||
return this.toRgbString() == (other as TinyColor).toRgbString()
|
||||
}
|
||||
return this.toRgbString() == new TinyColor(other).toRgbString();
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
|
||||
export function tinyColor(color : LColorInput = '', opts : LColorOptions = {} as LColorOptions) : TinyColor {
|
||||
return new TinyColor(color, opts);
|
||||
}
|
||||
306
uni_modules/lime-color/common/conversion.uts
Normal file
306
uni_modules/lime-color/common/conversion.uts
Normal file
@@ -0,0 +1,306 @@
|
||||
import { RGB,HSL,HSV } from '../utssdk/interface.uts';
|
||||
import { bound01, pad2 } from './util';
|
||||
|
||||
|
||||
/**
|
||||
* Handle bounds / percentage checking to conform to CSS color spec
|
||||
* 处理边界/百分比检查以符合 CSS 颜色规范
|
||||
* <http://www.w3.org/TR/css3-color/>
|
||||
* *Assumes:* r, g, b in [0, 255] or [0, 1]
|
||||
* *Returns:* { r, g, b } in [0, 255]
|
||||
*/
|
||||
function rgbToRgb(r: string, g: string, b: string):RGB;
|
||||
function rgbToRgb(r: number, g: string, b: string):RGB;
|
||||
function rgbToRgb(r: number, g: number, b: string):RGB;
|
||||
function rgbToRgb(r: number, g: number, b: number):RGB;
|
||||
function rgbToRgb(r: any, g: any, b: any) : RGB {
|
||||
return {
|
||||
r: bound01(r, 255) * 255,
|
||||
g: bound01(g, 255) * 255,
|
||||
b: bound01(b, 255) * 255,
|
||||
} as RGB;
|
||||
}
|
||||
export {
|
||||
rgbToRgb
|
||||
}
|
||||
/**
|
||||
* Converts an RGB color value to HSL.
|
||||
* 将 RGB 颜色值转换为 HSL。
|
||||
* *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
|
||||
* *Returns:* { h, s, l } in [0,1]
|
||||
*/
|
||||
function rgbToHsl(r: string, g: string, b: string):HSL;
|
||||
function rgbToHsl(r: number, g: string, b: string):HSL;
|
||||
function rgbToHsl(r: number, g: number, b: string):HSL;
|
||||
function rgbToHsl(r: number, g: number, b: number):HSL;
|
||||
function rgbToHsl(r : any, g : any, b : any) : HSL {
|
||||
r = bound01(r, 255);
|
||||
g = bound01(g, 255);
|
||||
b = bound01(b, 255);
|
||||
|
||||
const max = Math.max(r, g, b);
|
||||
const min = Math.min(r, g, b);
|
||||
let h = 0;
|
||||
let s:number// = 0;
|
||||
const l = (max + min) / 2;
|
||||
|
||||
if (max == min) {
|
||||
s = 0;
|
||||
h = 0; // achromatic
|
||||
} else {
|
||||
const d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
switch (max) {
|
||||
case r:
|
||||
h = (g - b) / d + (g < b ? 6 : 0);
|
||||
break;
|
||||
case g:
|
||||
h = (b - r) / d + 2;
|
||||
break;
|
||||
case b:
|
||||
h = (r - g) / d + 4;
|
||||
break;
|
||||
default:
|
||||
console.log('h')
|
||||
break;
|
||||
}
|
||||
|
||||
h /= 6;
|
||||
}
|
||||
|
||||
return { h, s, l } as HSL;
|
||||
}
|
||||
|
||||
export {
|
||||
rgbToHsl
|
||||
}
|
||||
|
||||
export function hue2rgb(p : number, q : number, t : number) : number {
|
||||
let _t = t
|
||||
if (_t < 0) {
|
||||
_t += 1;
|
||||
}
|
||||
|
||||
if (_t > 1) {
|
||||
_t -= 1;
|
||||
}
|
||||
|
||||
if (_t < 1 / 6) {
|
||||
return p + (q - p) * (6 * _t);
|
||||
}
|
||||
|
||||
if (_t < 1 / 2) {
|
||||
return q;
|
||||
}
|
||||
|
||||
if (_t < 2 / 3) {
|
||||
return p + (q - p) * (2 / 3 - _t) * 6;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an HSL color value to RGB.
|
||||
* 将 HSL 颜色值转换为 RGB。
|
||||
* *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
|
||||
* *Returns:* { r, g, b } in the set [0, 255]
|
||||
*/
|
||||
function hslToRgb(h : string,s : string,l : string) : RGB
|
||||
function hslToRgb(h : number,s : string,l : string) : RGB
|
||||
function hslToRgb(h : number,s : number,l : string) : RGB
|
||||
function hslToRgb(h : number,s : number,l : number) : RGB
|
||||
function hslToRgb(h : any,s : any,l : any) : RGB {
|
||||
let r : number;
|
||||
let g : number;
|
||||
let b : number;
|
||||
h = bound01(h, 360);
|
||||
s = bound01(s, 100);
|
||||
l = bound01(l, 100);
|
||||
|
||||
if (s == 0) {
|
||||
// achromatic
|
||||
g = l;
|
||||
b = l;
|
||||
r = l;
|
||||
} else {
|
||||
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
const p = 2 * l - q;
|
||||
r = hue2rgb(p, q, h + 1 / 3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1 / 3);
|
||||
}
|
||||
|
||||
return { r: r * 255, g: g * 255, b: b * 255 } as RGB;
|
||||
}
|
||||
export {
|
||||
hslToRgb
|
||||
}
|
||||
/**
|
||||
* Converts an RGB color value to HSV
|
||||
* 将RGB颜色值转换为HSV颜色值
|
||||
* *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
|
||||
* *Returns:* { h, s, v } in [0,1]
|
||||
*/
|
||||
export function rgbToHsv(r : number, g : number, b : number) : HSV {
|
||||
r = bound01(r, 255);
|
||||
g = bound01(g, 255);
|
||||
b = bound01(b, 255);
|
||||
|
||||
const max = Math.max(r, g, b);
|
||||
const min = Math.min(r, g, b);
|
||||
let h = 0;
|
||||
const v = max;
|
||||
const d = max - min;
|
||||
const s = max == 0 ? 0 : d / max;
|
||||
|
||||
if (max == min) {
|
||||
h = 0; // achromatic
|
||||
} else {
|
||||
switch (max) {
|
||||
case r:
|
||||
h = (g - b) / d + (g < b ? 6 : 0);
|
||||
break;
|
||||
case g:
|
||||
h = (b - r) / d + 2;
|
||||
break;
|
||||
case b:
|
||||
h = (r - g) / d + 4;
|
||||
break;
|
||||
default:
|
||||
console.log('1')
|
||||
break;
|
||||
}
|
||||
|
||||
h /= 6;
|
||||
}
|
||||
|
||||
return { h, s, v } as HSV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an HSV color value to RGB.
|
||||
* 将HSV颜色值转换为RGB。
|
||||
* *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
|
||||
* *Returns:* { r, g, b } in the set [0, 255]
|
||||
*/
|
||||
function hsvToRgb( h : string, s : string, v : string) : RGB
|
||||
function hsvToRgb( h : number, s : string, v : string) : RGB
|
||||
function hsvToRgb( h : number, s : number, v : string) : RGB
|
||||
function hsvToRgb( h : number, s : number, v : number) : RGB
|
||||
function hsvToRgb( h : any, s : any, v : any) : RGB {
|
||||
h = bound01(h, 360) * 6;
|
||||
s = bound01(s, 100);
|
||||
v = bound01(v, 100);
|
||||
|
||||
const i = Math.floor(h);
|
||||
const f = h - i;
|
||||
const p = v * (1 - s);
|
||||
const q = v * (1 - f * s);
|
||||
const t = v * (1 - (1 - f) * s);
|
||||
const mod = i % 6;
|
||||
const r = [v, q, p, p, t, v][mod];
|
||||
const g = [t, v, v, q, p, p][mod];
|
||||
const b = [p, p, t, v, v, q][mod];
|
||||
|
||||
return { r: r * 255, g: g * 255, b: b * 255 } as RGB;
|
||||
}
|
||||
export {
|
||||
hsvToRgb
|
||||
}
|
||||
/**
|
||||
* Converts an RGB color to hex
|
||||
* 将RGB颜色转换为十六进制。
|
||||
* Assumes r, g, and b are contained in the set [0, 255]
|
||||
* Returns a 3 or 6 character hex
|
||||
*/
|
||||
export function rgbToHex(r : number, g : number, b : number, allow3Char : boolean = false) : string {
|
||||
const hex = [
|
||||
pad2(Math.round(r).toString(16)),
|
||||
pad2(Math.round(g).toString(16)),
|
||||
pad2(Math.round(b).toString(16)),
|
||||
];
|
||||
|
||||
// Return a 3 character hex if possible
|
||||
if (
|
||||
allow3Char &&
|
||||
hex[0].startsWith(hex[0].charAt(1)) &&
|
||||
hex[1].startsWith(hex[1].charAt(1)) &&
|
||||
hex[2].startsWith(hex[2].charAt(1))
|
||||
) {
|
||||
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
|
||||
}
|
||||
|
||||
return hex.join('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an RGBA color plus alpha transparency to hex
|
||||
* 将带有透明度的RGBA颜色转换为十六进制。
|
||||
* Assumes r, g, b are contained in the set [0, 255] and
|
||||
* a in [0, 1]. Returns a 4 or 8 character rgba hex
|
||||
*/
|
||||
// eslint-disable-next-line max-params
|
||||
export function rgbaToHex(r : number, g : number, b : number, a : number, allow4Char : boolean = false) : string {
|
||||
const hex = [
|
||||
pad2(Math.round(r).toString(16)),
|
||||
pad2(Math.round(g).toString(16)),
|
||||
pad2(Math.round(b).toString(16)),
|
||||
pad2(convertDecimalToHex(a)),
|
||||
];
|
||||
|
||||
// Return a 4 character hex if possible
|
||||
if (
|
||||
allow4Char &&
|
||||
hex[0].startsWith(hex[0].charAt(1)) &&
|
||||
hex[1].startsWith(hex[1].charAt(1)) &&
|
||||
hex[2].startsWith(hex[2].charAt(1)) &&
|
||||
hex[3].startsWith(hex[3].charAt(1))
|
||||
) {
|
||||
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0);
|
||||
}
|
||||
|
||||
return hex.join('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an RGBA color to an ARGB Hex8 string
|
||||
* 将RGBA颜色转换为ARGB十六进制字符串。
|
||||
* Rarely used, but required for "toFilter()"
|
||||
*/
|
||||
export function rgbaToArgbHex(r : number, g : number, b : number, a : number) : string {
|
||||
const hex = [
|
||||
pad2(convertDecimalToHex(a)),
|
||||
pad2(Math.round(r).toString(16)),
|
||||
pad2(Math.round(g).toString(16)),
|
||||
pad2(Math.round(b).toString(16)),
|
||||
];
|
||||
|
||||
return hex.join('');
|
||||
}
|
||||
|
||||
/** Converts a decimal to a hex value */
|
||||
/** 将十进制转换为十六进制值。 */
|
||||
function convertDecimalToHex(d : number) : string
|
||||
function convertDecimalToHex(d : string) : string
|
||||
function convertDecimalToHex(d : any) : string {
|
||||
return Math.round(parseFloat(`${d}`) * 255).toString(16);
|
||||
}
|
||||
export {convertDecimalToHex}
|
||||
/** Converts a hex value to a decimal */
|
||||
export function convertHexToDecimal(h : string) : number {
|
||||
return parseIntFromHex(h) / 255;
|
||||
}
|
||||
|
||||
/** Parse a base-16 hex value into a base-10 integer */
|
||||
export function parseIntFromHex(val : string) : number {
|
||||
return parseInt(val, 16);
|
||||
}
|
||||
|
||||
export function numberInputToObject(color : number) : RGB {
|
||||
return {
|
||||
r: color >> 16,
|
||||
g: (color & 0xff00) >> 8,
|
||||
b: color & 0xff,
|
||||
} as RGB;
|
||||
}
|
||||
155
uni_modules/lime-color/common/css-color-names.uts
Normal file
155
uni_modules/lime-color/common/css-color-names.uts
Normal file
@@ -0,0 +1,155 @@
|
||||
// @ts-nocheck
|
||||
// https://github.com/bahamas10/css-color-names/blob/master/css-color-names.json
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
export const names: Map<string, string> = new Map<string, string>([
|
||||
['aliceblue', '#f0f8ff'],
|
||||
['antiquewhite', '#faebd7'],
|
||||
['aqua', '#00ffff'],
|
||||
['aquamarine', '#7fffd4'],
|
||||
['azure', '#f0ffff'],
|
||||
['beige', '#f5f5dc'],
|
||||
['bisque', '#ffe4c4'],
|
||||
['black', '#000000'],
|
||||
['blanchedalmond', '#ffebcd'],
|
||||
['blue', '#0000ff'],
|
||||
['blueviolet', '#8a2be2'],
|
||||
['brown', '#a52a2a'],
|
||||
['burlywood', '#deb887'],
|
||||
['cadetblue', '#5f9ea0'],
|
||||
['chartreuse', '#7fff00'],
|
||||
['chocolate', '#d2691e'],
|
||||
['coral', '#ff7f50'],
|
||||
['cornflowerblue', '#6495ed'],
|
||||
['cornsilk', '#fff8dc'],
|
||||
['crimson', '#dc143c'],
|
||||
['cyan', '#00ffff'],
|
||||
['darkblue', '#00008b'],
|
||||
['darkcyan', '#008b8b'],
|
||||
['darkgoldenrod', '#b8860b'],
|
||||
['darkgray', '#a9a9a9'],
|
||||
['darkgreen', '#006400'],
|
||||
['darkgrey', '#a9a9a9'],
|
||||
['darkkhaki', '#bdb76b'],
|
||||
['darkmagenta', '#8b008b'],
|
||||
['darkolivegreen', '#556b2f'],
|
||||
['darkorange', '#ff8c00'],
|
||||
['darkorchid', '#9932cc'],
|
||||
['darkred', '#8b0000'],
|
||||
['darksalmon', '#e9967a'],
|
||||
['darkseagreen', '#8fbc8f'],
|
||||
['darkslateblue', '#483d8b'],
|
||||
['darkslategray', '#2f4f4f'],
|
||||
['darkslategrey', '#2f4f4f'],
|
||||
['darkturquoise', '#00ced1'],
|
||||
['darkviolet', '#9400d3'],
|
||||
['deeppink', '#ff1493'],
|
||||
['deepskyblue', '#00bfff'],
|
||||
['dimgray', '#696969'],
|
||||
['dimgrey', '#696969'],
|
||||
['dodgerblue', '#1e90ff'],
|
||||
['firebrick', '#b22222'],
|
||||
['floralwhite', '#fffaf0'],
|
||||
['forestgreen', '#228b22'],
|
||||
['fuchsia', '#ff00ff'],
|
||||
['gainsboro', '#dcdcdc'],
|
||||
['ghostwhite', '#f8f8ff'],
|
||||
['goldenrod', '#daa520'],
|
||||
['gold', '#ffd700'],
|
||||
['gray', '#808080'],
|
||||
['green', '#008000'],
|
||||
['greenyellow', '#adff2f'],
|
||||
['grey', '#808080'],
|
||||
['honeydew', '#f0fff0'],
|
||||
['hotpink', '#ff69b4'],
|
||||
['indianred', '#cd5c5c'],
|
||||
['indigo', '#4b0082'],
|
||||
['ivory', '#fffff0'],
|
||||
['khaki', '#f0e68c'],
|
||||
['lavenderblush', '#fff0f5'],
|
||||
['lavender', '#e6e6fa'],
|
||||
['lawngreen', '#7cfc00'],
|
||||
['lemonchiffon', '#fffacd'],
|
||||
['lightblue', '#add8e6'],
|
||||
['lightcoral', '#f08080'],
|
||||
['lightcyan', '#e0ffff'],
|
||||
['lightgoldenrodyellow', '#fafad2'],
|
||||
['lightgray', '#d3d3d3'],
|
||||
['lightgreen', '#90ee90'],
|
||||
['lightgrey', '#d3d3d3'],
|
||||
['lightpink', '#ffb6c1'],
|
||||
['lightsalmon', '#ffa07a'],
|
||||
['lightseagreen', '#20b2aa'],
|
||||
['lightskyblue', '#87cefa'],
|
||||
['lightslategray', '#778899'],
|
||||
['lightslategrey', '#778899'],
|
||||
['lightsteelblue', '#b0c4de'],
|
||||
['lightyellow', '#ffffe0'],
|
||||
['lime', '#00ff00'],
|
||||
['limegreen', '#32cd32'],
|
||||
['linen', '#faf0e6'],
|
||||
['magenta', '#ff00ff'],
|
||||
['maroon', '#800000'],
|
||||
['mediumaquamarine', '#66cdaa'],
|
||||
['mediumblue', '#0000cd'],
|
||||
['mediumorchid', '#ba55d3'],
|
||||
['mediumpurple', '#9370db'],
|
||||
['mediumseagreen', '#3cb371'],
|
||||
['mediumslateblue', '#7b68ee'],
|
||||
['mediumspringgreen', '#00fa9a'],
|
||||
['mediumturquoise', '#48d1cc'],
|
||||
['mediumvioletred', '#c71585'],
|
||||
['midnightblue', '#191970'],
|
||||
['mintcream', '#f5fffa'],
|
||||
['mistyrose', '#ffe4e1'],
|
||||
['moccasin', '#ffe4b5'],
|
||||
['navajowhite', '#ffdead'],
|
||||
['navy', '#000080'],
|
||||
['oldlace', '#fdf5e6'],
|
||||
['olive', '#808000'],
|
||||
['olivedrab', '#6b8e23'],
|
||||
['orange', '#ffa500'],
|
||||
['orangered', '#ff4500'],
|
||||
['orchid', '#da70d6'],
|
||||
['palegoldenrod', '#eee8aa'],
|
||||
['palegreen', '#98fb98'],
|
||||
['paleturquoise', '#afeeee'],
|
||||
['palevioletred', '#db7093'],
|
||||
['papayawhip', '#ffefd5'],
|
||||
['peachpuff', '#ffdab9'],
|
||||
['peru', '#cd853f'],
|
||||
['pink', '#ffc0cb'],
|
||||
['plum', '#dda0dd'],
|
||||
['powderblue', '#b0e0e6'],
|
||||
['purple', '#800080'],
|
||||
['rebeccapurple', '#663399'],
|
||||
['red', '#ff0000'],
|
||||
['rosybrown', '#bc8f8f'],
|
||||
['royalblue', '#4169e1'],
|
||||
['saddlebrown', '#8b4513'],
|
||||
['salmon', '#fa8072'],
|
||||
['sandybrown', '#f4a460'],
|
||||
['seagreen', '#2e8b57'],
|
||||
['seashell', '#fff5ee'],
|
||||
['sienna', '#a0522d'],
|
||||
['silver', '#c0c0c0'],
|
||||
['skyblue', '#87ceeb'],
|
||||
['slateblue', '#6a5acd'],
|
||||
['slategray', '#708090'],
|
||||
['slategrey', '#708090'],
|
||||
['snow', '#fffafa'],
|
||||
['springgreen', '#00ff7f'],
|
||||
['steelblue', '#4682b4'],
|
||||
['tan', '#d2b48c'],
|
||||
['teal', '#008080'],
|
||||
['thistle', '#d8bfd8'],
|
||||
['tomato', '#ff6347'],
|
||||
['turquoise', '#40e0d0'],
|
||||
['violet', '#ee82ee'],
|
||||
['wheat', '#f5deb3'],
|
||||
['white', '#ffffff'],
|
||||
['whitesmoke', '#f5f5f5'],
|
||||
['yellow', '#ffff00'],
|
||||
['yellowgreen', '#9acd32'],
|
||||
]);
|
||||
356
uni_modules/lime-color/common/format-input.uts
Normal file
356
uni_modules/lime-color/common/format-input.uts
Normal file
@@ -0,0 +1,356 @@
|
||||
// @ts-nocheck
|
||||
import { HSL, HSLA, HSV, HSVA, HSB, HSBA,RGB, RGBA, LColorInfo, LColorFormats } from '../utssdk/interface.uts';
|
||||
import { convertHexToDecimal, hslToRgb, hsvToRgb, parseIntFromHex, rgbToRgb } from './conversion';
|
||||
import { names } from './css-color-names';
|
||||
import { boundAlpha, convertToPercentage, toBoolean } from './util';
|
||||
type ColorMatchers = {
|
||||
CSS_UNIT : RegExp,
|
||||
rgb : RegExp,
|
||||
rgba : RegExp,
|
||||
hsl : RegExp,
|
||||
hsla : RegExp,
|
||||
hsv : RegExp,
|
||||
hsva : RegExp,
|
||||
hsb : RegExp,
|
||||
hsba : RegExp,
|
||||
hex3 : RegExp,
|
||||
hex6 : RegExp,
|
||||
hex4 : RegExp,
|
||||
hex8 : RegExp,
|
||||
}
|
||||
|
||||
// #ifndef UNI-APP-X
|
||||
type UTSJSONObject = object
|
||||
// #endif
|
||||
|
||||
// <http://www.w3.org/TR/css3-values/#integers>
|
||||
const CSS_INTEGER = '[-\\+]?\\d+%?';
|
||||
|
||||
// <http://www.w3.org/TR/css3-values/#number-value>
|
||||
const CSS_NUMBER = '[-\\+]?\\d*\\.\\d+%?';
|
||||
|
||||
// Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
|
||||
// 允许正负整数/数字。不要捕获要么/或者,只需捕获整个结果。
|
||||
const CSS_UNIT = `(?:${CSS_NUMBER})|(?:${CSS_INTEGER})`;
|
||||
|
||||
// Actual matching.
|
||||
// Parentheses and commas are optional, but not required.
|
||||
// Whitespace can take the place of commas or opening paren
|
||||
// 实际匹配。
|
||||
// 圆括号和逗号是可选的,但不是必需的。
|
||||
// 空格可以代替逗号或左括号
|
||||
const PERMISSIVE_MATCH3 = '[\\s|\\(]+(' +
|
||||
CSS_UNIT +
|
||||
')[,|\\s]+(' +
|
||||
CSS_UNIT +
|
||||
')[,|\\s]+(' +
|
||||
CSS_UNIT +
|
||||
')\\s*\\)?';;
|
||||
// const PERMISSIVE_MATCH3 = `[\\s|\\(]+(${CSS_UNIT})[,|\\s]+(${CSS_UNIT})[,|\\s]+(${CSS_UNIT})\\s*\\)?`;
|
||||
const PERMISSIVE_MATCH4 = '[\\s|\\(]+(' +
|
||||
CSS_UNIT +
|
||||
')[,|\\s]+(' +
|
||||
CSS_UNIT +
|
||||
')[,|\\s]+(' +
|
||||
CSS_UNIT +
|
||||
')[,|\\s]+(' +
|
||||
CSS_UNIT +
|
||||
')\\s*\\)?';
|
||||
// const PERMISSIVE_MATCH4 = `[\\s|\\(]+(${CSS_UNIT})[,|\\s]+(${CSS_UNIT})[,|\\s]+(${CSS_UNIT})[,|\\s]+(${CSS_UNIT})\\s*\\)?`;
|
||||
|
||||
export const matchers = {
|
||||
CSS_UNIT: new RegExp(CSS_UNIT),
|
||||
rgb: new RegExp('rgb' + PERMISSIVE_MATCH3),
|
||||
rgba: new RegExp('rgba' + PERMISSIVE_MATCH4),
|
||||
hsl: new RegExp('hsl' + PERMISSIVE_MATCH3),
|
||||
hsla: new RegExp('hsla' + PERMISSIVE_MATCH4),
|
||||
hsv: new RegExp('hsv' + PERMISSIVE_MATCH3),
|
||||
hsva: new RegExp('hsva' + PERMISSIVE_MATCH4),
|
||||
hsb: new RegExp('hsb' + PERMISSIVE_MATCH3),
|
||||
hsba: new RegExp('hsba' + PERMISSIVE_MATCH4),
|
||||
hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
|
||||
hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
|
||||
hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
|
||||
hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
|
||||
} as ColorMatchers;
|
||||
|
||||
/**
|
||||
* Check to see if it looks like a CSS unit
|
||||
* 检查它是否看起来像一个 CSS 单位
|
||||
* (see `matchers` above for definition).
|
||||
*/
|
||||
function isValidCSSUnit(color : string) : boolean
|
||||
function isValidCSSUnit(color : number) : boolean
|
||||
// #ifndef APP
|
||||
function isValidCSSUnit(color : any|null) : boolean
|
||||
// #endif
|
||||
function isValidCSSUnit(color : any|null) : boolean {
|
||||
return toBoolean(matchers.CSS_UNIT.exec(`${color}`));
|
||||
}
|
||||
export { isValidCSSUnit }
|
||||
|
||||
function inputToRGB(color : string) : LColorInfo
|
||||
function inputToRGB(color : RGB) : LColorInfo
|
||||
function inputToRGB(color : RGBA) : LColorInfo
|
||||
function inputToRGB(color : HSL) : LColorInfo
|
||||
function inputToRGB(color : HSLA) : LColorInfo
|
||||
function inputToRGB(color : HSV) : LColorInfo
|
||||
function inputToRGB(color : HSVA) : LColorInfo
|
||||
function inputToRGB(color : HSB) : LColorInfo
|
||||
function inputToRGB(color : HSBA) : LColorInfo
|
||||
function inputToRGB(color : any) : LColorInfo {
|
||||
let _color: UTSJSONObject|null = null
|
||||
let rgb = { r: 0, g: 0, b: 0 } as RGB;
|
||||
let a:any = 1;
|
||||
let s: any | null;
|
||||
let v: any | null;
|
||||
let l: any | null;
|
||||
let ok = false;
|
||||
let format: LColorFormats | null = null;
|
||||
|
||||
if (typeof color == 'string') {
|
||||
_color = stringInputToObject(color as string);
|
||||
} else if(typeof color == 'object'){
|
||||
_color = JSON.parse(JSON.stringify(color)) as UTSJSONObject
|
||||
} else {
|
||||
// _color = {} as UTSJSONObject
|
||||
}
|
||||
if(_color != null){
|
||||
if (isValidCSSUnit(_color['r']) && isValidCSSUnit(_color['g']) && isValidCSSUnit(_color['b'])){
|
||||
rgb = rgbToRgb(_color['r']!, _color['g']!, _color['b']!);
|
||||
ok = true;
|
||||
format = `${_color['r']}`.endsWith('%') ? 'prgb' : 'rgb';
|
||||
} else if(isValidCSSUnit(_color['h']) && isValidCSSUnit(_color['s']) && (isValidCSSUnit(_color['v']) || isValidCSSUnit(_color['b'])) ){
|
||||
const isHSV = _color['v'] != null
|
||||
s = convertToPercentage(_color['s']!);
|
||||
v = isHSV ? convertToPercentage(_color['v']!) : convertToPercentage(_color['b']!);
|
||||
rgb = hsvToRgb(_color['h']!, s, v);
|
||||
ok = true;
|
||||
format = isHSV ? 'hsv' : 'hsb';
|
||||
} else if(isValidCSSUnit(_color['h']) && isValidCSSUnit(_color['s']) && isValidCSSUnit(_color['l'])){
|
||||
s = convertToPercentage(_color['s']!);
|
||||
l = convertToPercentage(_color['l']!);
|
||||
|
||||
rgb = hslToRgb(_color['h']!, s, l);
|
||||
ok = true;
|
||||
format = 'hsl';
|
||||
}
|
||||
if(_color['a']!=null){
|
||||
a = _color['a']!;
|
||||
}
|
||||
}
|
||||
a = boundAlpha(a);
|
||||
return {
|
||||
ok,
|
||||
format: _color?.['format'] as (string | null) ?? format,
|
||||
r: Math.min(255, Math.max(rgb.r, 0)),
|
||||
g: Math.min(255, Math.max(rgb.g, 0)),
|
||||
b: Math.min(255, Math.max(rgb.b, 0)),
|
||||
a,
|
||||
} as LColorInfo
|
||||
}
|
||||
|
||||
export {
|
||||
inputToRGB
|
||||
}
|
||||
|
||||
/**
|
||||
* Permissive string parsing. Take in a number of formats, and output an object
|
||||
* based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
|
||||
*/
|
||||
|
||||
export function stringInputToObject(color : string) : UTSJSONObject | null {
|
||||
let _color = color.trim().toLowerCase();
|
||||
if (_color.length == 0) {
|
||||
return null;
|
||||
}
|
||||
let named = false;
|
||||
if (names.get(_color) != null) {
|
||||
_color = names.get(_color)!;
|
||||
named = true;
|
||||
} else if (_color == 'transparent') {
|
||||
return { r: 0, g: 0, b: 0, a: 0, format: 'name' } as UTSJSONObject;
|
||||
// return new Map([
|
||||
// ['r', 0],
|
||||
// ['g', 0],
|
||||
// ['b', 0],
|
||||
// ['a', 0],
|
||||
// ['format', 'name'],
|
||||
// ])
|
||||
}
|
||||
// Try to match string input using regular expressions.
|
||||
// Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
|
||||
// Just return an object and let the conversion functions handle that.
|
||||
// This way the result will be the same whether the tinycolor is initialized with string or object.
|
||||
|
||||
let match = matchers.rgb.exec(_color);
|
||||
if (match != null) {
|
||||
const r = match[1]
|
||||
const g = match[2]
|
||||
const b = match[3]
|
||||
|
||||
return { r, g, b } as UTSJSONObject;
|
||||
// return new Map([
|
||||
// ['r', match[1]],
|
||||
// ['g', match[2]],
|
||||
// ['b', match[3]],
|
||||
// ])
|
||||
}
|
||||
|
||||
match = matchers.rgba.exec(_color);
|
||||
if (match != null) {
|
||||
const r = match[1]
|
||||
const g = match[2]
|
||||
const b = match[3]
|
||||
const a = match[4]
|
||||
return { r, g, b, a } as UTSJSONObject;
|
||||
// return new Map([
|
||||
// ['r', match[1]],
|
||||
// ['g', match[2]],
|
||||
// ['b', match[3]],
|
||||
// ['a', match[4]],
|
||||
// ])
|
||||
}
|
||||
|
||||
match = matchers.hsl.exec(_color);
|
||||
if (match != null) {
|
||||
const h = match[1]
|
||||
const s = match[2]
|
||||
const l = match[3]
|
||||
return { h, s, l } as UTSJSONObject;
|
||||
// return new Map([
|
||||
// ['h', match[1]],
|
||||
// ['s', match[2]],
|
||||
// ['l', match[3]],
|
||||
// ])
|
||||
}
|
||||
|
||||
match = matchers.hsla.exec(_color);
|
||||
if (match != null) {
|
||||
const h = match[1]
|
||||
const s = match[2]
|
||||
const l = match[3]
|
||||
const a = match[4]
|
||||
return { h, s, l, a } as UTSJSONObject;
|
||||
// return new Map([
|
||||
// ['h', match[1]],
|
||||
// ['s', match[2]],
|
||||
// ['l', match[3]],
|
||||
// ['a', match[4]],
|
||||
// ])
|
||||
}
|
||||
|
||||
match = matchers.hsv.exec(_color);
|
||||
if (match != null) {
|
||||
const h = match[1]
|
||||
const s = match[2]
|
||||
const v = match[3]
|
||||
return { h, s, v } as UTSJSONObject;
|
||||
// return new Map([
|
||||
// ['h', match[1]],
|
||||
// ['s', match[2]],
|
||||
// ['v', match[3]],
|
||||
// ])
|
||||
}
|
||||
|
||||
match = matchers.hsva.exec(_color);
|
||||
if (match != null) {
|
||||
const h = match[1]
|
||||
const s = match[2]
|
||||
const v = match[3]
|
||||
const a = match[4]
|
||||
return { h, s, v, a } as UTSJSONObject;
|
||||
// return new Map([
|
||||
// ['h', match[1]],
|
||||
// ['s', match[2]],
|
||||
// ['v', match[3]],
|
||||
// ['a', match[4]],
|
||||
// ])
|
||||
}
|
||||
|
||||
match = matchers.hex8.exec(_color);
|
||||
if (match != null) {
|
||||
const r = parseIntFromHex(match[1]!)
|
||||
const g = parseIntFromHex(match[2]!)
|
||||
const b = parseIntFromHex(match[3]!)
|
||||
const a = convertHexToDecimal(match[4]!)
|
||||
return {
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
a,
|
||||
format: named ? 'name' : 'hex8',
|
||||
} as UTSJSONObject;
|
||||
// return new Map([
|
||||
// ['r', parseIntFromHex(match[1])],
|
||||
// ['g', parseIntFromHex(match[2])],
|
||||
// ['b', parseIntFromHex(match[3])],
|
||||
// ['a', convertHexToDecimal(match[4])],
|
||||
// ['format', named ? 'name' : 'hex8'],
|
||||
// ])
|
||||
}
|
||||
|
||||
match = matchers.hex6.exec(_color);
|
||||
if (match != null) {
|
||||
const r = parseIntFromHex(match[1]!)
|
||||
const g = parseIntFromHex(match[2]!)
|
||||
const b = parseIntFromHex(match[3]!)
|
||||
// const a = parseIntFromHex(match[4])
|
||||
return {
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
format: named ? 'name' : 'hex',
|
||||
} as UTSJSONObject;
|
||||
// return new Map([
|
||||
// ['r', parseIntFromHex(match[1])],
|
||||
// ['g', parseIntFromHex(match[2])],
|
||||
// ['b', parseIntFromHex(match[3])],
|
||||
// ['format', named ? 'name' : 'hex'],
|
||||
// ])
|
||||
}
|
||||
|
||||
match = matchers.hex4.exec(_color);
|
||||
if (match != null) {
|
||||
const r = parseIntFromHex((match[1] + match[1]))
|
||||
const g = parseIntFromHex((match[2] + match[2]))
|
||||
const b = parseIntFromHex((match[3] + match[3]))
|
||||
const a = convertHexToDecimal((match[4] + match[4]))
|
||||
return {
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
a,
|
||||
format: named ? 'name' : 'hex8',
|
||||
} as UTSJSONObject;
|
||||
// return new Map([
|
||||
// ['r', parseIntFromHex(match[1] + match[1])],
|
||||
// ['g', parseIntFromHex(match[2] + match[2])],
|
||||
// ['b', parseIntFromHex(match[3] + match[3])],
|
||||
// ['a', convertHexToDecimal(match[4] + match[4])],
|
||||
// ['format', named ? 'name' : 'hex8'],
|
||||
// ])
|
||||
}
|
||||
|
||||
match = matchers.hex3.exec(_color);
|
||||
if (match != null) {
|
||||
const r = parseIntFromHex((match[1] + match[1]))
|
||||
const g = parseIntFromHex((match[2] + match[2]))
|
||||
const b = parseIntFromHex((match[3] + match[3]))
|
||||
return {
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
format: named ? 'name' : 'hex',
|
||||
} as UTSJSONObject;
|
||||
// return new Map([
|
||||
// ['r', parseIntFromHex(match[1] + match[1])],
|
||||
// ['g', parseIntFromHex(match[2] + match[2])],
|
||||
// ['b', parseIntFromHex(match[3] + match[3])],
|
||||
// ['format', named ? 'name' : 'hex'],
|
||||
// ])
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
202
uni_modules/lime-color/common/generate.uts
Normal file
202
uni_modules/lime-color/common/generate.uts
Normal file
@@ -0,0 +1,202 @@
|
||||
// https://github.com/ant-design/ant-design-colors/blob/main/src/generate.ts
|
||||
import { inputToRGB } from './format-input';
|
||||
import { rgbToHex, rgbToHsv } from './conversion';
|
||||
import { HSV, LColorInfo, LGenerateOptions} from '../utssdk/interface.uts';
|
||||
|
||||
type DarkColorMapItem = {
|
||||
index : number;
|
||||
opacity : number;
|
||||
};
|
||||
const hueStep = 2; // 色相阶梯
|
||||
const saturationStep = 0.16; // 饱和度阶梯,浅色部分
|
||||
const saturationStep2 = 0.05; // 饱和度阶梯,深色部分
|
||||
const brightnessStep1 = 0.05; // 亮度阶梯,浅色部分
|
||||
const brightnessStep2 = 0.15; // 亮度阶梯,深色部分
|
||||
const lightColorCount = 5; // 浅色数量,主色上
|
||||
const darkColorCount = 4; // 深色数量,主色下
|
||||
// 暗色主题颜色映射关系表
|
||||
const darkColorMap = [
|
||||
{ index: 7, opacity: 0.15 },
|
||||
{ index: 6, opacity: 0.25 },
|
||||
{ index: 5, opacity: 0.3 },
|
||||
{ index: 5, opacity: 0.45 },
|
||||
{ index: 5, opacity: 0.65 },
|
||||
{ index: 5, opacity: 0.85 },
|
||||
{ index: 4, opacity: 0.9 },
|
||||
{ index: 3, opacity: 0.95 },
|
||||
{ index: 2, opacity: 0.97 },
|
||||
{ index: 1, opacity: 0.98 },
|
||||
] as DarkColorMapItem[];
|
||||
|
||||
|
||||
// 从 TinyColor.toHsv 移植的包装函数
|
||||
// 保留这里,因为有 `hsv.h * 360`
|
||||
function toHsv({ r, g, b } : LColorInfo) : HSV {
|
||||
// 将 RGB 值转换为 HSV 值
|
||||
const hsv = rgbToHsv(r, g, b);
|
||||
// 返回一个 HsvObject,其中 h 值乘以 360
|
||||
return { h: hsv.h * 360, s: hsv.s, v: hsv.v } as HSV;
|
||||
}
|
||||
|
||||
// 从 TinyColor.toHexString 移植的包装函数
|
||||
// 保留这里,因为有前缀 `#`
|
||||
function toHex({ r, g, b }: LColorInfo) : string {
|
||||
// 将 RGB 值转换为十六进制字符串,并添加前缀 `#`
|
||||
return `#${rgbToHex(r, g, b, false)}`;
|
||||
}
|
||||
|
||||
|
||||
// 从 TinyColor.mix 移植的包装函数,无法进行 tree-shaking
|
||||
// 数量范围为 [0, 1]
|
||||
// 假设 color1 和 color2 没有透明度,因为以下源代码也是如此
|
||||
function mix(rgb1 : LColorInfo, rgb2 : LColorInfo, amount : number) : LColorInfo {
|
||||
// 将 amount 除以 100,得到一个范围为 [0, 1] 的值
|
||||
const p = amount / 100;
|
||||
// 计算混合后的 RGB 值
|
||||
const rgb = {
|
||||
r: (rgb2.r - rgb1.r) * p + rgb1.r,
|
||||
g: (rgb2.g - rgb1.g) * p + rgb1.g,
|
||||
b: (rgb2.b - rgb1.b) * p + rgb1.b,
|
||||
a: 1
|
||||
} as LColorInfo;
|
||||
// 返回混合后的 RGB 对象
|
||||
return rgb;
|
||||
}
|
||||
|
||||
// 根据给定的 HSV 对象和索引值计算新的色相值
|
||||
// 如果 light 参数为 true,则色相向左转动;否则向右转动
|
||||
function getHue(hsv : HSV, i : number, light : boolean = false) : number {
|
||||
let hue : number;
|
||||
// 根据色相不同,色相转向不同
|
||||
if (Math.round(hsv.h) >= 60 && Math.round(hsv.h) <= 240) {
|
||||
// 如果色相在 60 到 240 之间,向左转动
|
||||
hue = light ? Math.round(hsv.h) - hueStep * i : Math.round(hsv.h) + hueStep * i;
|
||||
} else {
|
||||
hue = light ? Math.round(hsv.h) + hueStep * i : Math.round(hsv.h) - hueStep * i;
|
||||
}
|
||||
|
||||
if (hue < 0) {
|
||||
// 如果新的色相值小于 0,则加上 360
|
||||
hue += 360;
|
||||
} else if (hue >= 360) {
|
||||
// 如果新的色相值大于等于 360,则减去 360
|
||||
hue -= 360;
|
||||
}
|
||||
return hue;
|
||||
}
|
||||
|
||||
|
||||
// 根据给定的 HSV 对象和索引值计算新的饱和度值
|
||||
// 如果 light 参数为 true,则饱和度减小;否则增加
|
||||
function getSaturation(hsv : HSV, i : number, light : boolean = false) : number {
|
||||
// grey color don't change saturation
|
||||
// 如果颜色是灰色(色相和饱和度都为 0),则饱和度不变
|
||||
if (hsv.h == 0 && hsv.s == 0) {
|
||||
return hsv.s;
|
||||
}
|
||||
let saturation : number;
|
||||
// 如果 light 参数为 true,则饱和度减小
|
||||
if (light) {
|
||||
saturation = hsv.s - saturationStep * i;
|
||||
}
|
||||
// 如果 i 等于 darkColorCount,则饱和度增加
|
||||
else if (i == darkColorCount) {
|
||||
saturation = hsv.s + saturationStep;
|
||||
}
|
||||
// 否则,饱和度增加
|
||||
else {
|
||||
saturation = hsv.s + saturationStep2 * i;
|
||||
}
|
||||
// 边界值修正
|
||||
if (saturation > 1) {
|
||||
saturation = 1;
|
||||
}
|
||||
// 第一格的 s 限制在 0.06-0.1 之间
|
||||
if (light && i == lightColorCount && saturation > 0.1) {
|
||||
saturation = 0.1;
|
||||
}
|
||||
if (saturation < 0.06) {
|
||||
saturation = 0.06;
|
||||
}
|
||||
return parseFloat(saturation.toFixed(2))
|
||||
}
|
||||
|
||||
// 根据给定的 HSV 对象和索引值计算新的亮度值
|
||||
// 如果 light 参数为 true,则亮度增加;否则减少
|
||||
function getValue(hsv : HSV, i : number, light : boolean = false) : number {
|
||||
let value : number;
|
||||
// 如果 light 参数为 true,则亮度增加
|
||||
if (light) {
|
||||
value = hsv.v + brightnessStep1 * i;
|
||||
} else {
|
||||
value = hsv.v - brightnessStep2 * i;
|
||||
}
|
||||
if (value > 1) {
|
||||
value = 1;
|
||||
}
|
||||
// 返回保留两位小数的亮度值
|
||||
return parseFloat(value.toFixed(2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* generate 函数用于生成一组基于给定颜色的色彩模式。
|
||||
* 它可以生成亮色、暗色和深色主题颜色模式。
|
||||
*
|
||||
* @param {string} color - 输入的颜色值,可以是十六进制、RGB、RGBA、HSL、HSLA或颜色名称。
|
||||
* @param {LGenerateOptions} [opts] - 可选的生成选项。
|
||||
* @returns {string[]} - 返回一个包含生成的颜色模式的字符串数组。
|
||||
*/
|
||||
export function generate(color : string, opts : LGenerateOptions = {} as LGenerateOptions) : string[] {
|
||||
const patterns : string[] = [];
|
||||
const pColor = inputToRGB(color);
|
||||
|
||||
// 生成亮色模式
|
||||
for (let i = lightColorCount; i > 0; i -= 1) {
|
||||
const hsv = toHsv(pColor);
|
||||
const colorString : string = toHex(
|
||||
inputToRGB({
|
||||
h: getHue(hsv, i, true),
|
||||
s: getSaturation(hsv, i, true),
|
||||
v: getValue(hsv, i, true),
|
||||
}),
|
||||
);
|
||||
patterns.push(colorString);
|
||||
}
|
||||
|
||||
// 添加原始颜色
|
||||
patterns.push(toHex(pColor));
|
||||
|
||||
// 生成暗色模式
|
||||
for (let i = 1; i <= darkColorCount; i += 1) {
|
||||
const hsv = toHsv(pColor);
|
||||
const colorString : string = toHex(
|
||||
inputToRGB({
|
||||
h: getHue(hsv, i),
|
||||
s: getSaturation(hsv, i),
|
||||
v: getValue(hsv, i),
|
||||
}),
|
||||
);
|
||||
patterns.push(colorString);
|
||||
}
|
||||
|
||||
// 如果选项中指定了 dark 主题,则生成深色主题颜色模式
|
||||
if (opts.theme == 'dark') {
|
||||
return darkColorMap.map(({ index, opacity }, _):string => {
|
||||
const darkColorString : string = toHex(
|
||||
mix(
|
||||
inputToRGB(opts.backgroundColor ?? '#141414'),
|
||||
inputToRGB(patterns[index]),
|
||||
opacity * 100,
|
||||
),
|
||||
);
|
||||
return darkColorString;
|
||||
});
|
||||
}
|
||||
|
||||
// 返回默认颜色模式
|
||||
return patterns;
|
||||
}
|
||||
|
||||
211
uni_modules/lime-color/common/test.uts
Normal file
211
uni_modules/lime-color/common/test.uts
Normal file
@@ -0,0 +1,211 @@
|
||||
// import * as util from './util-test'
|
||||
// import * as util from './conversion-test'
|
||||
// import * as util from './format-input-test'
|
||||
// import * as util from './color-test'
|
||||
// import * as util from './generate-test'
|
||||
import { tinyColor } from './color'
|
||||
|
||||
// console.log('generate:', generate('red'))
|
||||
console.log('tinyColor~~~~~~~~~~~~~~test')
|
||||
// console.log('示例1',tinyColor('#000'));
|
||||
// console.log('示例2',tinyColor('000'));
|
||||
// console.log('示例3',tinyColor('#369C'));
|
||||
// console.log('示例4',tinyColor('369C'));
|
||||
// console.log('示例5',tinyColor('#f0f0f6'));
|
||||
// console.log('示例6',tinyColor('f0f0f6'));
|
||||
// console.log('示例7',tinyColor('#f0f0f688'));
|
||||
// console.log(tinyColor('f0f0f688'));
|
||||
|
||||
// console.log('示例1',tinyColor('hsl(0, 100%, 50%)').toString());
|
||||
// console.log('示例2',tinyColor('hsla(0, 100%, 50%, .5)').toString());
|
||||
// console.log('示例3',tinyColor('hsl(0, 100%, 50%)').toString());
|
||||
// console.log('示例4',tinyColor('hsl 0 1.0 0.5').toString());
|
||||
// console.log('示例5',tinyColor({ h: 0, s: 1, l: 0.5 }).toString());
|
||||
|
||||
// console.log('示例1',tinyColor('hsv(0, 100%, 100%)').toString());
|
||||
// console.log('示例2',tinyColor('hsva(0, 100%, 100%, .5)').toString());
|
||||
// console.log('示例3',tinyColor('hsv (0 100% 100%)').toString());
|
||||
// console.log('示例4',tinyColor('hsv 0 1 1').toString());
|
||||
// console.log('示例5',tinyColor({ h: 0, s: 100, v: 100 }).toString());
|
||||
|
||||
// console.log('示例1',tinyColor('RED').toString(), tinyColor('RED'));
|
||||
// console.log('示例2',tinyColor('blanchedalmond').toString());
|
||||
// console.log('示例3',tinyColor('darkblue').toString());
|
||||
|
||||
// console.log('示例1:',0x0,tinyColor(0x0).toString());
|
||||
// console.log('示例2',tinyColor(0xaabbcc).toString());
|
||||
// console.log('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
|
||||
// const color = tinyColor('red')
|
||||
// const color2 = tinyColor({ r: 255, g: 255, b: 255 })
|
||||
// console.log('示例1:',color.originalInput);
|
||||
// console.log('示例2:',color2.originalInput);
|
||||
|
||||
// const color3 = tinyColor('red')
|
||||
// const color4 = tinyColor({ r: 255, g: 255, b: 255 })
|
||||
// console.log('示例3:',color3.format);
|
||||
// console.log('示例4:',color4.format);
|
||||
|
||||
// const color5 = tinyColor('red');
|
||||
// console.log(color5.isValid, color5.toHexString())
|
||||
// const color6 = tinyColor('not a color');
|
||||
// console.log(color6.isValid, color6.toHexString())
|
||||
|
||||
// const color7 = tinyColor('#fff');
|
||||
// const color8 = tinyColor('#000')
|
||||
// console.log(color7.getBrightness())
|
||||
// console.log(color8.getBrightness())
|
||||
|
||||
// const color9 = tinyColor('#fff');
|
||||
// const color10 = tinyColor('#000')
|
||||
// console.log(color9.isLight())
|
||||
// console.log(color10.isLight())
|
||||
|
||||
// const color11 = tinyColor('#fff');
|
||||
// const color12 = tinyColor('#000')
|
||||
// console.log(color11.isDark())
|
||||
// console.log(color12.isDark())
|
||||
|
||||
// const color13 = tinyColor('#fff');
|
||||
// const color14 = tinyColor('#000')
|
||||
// console.log(color13.getLuminance())
|
||||
// console.log(color14.getLuminance())
|
||||
|
||||
// const color15 = tinyColor('rgba(255, 0, 0, .5)');
|
||||
// const color16 = tinyColor('rgb(255, 0, 0)')
|
||||
// const color17 = tinyColor('transparent')
|
||||
// console.log(color15.getAlpha())
|
||||
// console.log(color16.getAlpha())
|
||||
// console.log(color17.getAlpha())
|
||||
|
||||
// const color18 = tinyColor('red');
|
||||
// console.log(color18.getAlpha()) ; // 1
|
||||
// color18.setAlpha(0.5);
|
||||
// console.log(color18.getAlpha()); // .5
|
||||
// console.log(color18.toRgbString()); // "rgba(255, 0, 0, .5)"
|
||||
|
||||
// const color19 = tinyColor('rgba(255, 0, 0, .5)');
|
||||
// const computedColor = color19.onBackground('rgb(0, 0, 255)');
|
||||
// console.log('color19',computedColor.toRgbString()); // "rgb(128, 0, 128)"
|
||||
|
||||
// const color20 = tinyColor('red');
|
||||
// console.log('color20',color20.toHsv()); // { h: 0, s: 1, v: 1, a: 1 }
|
||||
|
||||
// const color21 = tinyColor('red');
|
||||
// console.log(color21.toHsvString()); // "hsv(0, 100%, 100%)"
|
||||
// color21.setAlpha(0.5);
|
||||
// console.log(color21.toHsvString()); // "hsva(0, 100%, 100%, 0.5)"
|
||||
|
||||
// const color33 = tinyColor('red');
|
||||
// console.log(color33.toHsl()); // { h: 0, s: 1, l: 0.5, a: 1 }
|
||||
|
||||
// const color34 = tinyColor('red');
|
||||
// console.log(color34.toHsvString()); // "hsl(0, 100%, 50%)"
|
||||
// color34.setAlpha(0.5);
|
||||
// console.log(color34.toHsvString()); // "hsla(0, 100%, 50%, 0.5)"
|
||||
|
||||
// console.log(tinyColor('#aabbcc').toNumber() == 0xaabbcc)
|
||||
// console.log(tinyColor('rgb(1, 1, 1)').toNumber() == (1 << 16) + (1 << 8) + 1)
|
||||
|
||||
// const color35 = tinyColor('red');
|
||||
// console.log(color35.toHex()); // "ff0000"
|
||||
|
||||
// const color36 = tinyColor('red');
|
||||
// console.log(color36.toHexString()); // "#ff0000"
|
||||
|
||||
// const color37 = tinyColor('red');
|
||||
// console.log(color37.toHex8()); // "ff0000ff"
|
||||
|
||||
// const color38 = tinyColor('red');
|
||||
// console.log(color38.toHex8String()); // "#ff0000ff"
|
||||
|
||||
// const color39 = tinyColor('#ff000000');
|
||||
// console.log(color39.toHexShortString()); // "#ff000000"
|
||||
// console.log(color39.toHexShortString(true)); // "#f000"
|
||||
|
||||
// const color40 = tinyColor('#ff0000ff');
|
||||
// console.log(color40.toHexShortString()); // "#ff0000"
|
||||
// console.log(color40.toHexShortString(true)); // "#f00"
|
||||
|
||||
// const color41 = tinyColor('red');
|
||||
// console.log(color41.toRgb()); // { r: 255, g: 0, b: 0, a: 1 }
|
||||
|
||||
// const color42 = tinyColor('red');
|
||||
// console.log(color42.toRgbString()); // "rgb(255, 0, 0)"
|
||||
// color42.setAlpha(0.5);
|
||||
// console.log(color42.toRgbString()); // "rgba(255, 0, 0, 0.5)"
|
||||
|
||||
// const color43 = tinyColor('red')
|
||||
// console.log(color43.toPercentageRgb())
|
||||
|
||||
// const color44 = tinyColor('red');
|
||||
// console.log(color44.toPercentageRgbString()); // "rgb(100%, 0%, 0%)"
|
||||
// color44.setAlpha(0.5);
|
||||
// console.log(color44.toPercentageRgbString()); // "rgba(100%, 0%, 0%, 0.5)"
|
||||
|
||||
// const color45 = tinyColor('red');
|
||||
// console.log(color45.toName()); // "red"
|
||||
|
||||
// const color46 = tinyColor('red');
|
||||
// console.log(color46.toString()); // "red"
|
||||
// console.log(color46.toString('hsv')); // "hsv(0, 100%, 100%)"
|
||||
|
||||
// const color47 = tinyColor('rgb(255, 0, 0)');
|
||||
// console.log(color47.toString()); // "rgb(255, 0, 0)"
|
||||
// color47.setAlpha(0.5);
|
||||
// console.log(color47.toString()); // "rgba(255, 0, 0, 0.5)"
|
||||
|
||||
// const color48 = tinyColor('red')
|
||||
// .lighten()
|
||||
// .desaturate()
|
||||
// .toHexString()
|
||||
// console.log(color48)
|
||||
|
||||
// console.log(tinyColor('#f00').lighten().toString())
|
||||
// console.log(tinyColor('#f00').lighten(100).toString())
|
||||
|
||||
// console.log(tinyColor('#f00').brighten().toString())
|
||||
console.log('tinyColor',tinyColor({a: 1, h: 0, l: 0.4, s: 1}))
|
||||
// console.log(tinyColor('#f00').darken(100).toString())
|
||||
// console.log(tinyColor('#f00').tint().toString())
|
||||
// console.log(tinyColor('#f00').tint(100).toString())
|
||||
// console.log(tinyColor('#f00').shade().toString())
|
||||
// console.log(tinyColor('#f00').shade(100).toString())
|
||||
// console.log(tinyColor('#f00').desaturate().toString())
|
||||
// console.log(tinyColor('#f00').desaturate(100).toString())
|
||||
// console.log(tinyColor('hsl(0, 10%, 50%)').saturate().toString())
|
||||
// console.log(tinyColor('#f00').greyscale().toString())
|
||||
// console.log(tinyColor('#f00').spin(180).toString())
|
||||
// console.log(tinyColor('#f00').spin(-90).toString())
|
||||
// console.log(tinyColor('#f00').spin(90).toString())
|
||||
// console.log(tinyColor('#f00').spin(0).toString())
|
||||
// console.log(tinyColor('#f00').spin(360).toString())
|
||||
// let color51 = tinyColor('#f0f');
|
||||
// let color52 = tinyColor('#0f0');
|
||||
// console.log(color51.mix(color52).toHexString())
|
||||
|
||||
// const colors52 = tinyColor('#f00').analogous()
|
||||
// console.log(colors52.map((t):string => t.toHexString()))
|
||||
|
||||
// const colors53 = tinyColor('#f00').monochromatic();
|
||||
// console.log(colors53.map((t):string => t.toHexString()))
|
||||
// const colors54 = tinyColor('#f00').splitcomplement();
|
||||
// console.log(colors54.map((t):string => t.toHexString()));
|
||||
|
||||
// const colors55 = tinyColor('#f00').triad();
|
||||
// console.log(colors55.map((t):string => t.toHexString()));
|
||||
|
||||
// const colors56 = tinyColor('#f00').tetrad();
|
||||
// console.log(colors56.map((t):string => t.toHexString()));
|
||||
|
||||
// const colors57 = tinyColor('#f00').polyad(4);
|
||||
// console.log(colors57.map((t):string => t.toHexString()));
|
||||
// console.log(tinyColor('#f00').complement().toHexString())
|
||||
|
||||
|
||||
// let color158 = tinyColor('red');
|
||||
// let color58 = tinyColor('#f00');
|
||||
|
||||
// function a():string{
|
||||
// return 'rgb(255, 0, 0)'
|
||||
// }
|
||||
// console.log('tinyColor equals:', color158.equals(color58), color158.equals('#f00'), a() == a());
|
||||
200
uni_modules/lime-color/common/util.uts
Normal file
200
uni_modules/lime-color/common/util.uts
Normal file
@@ -0,0 +1,200 @@
|
||||
// import {isNumber} from '@/uni_modules/lime-shared/isNumber'
|
||||
// import {isString} from '@/uni_modules/lime-shared/isString'
|
||||
// import {isNumeric} from '@/uni_modules/lime-shared/isNumeric'
|
||||
// #ifdef APP-ANDROID
|
||||
import BigDecimal from 'java.math.BigDecimal'
|
||||
// #endif
|
||||
export function isNumber(value: any|null):boolean{
|
||||
// #ifdef APP-ANDROID
|
||||
return ['Byte', 'UByte','Short','UShort','Int','UInt','Long','ULong','Float','Double','number'].includes(typeof value)
|
||||
// #endif
|
||||
// #ifdef APP-IOS
|
||||
return ['Int8', 'UInt8','Int16','UInt16','Int32','UInt32','Int64','UInt64','Int','UInt','Float','Float16','Float32','Float64','Double', 'number'].includes(typeof value)
|
||||
// #endif
|
||||
// #ifndef APP-ANDROID || APP-IOS
|
||||
return typeof value == 'number' && !isNaN(value);
|
||||
// #endif
|
||||
}
|
||||
export function isString(value: any|null):boolean{
|
||||
return typeof value == 'string';
|
||||
}
|
||||
export function isNumeric(value: any|null):boolean{
|
||||
if(isNumber(value)) {
|
||||
return true
|
||||
} else if(isString(value)) {
|
||||
// const regex = "-?\\d+(\\.\\d+)?".toRegex()
|
||||
const regex = new RegExp("^(-)?\\d+(\\.\\d+)?$")
|
||||
return regex.test(value as string) //regex.matches(value as string)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
export function toBoolean(value: any|null):boolean{
|
||||
// #ifdef APP
|
||||
// 根据输入值的类型,返回相应的布尔值
|
||||
if(isNumber(value)){
|
||||
return (value as number) != 0;
|
||||
}
|
||||
if(isString(value)){
|
||||
return `${value}`.length > 0;
|
||||
}
|
||||
if(typeof value == 'boolean'){
|
||||
return value as boolean;
|
||||
}
|
||||
|
||||
return value != null
|
||||
// #endif
|
||||
// #ifndef APP
|
||||
return Boolean(value)
|
||||
// #endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if string passed in is a percentage
|
||||
* 检查传入的字符串是否为百分比
|
||||
* @hidden
|
||||
*/
|
||||
export function isPercentage(n : any) : boolean {
|
||||
return isString(n) && (n as string).indexOf('%') != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
|
||||
* 需要处理 1.0 为 100%,因为一旦它是数字,它与 1 没有区别
|
||||
* <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
|
||||
* @hidden
|
||||
*/
|
||||
export function isOnePointZero(n : any) : boolean {
|
||||
return isString(n) && (n as string).indexOf('.') != -1 && parseFloat(n as string) == 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Take input from [0, n] and return it as [0, 1]
|
||||
* 将输入值从 [0, n] 转换为 [0, 1]
|
||||
* @hidden
|
||||
*/
|
||||
function bound01(n: string, max: number): number
|
||||
function bound01(n: number, max: number): number
|
||||
// #ifndef APP
|
||||
function bound01(n : any, max : number) : number
|
||||
// #endif
|
||||
function bound01(n : any, max : number) : number {
|
||||
if(!(isNumber(n) || isString(n))){
|
||||
return 1
|
||||
}
|
||||
if (isOnePointZero(n)) {
|
||||
n = '100%';
|
||||
}
|
||||
|
||||
const isPercent = isPercentage(n);
|
||||
n = (isNumber(n) ? n : parseFloat(n as string)) as number
|
||||
n = max == 360 ? n : Math.min(max, Math.max(0, n));
|
||||
|
||||
// Automatically convert percentage into number
|
||||
// 自动将百分比转换为数字
|
||||
if (isPercent) {
|
||||
n = parseInt(`${Math.min(n, 100) * max}`, 10) / 100;
|
||||
}
|
||||
|
||||
// Handle floating point rounding errors
|
||||
// 处理浮点数舍入误差
|
||||
|
||||
if ( Math.abs(n - max) < 0.000001) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Convert into [0, 1] range if it isn't already
|
||||
// 如果它还不是,将其转换为 [0, 1] 范围
|
||||
if (max == 360) {
|
||||
// If n is a hue given in degrees,
|
||||
// wrap around out-of-range values into [0, 360] range
|
||||
// then convert into [0, 1].
|
||||
// 如果 n 是以度为单位的色调,
|
||||
// 将超出范围的值环绕到 [0, 360] 范围内
|
||||
// 然后将其转换为 [0, 1]。
|
||||
n = (n < 0 ? (n % max) + max : n % max) / max // parseFloat(`${max}`);
|
||||
} else {
|
||||
// If n not a hue given in degrees
|
||||
// Convert into [0, 1] range if it isn't already.
|
||||
// 如果 n 不是以度为单位的色调
|
||||
// 如果它还不是,将其转换为 [0, 1] 范围。
|
||||
n = (n % max) / max //parseFloat(`${max}`);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
export {bound01}
|
||||
|
||||
|
||||
/**
|
||||
* Force a number between 0 and 1
|
||||
* 在 0 和 1 之间强制一个数字
|
||||
* @hidden
|
||||
*/
|
||||
export function clamp01(val : number) : number {
|
||||
return Math.min(1, Math.max(0, val));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a valid alpha value [0,1] with all invalid values being set to 1
|
||||
* 返回一个有效的 alpha 值 [0,1],将所有无效值设置为 1
|
||||
* @hidden
|
||||
*/
|
||||
function boundAlpha(a: number):number
|
||||
function boundAlpha(a: string):number
|
||||
// #ifndef APP
|
||||
function boundAlpha(a: any|null) : number
|
||||
// #endif
|
||||
function boundAlpha(a: any|null) : number {
|
||||
let n = a == null ? 1 : (isString(a) ? parseFloat(a as string) : a as number)
|
||||
|
||||
if (isNaN(n) || n < 0 || n > 1) {
|
||||
n = 1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
export {
|
||||
boundAlpha
|
||||
}
|
||||
/**
|
||||
* Replace a decimal with it's percentage value
|
||||
* 用百分比值替换小数
|
||||
* number | string
|
||||
* @hidden
|
||||
*/
|
||||
function convertToPercentage(n:number):number
|
||||
function convertToPercentage(n:string):string
|
||||
// #ifndef APP
|
||||
function convertToPercentage(n:any): any
|
||||
// #endif
|
||||
function convertToPercentage(n:any): any{
|
||||
// #ifdef APP-ANDROID
|
||||
n = isNumeric(n) ? parseFloat(typeof n == 'string' ? n as string : BigDecimal.valueOf((n as number).toDouble()).toPlainString()) : n// as number
|
||||
// #endif
|
||||
// #ifndef APP-ANDROID
|
||||
n = isNumeric(n) ? parseFloat(`${n}`) : n// as number
|
||||
// #endif
|
||||
if(isNumber(n) && (n as number) <= 1){
|
||||
return `${n * 100}%`.replace('.0%','%');
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
export {convertToPercentage}
|
||||
|
||||
/**
|
||||
* Force a hex value to have 2 characters
|
||||
* 强制使十六进制值具有 2 个字符
|
||||
* @hidden
|
||||
*/
|
||||
export function pad2(c : string) : string {
|
||||
//c.padStart(2, '0');//
|
||||
return c.length == 1 ? '0' + c : `${c}`;
|
||||
}
|
||||
Reference in New Issue
Block a user