前言
努力学习的我,最近在看Ant Design,然后不经意间看到了Ant Design对于色彩的设计,可以通过一种主色调生成其他衍生色,而且附上了Ant Design色板生成算法演进之路这篇文章,大致意思是从简单的百分比,到贝塞尔曲线,到最终的使用HSV实现色板的过程,有兴趣的小伙伴可以自行研究吧。
由于ant design使用的是less,而我平时开发使用的是sass,所以产生了使用sass实现该算法的想法。
ant design算法
@functions: ~`(function() {
var hueStep = 2;
var saturationStep = 0.16;
var saturationStep2 = 0.05;
var brightnessStep1 = 0.05;
var brightnessStep2 = 0.15;
var lightColorCount = 5;
var darkColorCount = 4;
var getHue = function(hsv, i, isLight) {
var hue;
if (hsv.h >= 60 && hsv.h <= 240) {
hue = isLight ? hsv.h - hueStep * i : hsv.h + hueStep * i;
} else {
hue = isLight ? hsv.h + hueStep * i : hsv.h - hueStep * i;
}
if (hue < 0) {
hue += 360;
} else if (hue >= 360) {
hue -= 360;
}
return Math.round(hue);
};
var getSaturation = function(hsv, i, isLight) {
var saturation;
if (isLight) {
saturation = hsv.s - saturationStep * i;
} else if (i === darkColorCount) {
saturation = hsv.s + saturationStep;
} else {
saturation = hsv.s + saturationStep2 * i;
}
if (saturation > 1) {
saturation = 1;
}
if (isLight && i === lightColorCount && saturation > 0.1) {
saturation = 0.1;
}
if (saturation < 0.06) {
saturation = 0.06;
}
return Number(saturation.toFixed(2));
};
var getValue = function(hsv, i, isLight) {
var value;
if (isLight) {
value = hsv.v + brightnessStep1 * i;
}else{
value = hsv.v - brightnessStep2 * i
}
if (value > 1) {
value = 1;
}
return Number(value.toFixed(2))
};
this.colorPalette = function(color, index) {
var isLight = index <= 6;
var hsv = tinycolor(color).toHsv();
var i = isLight ? lightColorCount + 1 - index : index - lightColorCount - 1;
return tinycolor({
h: getHue(hsv, i, isLight),
s: getSaturation(hsv, i, isLight),
v: getValue(hsv, i, isLight),
}).toHexString();
};
})()`;
对于less,我不是很懂,但是看起来语法和js还是比较相似的,主要这里使用了tinycolor将颜色转换成hsv,然后根据得到的颜色和色板位置去生成新的hsv。
getHue是根据原有的h值生成新的h值,60度到240度是黄绿青蓝,也就是我们常说的冷色调,算法里的操作时冷色调的h随着色板依次增加,而暖色调则相反。
getSaturation是根据原有的s值生成新的s值,饱和度随着色板依次增加,只不过这里会在加深的过程中放缓
getValue是根据原有的v值生成新的v值,明度随着颜色的加深而减淡
总而言之就是h值根据冷暖色调进行不同方向的旋转,而对于sv来说,随着颜色的加深不断的增加饱和度,降低明度。
至于定义的几个值,这里也不做深究了,肯定是支付宝设计师根据千百次的测试得出的结果。
sass实现
-
定义变量和公用方法
$hueStep: 2;
$saturationStep1: 0.16;
$saturationStep2: 0.05;
$brightnessStep1: 0.05;
$brightnessStep2: 0.15;
$lightColorCount: 5;
d a r k C o l o r C o u n t : 4 ; / / 求 一 个 数 的 n 次 幂 @ f u n c t i o n p o w ( darkColorCount: 4; // 求一个数的n次幂 @function pow( darkColorCount:4;//求一个数的n次幂@functionpow(number, $n) {
$ret: 1;
@if $digits >= 0 {
@for $i from 1 through $n {
$ret: $ret * $number;
}
} @else {
@for $i from $nto 0 {
$ret: $ret / $number;
}
}
@return KaTeX parse error: Expected 'EOF', got '}' at position 6: ret; }̲ // 浮点数保留小数位 @f…float, $digits: 2) {
$pow: pow(10, d i g i t s ) ; @ r e t u r n r o u n d ( digits); @return round( digits);@returnround(float * $pow) / $pow;
} -
rgb转hsv的方法
// 根据颜色获取对应的hsv,在tinycolor中首先进行了归一化处理,这里没有
// 返回的结果h是0~360,代表的是色相的角度, sv的范围0-1
@function rbgToHsv($color) {
r e d : r e d ( red: red( red:red(color);
g r e e n : g r e