返回 slidev
color.ts
根目录 / packages / client / logic / color.ts
1 import { isDark } from './dark'
2
3 /**
4 * Predefined color map for matching the branding
5 *
6 * Accpet a 6-digit hex color string or a hue number
7 * Hue numbers are preferred because they will adapt better contrast in light/dark mode
8 *
9 * Hue numbers reference:
10 * - 0: red
11 * - 30: orange
12 * - 60: yellow
13 * - 120: green
14 * - 180: cyan
15 * - 240: blue
16 * - 270: purple
17 */
18 const predefinedColorMap = {
19 error: 0,
20 client: 60,
21 Light: 60,
22 Dark: 240,
23 } as Record<string, number>
24
25 export function getHashColorFromString(
26 name: string,
27 opacity: number | string = 1,
28 ) {
29 if (predefinedColorMap[name])
30 return getHsla(predefinedColorMap[name], opacity)
31
32 let hash = 0
33 for (let i = 0; i < name.length; i++)
34 hash = name.charCodeAt(i) + ((hash << 5) - hash)
35 const hue = hash % 360
36 return getHsla(hue, opacity)
37 }
38
39 export function getHsla(
40 hue: number,
41 opacity: number | string = 1,
42 ) {
43 const saturation = hue === -1
44 ? 0
45 : isDark.value ? 50 : 100
46 const lightness = isDark.value ? 60 : 20
47 return `hsla(${hue}, ${saturation}%, ${lightness}%, ${opacity})`
48 }
49
50 export function getPluginColor(name: string, opacity = 1): string {
51 if (predefinedColorMap[name]) {
52 const color = predefinedColorMap[name]
53 if (typeof color === 'number') {
54 return getHsla(color, opacity)
55 }
56 else {
57 if (opacity === 1)
58 return color
59 const opacityHex = Math.floor(opacity * 255).toString(16).padStart(2, '0')
60 return color + opacityHex
61 }
62 }
63 return getHashColorFromString(name, opacity)
64 }
65
65 lines TYPESCRIPT