개인 프로젝트 super easy는 자주 쓰는 디자인 리소스를 저장하고, 어디서든 복사 붙여넣기하여 편리하게 사용할 수 있는 웹 사이트입니다.
저장된 컴포넌트를 클릭하여 css 스타일링 코드를 클립보드에 복사할 수 있습니다. 오늘은 Colours
탭에 기능을 개선한 부분에 대해 기록해보려 합니다.
Colours
기능은 간단합니다. 사용자가 원하는 색상을 추가하면 추가된 색상의 brightness를 조절하여 variation을 출력해주는 기능입니다.
가령 프로젝트의 primary-color
를 #aa1231
로 정했다고 예를 들면,
해당 컬러를 등록하여 등록된 컬러의 variation을 아래와 같이 보여줍니다.
사용자가 등록한 원본의 컬러는 Hex Code로 잘 출력이 됩니다. 다른 variation들은 원본 값에 filter: brightness();
를 추가하여 출력합니다. 그런데 사용자는 원본 값을 제외한 variation의 컬러 Hex code를 알 수 없습니다. 해당 컬러 팔레트를 클릭하여 클립보드에 복사하면 아래와 같은 값이 복사됩니다.
color: #aa1231;
filter: brightness(1.2);
사용자는 원하는 색상을 사용할 순 있지만 그 색상의 Hex code는 알 방법이 없습니다. 게다가 color
를 두가지 속성으로 제어하기 때문에 코드의 가독성도 떨어질 것으로 예상했습니다.
그래서 color에 brightness를 더하여 새로운 Hex code를 반환하는 기능을 만들기로 계획했습니다!
image processing algorithm에서 착안하였습니다. 방법은 아래와 같습니다.
colour = GetPixelColour(x, y)
newRed = Truncate(Red(colour) + brightness)
newGreen = Truncate(Green(colour) + brightness)
newBlue = Truncate(Blue(colour) + brightness)
PutPixelColour(x, y) = RGB(newRed, newGreen, newBlue)
위 방법은 RGB 표현법을 기반으로 하고 있습니다. 주의 깊게 봐야하는 것은 brightness
입니다. RGB 값에 brightness를 더해서 새로운 RGB 값을 반환하는 방식입니다. 그렇다면 brightness는 0 ~ 255
값을 가질 것으로 예상할 수 있습니다.
Super easy로 돌아오겠습니다. Super easy에서는 사용자에게 RGB 값이 아닌 Hex 값을 받고 있습니다. 받은 Hex값을 RGB로 변환하는 것이 첫 단계입니다. 코드는 아래와 같습니다.
const tmp = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
정규식을 사용하여 RGB 코드를 반환합니다.
여기서 주의할 점은 hex코드는
#000
처럼 3자리로 만들어 질 수 있지만, 위 정규식은#000000
과 같이 6자리의 hex code만 반환 가능하기 때문에 세자리의 hex code 입력을 방지하였습니다.
이후 변환함수 전문입니다.
export const addBrightness = (hex, brightness) => {
const tmp = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
const result = {
r:
Math.trunc(parseInt(tmp[1], 16) * brightness) > 255
? 255
: Math.trunc(parseInt(tmp[1], 16) * brightness) < 0
? 0
: Math.trunc(parseInt(tmp[1], 16) * brightness),
g:
Math.trunc(parseInt(tmp[2], 16) * brightness) > 255
? 255
: Math.trunc(parseInt(tmp[2], 16) * brightness) < 0
? 0
: Math.trunc(parseInt(tmp[2], 16) * brightness),
b:
Math.trunc(parseInt(tmp[3], 16) * brightness) > 255
? 255
: Math.trunc(parseInt(tmp[3], 16) * brightness) < 0
? 0
: Math.trunc(parseInt(tmp[3], 16) * brightness),
};
return rgbToHex(result.r, result.g, result.b);
};
추출한 RGB를 이용하여 새로운 RGB 값을 만들어내는 과정입니다. 여기서 주의 깊게 봐야하는 부분은 brightness
입니다. css에서는 brightness를 0 ~ 255
의 정수 값이 아닌 퍼센트 값으로 계산합니다.
따라서 image processing algorithms의 계산과는 다르게 여기선 brighness를 곱하여 계산합니다. RGB의 값은 0 ~ 255
이기 때문에 예외처리도 해주었습니다. Math.trunc
는 소수점을 제거하고 정수부분만 반환하는 함수입니다.
마지막으로 rgbToHex
는 아래와 같습니다.
const componentToHex = (color) => {
const hex = color.toString(16);
return hex.length === 1 ? "0" + hex : hex;
};
export const rgbToHex = (r, g, b) => {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
};
addBrightness
함수의 반환값을 사용하여 variation에 모두 hex code로 라벨링이 가능해졌습니다.
반환된 새로운 hex code가 의도한대로 잘 나왔는지 확인을 위해 adobe XD를 이용했습니다.
컬러가 미세하게 다른 것이 느껴지시나요?
밝은 색상 뿐 아니라 어두운 색상에서도 미세히 차이를 보이고 있습니다.
스포이드 기능을 사용하여 원본 색상을 복사하면 위와 같이 다른 hex code를 같은 색으로 인지합니다.
하지만 걱정하지 않아도 됩니다. 웹에서는 sRGB color space
를 사용하는 반면에 design software에서는 raw color space
를 사용하기 때문에 생기는 문제입니다.
쉽게 말해 웹에서의 #ff1c4e
는 xd에서의 #ea3b53
과 같은 색상입니다.
이제 사용자가 color를 지정하여 등록하면 variation을 hex code로 나타낼 수 있습니다. 또한 원하는 color palette를 클릭하여 hex code를 클립보드에 복사할 수 있게 되었습니다.