goldenChat base source add

This commit is contained in:
aidev
2026-05-23 15:11:48 +09:00
commit a4ea7762b5
2081 changed files with 1155760 additions and 0 deletions
+102
View File
@@ -0,0 +1,102 @@
/** HEX · RGB · HSV 변환 (색상 팔레트 UI용) */
export interface Rgb {
r: number;
g: number;
b: number;
}
export interface Hsv {
/** 0360 */
h: number;
/** 01 */
s: number;
/** 01 */
v: number;
}
function clamp(n: number, min: number, max: number): number {
return Math.max(min, Math.min(max, n));
}
export function normalizeHex6(hex: string): string {
const h = hex.trim();
if (/^#[0-9A-Fa-f]{6}$/.test(h)) return h.toUpperCase();
if (/^#[0-9A-Fa-f]{3}$/.test(h)) {
const c = h.slice(1);
return ('#' + c[0] + c[0] + c[1] + c[1] + c[2] + c[2]).toUpperCase();
}
return '#2962FF';
}
export function hexToRgb(hex: string): Rgb {
const h = normalizeHex6(hex).slice(1);
return {
r: parseInt(h.slice(0, 2), 16),
g: parseInt(h.slice(2, 4), 16),
b: parseInt(h.slice(4, 6), 16),
};
}
export function rgbToHex(r: number, g: number, b: number): string {
const to = (n: number) => clamp(Math.round(n), 0, 255).toString(16).padStart(2, '0');
return `#${to(r)}${to(g)}${to(b)}`.toUpperCase();
}
export function rgbToHsv({ r, g, b }: Rgb): Hsv {
const rn = r / 255;
const gn = g / 255;
const bn = b / 255;
const max = Math.max(rn, gn, bn);
const min = Math.min(rn, gn, bn);
const d = max - min;
let h = 0;
if (d !== 0) {
if (max === rn) h = ((gn - bn) / d) % 6;
else if (max === gn) h = (bn - rn) / d + 2;
else h = (rn - gn) / d + 4;
h *= 60;
if (h < 0) h += 360;
}
const s = max === 0 ? 0 : d / max;
return { h, s, v: max };
}
export function hsvToRgb({ h, s, v }: Hsv): Rgb {
const c = v * s;
const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
const m = v - c;
let rp = 0;
let gp = 0;
let bp = 0;
if (h < 60) { rp = c; gp = x; }
else if (h < 120) { rp = x; gp = c; }
else if (h < 180) { gp = c; bp = x; }
else if (h < 240) { gp = x; bp = c; }
else if (h < 300) { rp = x; bp = c; }
else { rp = c; bp = x; }
return {
r: Math.round((rp + m) * 255),
g: Math.round((gp + m) * 255),
b: Math.round((bp + m) * 255),
};
}
export function hexToHsv(hex: string): Hsv {
return rgbToHsv(hexToRgb(hex));
}
export function hsvToHex(hsv: Hsv): string {
const { r, g, b } = hsvToRgb(hsv);
return rgbToHex(r, g, b);
}
/** 채도·명도 영역 배경 (hue 고정) */
export function svPanelBackground(hue: number): string {
const pure = hsvToHex({ h: hue, s: 1, v: 1 });
return `linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, ${pure})`;
}
/** 색상(Hue) 슬라이더 배경 */
export const HUE_SLIDER_BG =
'linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)';