UNPKG

@_lan/web-libs

Version:

<div align="center"> <img src="./public/favicon.svg" width="160" /> <h1>SoybeanAdmin AntDesign</h1> <span>中文 | <a href="./README.en_US.md">English</a></span> </div>

153 lines (118 loc) 3.85 kB
import { getColorName, getDeltaE, getHsl, isValidColor, transformHslToHex } from '../shared'; import { colorPalettes } from '../constant'; import type { ColorPalette, ColorPaletteFamily, ColorPaletteFamilyWithNearestPalette, ColorPaletteMatch, ColorPaletteNumber } from '../types'; /** * get recommended color palette by provided color * * @param color the provided color */ export function getRecommendedColorPalette(color: string) { const colorPaletteFamily = getRecommendedColorPaletteFamily(color); const colorMap = new Map<ColorPaletteNumber, ColorPalette>(); colorPaletteFamily.palettes.forEach(palette => { colorMap.set(palette.number, palette); }); const mainColor = colorMap.get(500)!; const matchColor = colorPaletteFamily.palettes.find(palette => palette.hex === color)!; const colorPalette: ColorPaletteMatch = { ...colorPaletteFamily, colorMap, main: mainColor, match: matchColor }; return colorPalette; } /** * get recommended palette color by provided color * * @param color the provided color * @param number the color palette number */ export function getRecommendedPaletteColorByNumber(color: string, number: ColorPaletteNumber) { const colorPalette = getRecommendedColorPalette(color); const { hex } = colorPalette.colorMap.get(number)!; return hex; } /** * get color palette family by provided color and color name * * @param color the provided color */ export function getRecommendedColorPaletteFamily(color: string) { if (!isValidColor(color)) { throw new Error('Invalid color, please check color value!'); } let colorName = getColorName(color); colorName = colorName.toLowerCase().replace(/\s/g, '-'); const { h: h1, s: s1 } = getHsl(color); const { nearestLightnessPalette, palettes } = getNearestColorPaletteFamily(color, colorPalettes); const { number, hex } = nearestLightnessPalette; const { h: h2, s: s2 } = getHsl(hex); const deltaH = h1 - h2; const sRatio = s1 / s2; const colorPaletteFamily: ColorPaletteFamily = { name: colorName, palettes: palettes.map(palette => { let hexValue = color; const isSame = number === palette.number; if (!isSame) { const { h: h3, s: s3, l } = getHsl(palette.hex); const newH = deltaH < 0 ? h3 + deltaH : h3 - deltaH; const newS = s3 * sRatio; hexValue = transformHslToHex({ h: newH, s: newS, l }); } return { hex: hexValue, number: palette.number }; }) }; return colorPaletteFamily; } /** * get nearest color palette family * * @param color color * @param families color palette families */ function getNearestColorPaletteFamily(color: string, families: ColorPaletteFamily[]) { const familyWithConfig = families.map(family => { const palettes = family.palettes.map(palette => { return { ...palette, delta: getDeltaE(color, palette.hex) }; }); const nearestPalette = palettes.reduce((prev, curr) => (prev.delta < curr.delta ? prev : curr)); return { ...family, palettes, nearestPalette }; }); const nearestPaletteFamily = familyWithConfig.reduce((prev, curr) => prev.nearestPalette.delta < curr.nearestPalette.delta ? prev : curr ); const { l } = getHsl(color); const paletteFamily: ColorPaletteFamilyWithNearestPalette = { ...nearestPaletteFamily, nearestLightnessPalette: nearestPaletteFamily.palettes.reduce((prev, curr) => { const { l: prevLightness } = getHsl(prev.hex); const { l: currLightness } = getHsl(curr.hex); const deltaPrev = Math.abs(prevLightness - l); const deltaCurr = Math.abs(currLightness - l); return deltaPrev < deltaCurr ? prev : curr; }) }; return paletteFamily; }