코딩기록

색상에 따라 텍스트 배경 바꾸기 본문

프론트/리액트

색상에 따라 텍스트 배경 바꾸기

뽀짝코딩 2025. 6. 20. 20:53
728x90

 

 

 

아래 코드에서 getTextColor(color: string) 함수는 주어진 color가 밝은 색인지 어두운 색인지 판단해서 텍스트 색상을 흰색(white) 또는 검정(black)으로 자동 결정해주는 함수.


✅ 1단계: 준비 (초기값 및 색상 테이블 정의)

let r = 0, g = 0, b = 0;
const lowerColor = color.toLowerCase();
  • 입력값 color를 소문자로 바꿔서 처리 (대소문자 구분 없이 일치 확인하기 위해).
  • RGB 기본값은 (0, 0, 0)으로 초기화.

✅ 2단계: named color 처리

if (namedColors[lowerColor]) {
  [r, g, b] = namedColors[lowerColor];
}
  • namedColors는 CSS에서 쓰는 "blue", "navy" 같은 이름을 RGB 값으로 바꿔주는 사전.
  • 만약 color가 "blue"면 [0, 0, 255]를 가져와서 r, g, b에 할당.

✅ 3단계: HEX 코드 처리 (#rrggbb 또는 #rgb)

else if (color.startsWith("#")) {
  const hex = color.slice(1); // # 제거
  const fullHex = hex.length === 3
    ? hex.split("").map((c) => c + c).join("") // #fff → #ffffff
    : hex.padEnd(6, "0"); // 부족한 경우 뒷자리 채움

  const bigint = parseInt(fullHex, 16);
  r = (bigint >> 16) & 255;
  g = (bigint >> 8) & 255;
  b = bigint & 255;
}
  • HEX 코드일 경우 문자열을 파싱하여 16진수 → 10진수 RGB로 변환
  • 예: #ff0000 → R: 255, G: 0, B: 0

✅ 4단계: rgb(r,g,b) 포맷 처리

else if (color.startsWith("rgb")) {
  const match = color.match(/\d+/g);
  if (match) {
    [r, g, b] = match.map(Number);
  }
}
  • color가 "rgb(0, 0, 255)"처럼 생겼다면 정규식으로 숫자만 뽑아서 r, g, b로 변환.

✅ 5단계: canvas fallback (브라우저에서만 실행됨)

else if (typeof window !== "undefined") {
  const ctx = document.createElement("canvas").getContext("2d");
  if (ctx) {
    ctx.fillStyle = color; // 색상 이름 또는 기타 문자열
    const match = ctx.fillStyle.match(/\d+/g);
    if (match) {
      [r, g, b] = match.map(Number);
    }
  }
}
  • 만약 위 3단계에도 해당하지 않는 값이면 canvas를 이용해 브라우저가 파싱한 실제 색상으로 변환.
  • "skyblue", "hotpink" 같은 CSS 내장 색상 이름을 처리할 수 있음.
  • ctx.fillStyle을 통해 브라우저가 해석한 색상 문자열(rgb(...))을 추출하고 숫자만 파싱.

✅ 6단계: 밝기(brightness) 계산 및 텍스트 색상 결정

const brightness = (r * 299 + g * 587 + b * 114) / 1000;
return brightness < 186 ? "white" : "black";
Brightness = (R * 299 + G * 587 + B * 114) / 1000
  • 밝기가 186보다 작으면 어두운 배경 → 텍스트는 "white"
  • 밝기가 186 이상이면 밝은 배경 → 텍스트는 "black"

✅ 마지막으로 export

export default getTextColor;
  • getTextColor를 다른 파일에서 import 해서 사용할 수 있도록 기본 내보내기(export).

🎯 이 함수의 진짜 장점

  • "red", "blue"처럼 CSS에서 허용하는 색상 이름 지원
  • #hex, rgb() 포맷도 지원
  • 밝기에 따라 텍스트 색상을 자동으로 반전
  • canvas까지 활용해서 대부분의 CSS 색상 처리 가능

 

 

적용

  interface ItemDetailProps {
  productId: string;
}


  const ItemDetail = ({ productId }: ItemDetailProps) => {
  const item = cartItemList.find((item) => item.id === productId);

  // ✅ item이 있으면 color[0], 없으면 빈 문자열
  const [selectedColor, setSelectedColor] = useState(item?.color[0] || "");
  const [isOpenColor, setIsOpenColor] = useState(false);

  if (!item) {
    return <div className="p-4">해당 상품을 찾을 수 없습니다.</div>;
  }

  {/* 색상 선택 */}
  <div className="flex flex-row p-2">
    <span className=" mr-4">색상</span>

    <div className="relative inline-block text-left">
      <div
        style={{ backgroundColor: selectedColor, color: getTextColor(selectedColor) }}
        onClick={() => setIsOpenColor((prev) => !prev)}
        className={`outline-none text-base border px-4 py-2 rounded cursor-pointer min-w-[100px] `}
      >
        {selectedColor}
      </div>

      {isOpenColor && (
        <ul className="absolute mt-1 border rounded bg-white z-10">
          {item.color.map((color) => (
            <li
              key={color}
              onClick={() => {
                setSelectedColor(color);
                setIsOpenColor(false);
              }}
              className={`px-3 py-2 cursor-pointer hover:opacity-80`}
              style={{ backgroundColor: color, color: getTextColor(color) }}
            >
              {color}
            </li>
          ))}
        </ul>
      )}
    </div>
  </div>
  
  ...

 

 

 

 

 

 

 

참고

쳇지피티

반응형
Comments