Notice
Recent Posts
Recent Comments
Link
반응형
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- @Moditying @Query
- 아래로펼치기
- 객체의 밸류값만 찾기
- 깃 토큰 만료
- 중첩배열평탄화
- 중복문자제거
- ubuntu타임존
- 프론트엔드 스쿨
- 단어 제거
- 재귀스왑
- 스프링 데이타 JPA
- 객체의키값만 찾기
- 중복 문자열
- 제로베이스
- 배엘에서 스왑
- sql 문자열 패턴 검색
- 5.3.8 Modifying Queries
- indexOf()
- 우분투 시간 변경
- lastIndexOf()
- 중복된 단어
- ...점점점문법
- js 문자열을 문자배열로
- 중복단어제거
- 문자열순서바꾸기
- 중첩배열
- 레디스 확인
- 시퀄 문법
- 문자열 중복
- 코딩 어?
Archives
- Today
- Total
코딩기록
색상에 따라 텍스트 배경 바꾸기 본문
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";
- W3C 접근성 기준으로 추천되는 공식 사용:
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>
...
참고
쳇지피티
반응형
'프론트 > 리액트' 카테고리의 다른 글
텍스트 커서-깜빡이는 막대기 " | " 없애기 (0) | 2025.06.26 |
---|---|
리액트, Next.js) height를 부드럽게 열고 닫는 framer-motion 라이브러리 (2) | 2025.06.26 |
Next.js) 폴더명에 []대괄호 사용- 동적라우팅 (1) | 2025.06.20 |
Carousel) Swiper(스와이퍼)- 반응형 슬라이드(캐러셀) 라이브러리 (0) | 2025.06.18 |
문법) 'use client'를 작성하는 이유- 서버 컴포넌트, 클라이언트 컴포넌트 (0) | 2025.06.11 |
Comments