An ATproto social media client -- with an independent Appview.

feat: convenience methods

serenity 1462e156 f963e0d8

+79 -21
+18 -21
src/alf/util/colors/conversion.ts
··· 1 - export interface HslColor { 2 - h: number 3 - s: number 4 - l: number 5 - } 6 - 7 - export interface RgbColor { 8 - r: number 9 - g: number 10 - b: number 11 - } 12 - 13 - export type HexCode = `#${string}` | string 14 15 /** 16 * Converts a hexcode string in the format `"#RRGGBB"` to a `HslColor` object (`{ h: number, s: number, l: number }`). ··· 23 const r = parseInt(hex.substring(0, 2), 16) / 255 24 const g = parseInt(hex.substring(2, 4), 16) / 255 25 const b = parseInt(hex.substring(4, 6), 16) / 255 26 27 const max = Math.max(r, g, b) 28 const min = Math.min(r, g, b) ··· 57 h: h * 360, 58 s: s * 100, 59 l: l * 100, 60 } 61 } 62 ··· 67 * @returns {HexCode} A hexcode string in the format `"#RRGGBB"`. The leading "#" symbol is optional. 68 */ 69 export const hslToHex = ( 70 - {h, s, l}: HslColor, 71 appendSymbol: boolean = true, 72 ): HexCode => { 73 h = (h % 360) / 360 ··· 103 const g = hue(h) * 255 104 const b = hue(h - 1 / 3) * 255 105 106 - return `${appendSymbol ? '#' : ''}${r.toString(16)}${g.toString(16)}${b.toString(16)}` 107 } 108 109 /** ··· 113 * @returns {HexCode} A hexcode string in the format `"#RRGGBB"`. The leading "#" symbol is optional. 114 */ 115 export const rgbToHex = ( 116 - {r, g, b}: RgbColor, 117 appendSymbol: boolean = true, 118 ): HexCode => { 119 - return `${appendSymbol ? '#' : ''}${r.toString(16)}${g.toString(16)}${b.toString(16)}` 120 } 121 122 /** ··· 129 const r = parseInt(hex.substring(0, 2), 16) / 255 130 const g = parseInt(hex.substring(2, 4), 16) / 255 131 const b = parseInt(hex.substring(4, 6), 16) / 255 132 - return {r, g, b} 133 } 134 135 /** ··· 137 * @param {RgbColor} - An RGB colour object. 138 * @returns {HslColor} A HSL colour object. 139 */ 140 - export const rgbToHsl = ({r, g, b}: RgbColor): HslColor => { 141 r = r / 255 142 g = g / 255 143 b = b / 255 ··· 174 h: h * 360, 175 s: s * 100, 176 l: l * 100, 177 } 178 } 179 ··· 182 * @param {HslColor} - A HSL colour object. 183 * @returns {RgbColor} An RGB colour object. 184 */ 185 - export const hslToRgb = ({h, s, l}: HslColor): RgbColor => { 186 h = (h % 360) / 360 187 s = Math.max(0, Math.min(1, s / 100)) 188 l = Math.max(0, Math.min(1, l / 100)) ··· 216 const g = hue(h) * 255 217 const b = hue(h - 1 / 3) * 255 218 219 - return {r: Math.round(r), g: Math.round(g), b: Math.round(b)} 220 }
··· 1 + import {type HexCode, type HslColor, type RgbColor} from '#/alf/util/colors' 2 3 /** 4 * Converts a hexcode string in the format `"#RRGGBB"` to a `HslColor` object (`{ h: number, s: number, l: number }`). ··· 11 const r = parseInt(hex.substring(0, 2), 16) / 255 12 const g = parseInt(hex.substring(2, 4), 16) / 255 13 const b = parseInt(hex.substring(4, 6), 16) / 255 14 + const a = hex.length > 6 ? parseInt(hex.substring(6, 8), 16) / 255 : undefined 15 16 const max = Math.max(r, g, b) 17 const min = Math.min(r, g, b) ··· 46 h: h * 360, 47 s: s * 100, 48 l: l * 100, 49 + a, 50 } 51 } 52 ··· 57 * @returns {HexCode} A hexcode string in the format `"#RRGGBB"`. The leading "#" symbol is optional. 58 */ 59 export const hslToHex = ( 60 + {h, s, l, a}: HslColor, 61 appendSymbol: boolean = true, 62 ): HexCode => { 63 h = (h % 360) / 360 ··· 93 const g = hue(h) * 255 94 const b = hue(h - 1 / 3) * 255 95 96 + return `${appendSymbol ? '#' : ''}${r.toString(16)}${g.toString(16)}${b.toString(16)}${a ? a.toString(16) : ''}` 97 } 98 99 /** ··· 103 * @returns {HexCode} A hexcode string in the format `"#RRGGBB"`. The leading "#" symbol is optional. 104 */ 105 export const rgbToHex = ( 106 + {r, g, b, a}: RgbColor, 107 appendSymbol: boolean = true, 108 ): HexCode => { 109 + return `${appendSymbol ? '#' : ''}${r.toString(16)}${g.toString(16)}${b.toString(16)}${a ? a.toString(16) : ''}` 110 } 111 112 /** ··· 119 const r = parseInt(hex.substring(0, 2), 16) / 255 120 const g = parseInt(hex.substring(2, 4), 16) / 255 121 const b = parseInt(hex.substring(4, 6), 16) / 255 122 + const a = hex.length > 6 ? parseInt(hex.substring(6, 8), 16) / 255 : undefined 123 + return {r, g, b, a} 124 } 125 126 /** ··· 128 * @param {RgbColor} - An RGB colour object. 129 * @returns {HslColor} A HSL colour object. 130 */ 131 + export const rgbToHsl = ({r, g, b, a}: RgbColor): HslColor => { 132 r = r / 255 133 g = g / 255 134 b = b / 255 ··· 165 h: h * 360, 166 s: s * 100, 167 l: l * 100, 168 + a: a ? (a / 255) * 100 : undefined, 169 } 170 } 171 ··· 174 * @param {HslColor} - A HSL colour object. 175 * @returns {RgbColor} An RGB colour object. 176 */ 177 + export const hslToRgb = ({h, s, l, a}: HslColor): RgbColor => { 178 h = (h % 360) / 360 179 s = Math.max(0, Math.min(1, s / 100)) 180 l = Math.max(0, Math.min(1, l / 100)) ··· 208 const g = hue(h) * 255 209 const b = hue(h - 1 / 3) * 255 210 211 + return { 212 + r: Math.round(r), 213 + g: Math.round(g), 214 + b: Math.round(b), 215 + a: a ? (a / 100) * 255 : undefined, 216 + } 217 }
+61
src/alf/util/colors/index.ts
···
··· 1 + import {hexToHsl, hslToHex} from '#/alf/util/colors/conversion' 2 + 3 + export interface HslColor { 4 + h: number 5 + s: number 6 + l: number 7 + a?: number 8 + } 9 + 10 + export interface RgbColor { 11 + r: number 12 + g: number 13 + b: number 14 + a?: number 15 + } 16 + 17 + export type HexCode = `#${string}` | string 18 + 19 + export const clamp = (val: number) => { 20 + return Math.min(1, Math.max(0, val)) 21 + } 22 + 23 + export const lighten = ( 24 + hex: HexCode, 25 + amount: number, 26 + method: 'relative' | undefined = undefined, 27 + ) => { 28 + const hsl = hexToHsl(hex) 29 + 30 + if (typeof method !== 'undefined' && method === 'relative') { 31 + hsl.l += (hsl.l * amount) / 100 32 + } else { 33 + hsl.l += amount / 100 34 + } 35 + hsl.l = clamp(hsl.l) 36 + return hslToHex(hsl) 37 + } 38 + 39 + export const darken = ( 40 + hex: HexCode, 41 + amount: number, 42 + method: 'relative' | undefined = undefined, 43 + ) => { 44 + const hsl = hexToHsl(hex) 45 + 46 + if (typeof method !== 'undefined' && method === 'relative') { 47 + hsl.l -= (hsl.l * amount) / 100 48 + } else { 49 + hsl.l -= amount / 100 50 + } 51 + hsl.l = clamp(hsl.l) 52 + return hslToHex(hsl) 53 + } 54 + 55 + export const fade = (hex: HexCode, amount: number) => { 56 + const hsl = hexToHsl(hex) 57 + 58 + hsl.a = amount / 100 59 + hsl.a = clamp(hsl.a) 60 + return hslToHex(hsl) 61 + }