|
| 1 | +// src/utils/array.ts |
| 2 | + |
| 3 | +export const hashString = (str: string): number => { |
| 4 | + let hash = 0; |
| 5 | + |
| 6 | + for (let i = 0; i < str.length; i++) { |
| 7 | + hash = (hash * 31 + str.charCodeAt(i)) >>> 0; |
| 8 | + } |
| 9 | + |
| 10 | + return hash; |
| 11 | +}; |
| 12 | + |
| 13 | +/** Deterministic. Enables caching in build. */ |
| 14 | +export const getRandomElementFromArrayBySeed = <T>(arr: T[], seed: string, salt = ''): T => { |
| 15 | + const hash = hashString(seed + salt); |
| 16 | + |
| 17 | + return arr[hash % arr.length]; |
| 18 | +}; |
| 19 | + |
| 20 | + |
| 21 | +import { default as twColors } from 'tailwindcss/colors'; |
| 22 | + |
| 23 | +import { getRandomElementFromArrayBySeed as rndFn } from '@/utils/array'; |
| 24 | + |
| 25 | +import type { DefaultColors } from 'tailwindcss/types/generated/colors'; |
| 26 | + |
| 27 | +type ColorKeys = keyof DefaultColors; |
| 28 | +type ShadeKeys = keyof DefaultColors[ColorKeys]; |
| 29 | + |
| 30 | +const colors = ['gray', 'indigo', 'yellow', 'blue', 'cyan', 'lime', 'sky', 'white'] as ColorKeys[]; |
| 31 | +const shades = [50, 100, 200] as ShadeKeys[]; |
| 32 | +const directions = ['to right', 'to bottom', '45deg']; |
| 33 | + |
| 34 | +// to support white |
| 35 | +// Todo: for cached build should depend on title arg |
| 36 | +const getRandomColor = (seed: string, salt: string) => { |
| 37 | + const rndColor = rndFn(colors, seed, `color-${salt}`); |
| 38 | + return rndColor === 'white' ? rndColor : twColors[rndColor][rndFn(shades, `shade-${salt}`)]; |
| 39 | +}; |
| 40 | + |
| 41 | +export const getRandomGradient = (seed: string) => |
| 42 | + `background: linear-gradient(${rndFn(directions, seed, 'direction')}, ${getRandomColor(seed, 'start')}, ${getRandomColor(seed, 'end')})`; |
| 43 | + |
| 44 | +export const grayGradient = `background: linear-gradient(to right, ${twColors.gray[100]}, ${twColors.gray[300]})`; |
| 45 | + |
0 commit comments