logo

Juniverse Dev

Color System Generator 코드 도슨트

Color System Generator 코드 도슨트

디자인을 위한 컬러 팔레트를 찾던 중, 색상의 변형까지 제공하는 팔레트가 부족하다는 문제를 발견했다. 이를 해결하기 위해 직접 Color System Generator를 개발하게 되었고, 색상의 밝기 변화를 조절하는 기능을 구현했다. 이제, 이 코드의 동작 방식에 대해 살펴본다.

TypescriptReact.js
30 views

며칠 전, 진행해 보고 싶은 프로젝트 아이디어가 떠올랐다. 디자인을 먼저 잡기 위해 컬러 팔레트를 찾아보았는데, 단순한 색 조합뿐만 아니라 색상의 밝기 변화를 포함한 색 변형(Variation)까지 함께 필요했다.

하지만 무료 사이트에서는 원하는 기능을 제공하는 곳을 찾기 어려웠고, 결국 직접 만들어야겠다는 결론을 내렸다.

그렇게 개발된 것이 바로 Color System Generator이다.

이제, 이 프로젝트의 핵심 코드들을 하나씩 살펴보자.

 

Repository

 

hexToRgb

16진수로된 Hex 코드를 RGB로 변환하는 함수

 

    const hexToRgb = (hex: string): [number, number, number] => {
        hex = hex.replace(/^#/, "");
        const bigint = parseInt(hex, 16);
        return [(bigint >> 16) & 255, (bigint >> 8) & 255, bigint & 255];
    }

예를 들어, #AD83EC을 입력하면

결과적으로 [R, G, B] 를 리턴하게 된다.

 

adjustBrightness

주어진 색에서 factor 값에 따라 더 밝게 혹은 더 어둡게 조정

const adjustBrightness = ([r, g, b]: number[], factor: number, isBrighter: boolean) => {
    return isBrighter
        ? [
            Math.min(255, Math.round(r + (255 - r) * factor)),
            Math.min(255, Math.round(g + (255 - g) * factor)),
            Math.min(255, Math.round(b + (255 - b) * factor)),
        ]
        : [
            Math.max(0, Math.round(r * factor + 10)),
            Math.max(0, Math.round(g * factor + 10)),
            Math.max(0, Math.round(b * factor + 10)),
        ];
}

 

generateColorScale

주어진 hex 코드를 기준으로 색 바리데이션 생성

const generateColorScale = (baseHex: string): string[] => {
        const baseRgb = hexToRgb(baseHex);

        if (baseHex.toUpperCase() === "#000000") {
            return [
                "#E0E0E0",
                "#C0C0C0",
                "#A0A0A0",
                "#808080",
                "#606060",
                "#404040",
                "#303030",
                "#202020",
                "#101010"
            ]
        }

        if (baseHex.toUpperCase() === "#FFFFFF") {
            return [
                "#FFFFFF",
                "#E6E6E6",
                "#CCCCCC",
                "#B3B3B3",
                "#999999",
                "#808080",
                "#666666",
                "#4D4D4D",
                "#333333"
            ]
        }

        const scale = [];
        for (let step = 100; step <= 900; step += 100) {
            let factor;
            let isBrighter;

            if (step <= 500) {
                factor = (500 - step) / 500;
                isBrighter = true;
            } else {
                factor = (900 - step) / 500 + 0.1;
                isBrighter = false;
            }

            scale.push(rgbToHex(adjustBrightness(baseRgb as [number, number, number], factor, isBrighter)));
        }

        return scale;
    }

검은색(#000000) 이나 흰색(#FFFFFF) 일 경우 더 어두운색이나 더 밝은 색을 생성하는것은 불가능 하므로 미리 정해둔 컬러 시스템을 반환한다.

100~900, 총 9개의 컬러 바리데이션을 생성

rgbToHex

RGB 배열을 hex 코드로 변환

const rgbToHex = ([r, g, b]: number[]) => {
    return `#${((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1).toUpperCase()}`;
}

 

결과

 

JSON 으로 복사 시

{
            "red": {
                "100": "#FFCCCC",
                "200": "#FF9999",
                "300": "#FF6666",
                "400": "#FF3333",
                "500": "#FF0000",
                "600": "#BD0A0A",
                "700": "#8A0A0A",
                "800": "#570A0A",
                "900": "#240A0A"
            },
            "green": {
                "100": "#CCFFCC",
                "200": "#99FF99",
                "300": "#66FF66",
                "400": "#33FF33",
                "500": "#00FF00",
                "600": "#0ABD0A",
                "700": "#0A8A0A",
                "800": "#0A570A",
                "900": "#0A240A"
            },
            "blue": {
                "100": "#CCCCFF",
                "200": "#9999FF",
                "300": "#6666FF",
                "400": "#3333FF",
                "500": "#0000FF",
                "600": "#0A0ABD",
                "700": "#0A0A8A",
                "800": "#0A0A57",
                "900": "#0A0A24"
            }
}