Skip to content
On this page

2022-08-如何hover的时候让它本来的颜色变亮

1. 需求场景

前端设计的时候,一般鼠标hover上去之后,都会有一定的效果以示区别。最简单的两种方式

jsx
a:hover{
  opacity: 0.8;
}
jsx
a:hover{
  transform: scale(0.96)
}

但是opacity用0.8会让文字看起来很暗,实际我们需要的是使他变亮。

2. 参考antd的设计

https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less

jsx
@primary-color: @blue-6;
@primary-color-hover: color(~`colorPalette('@{primary-color}', 5) `);
@primary-color-active: color(~`colorPalette('@{primary-color}', 7) `);

可以看到antd用less定义颜色的时候,hover的颜色是用colorPalette这个less函数做了处理,让他变亮。

https://github.com/ant-design/ant-design/blob/master/components/style/color/colorPalette.less

jsx
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();
};

大概的思路就是,先把颜色值按照一定算法算错H(Hue-色调)、S(Saturation-饱和度)、V(value-明亮度)的单独值。 hsv是一种描述颜色的表示值,同rgb类似。 如果是变亮,就单独的把明亮度调大,把其他两个值也做一定换算,得到新的HSV,再通过tinyColor把HSV换算成十六进制的形式,供我们使用。

jsx
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);
};
jsx
var getSaturation = function(hsv, i, isLight) {
  // grey color don't change saturation
  if (hsv.h === 0 && hsv.s === 0) {
    return hsv.s;
  }
  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));
};
jsx
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))
};

Released under the MIT License.