in src/common/common.ts [823:902]
export function calcLinearColor(primaryColor: string, backgroundColor?: string, linearCount?: number, type?: string, needDistribution?: boolean) {
const linear = [];
const front = tinycolor(primaryColor);
const { h, s, v } = front.toHsv();
const { v: backValue } = tinycolor(backgroundColor).toHsv();
const isLight = backValue > 0.5;
const whiteV = tinycolor("#ffffff").toHsv().v;
const count = linearCount + 1;
// 中心取色逻辑
if (type === 'center') {
let colorString;
for (let i = 1; i < count + 1; i++) {
colorString = tinycolor({
h,
s: Math.round((i * s * 100) / count) + 1,
v: Math.round(((i * (v - whiteV)) / count + whiteV) * 100),
}).toHexString();
if (i % 2 === 0) {
linear.push(colorString);
} else if (colorString === primaryColor) {
linear.push(colorString);
}
}
for (let i = count; i > Math.floor(count/ 2) + 1; i--) {
colorString = tinycolor.mix("#000000", primaryColor, (i - 2) * 10).toHexString();
linear.push(colorString);
}
if (linear[Math.floor(linearCount / 2)] !== primaryColor) {
linear[Math.floor(linearCount / 2)] = primaryColor;
}
} else {
// 如果数量超过10,则有限调整前5的颜色梯度差值,避免过于相近
// 同时需要防止颜色过于趋向于白/黑
if (needDistribution) {
const distributionArray = generateScaledArray(count);
// console.log(distributionArray)
for (let i = count - 1; i > 0; i--) {
let colorString;
// 亮色模式
if (isLight) {
colorString = tinycolor({
h,
s: distributionArray[count - i - 1] * s * 100,
// v: v * 100,
v: Math.round(((i * (v - backValue)) / count + backValue) * 100),
}).toHexString();
} else {
// 暗色模式
colorString = tinycolor.mix(backgroundColor, primaryColor, distributionArray[count - i - 1] * 100).toHexString();
}
linear.push(colorString);
}
} else {
for (let i = count - 1; i > 0; i--) {
let colorString;
// 亮色模式
if (isLight) {
colorString = tinycolor({
h,
s: Math.round((i / count) * s * 100),
v: Math.round(((i * (v - backValue)) / count + backValue) * 100),
}).toHexString();
} else {
// 暗色模式
colorString = tinycolor.mix(backgroundColor, primaryColor, i * 10).toHexString();
}
linear.push(colorString);
}
}
}
return linear;
}