baseColor 위에 흰색을 몇 % 로 덮어야 targetColor 가 되는지 역산한다 — 합성식 결과 = 흰색·α + base·(1−α) 를 α 에 대해 푼 것1

class ColorManipulator {
  private baseColor: string
  private targetColor: string

  constructor(baseColor: string, targetColor: string) {
    this.baseColor = baseColor
    this.targetColor = targetColor
  }

  private hexToRgb(hex: string) {
    const bigint = parseInt(hex.slice(1), 16)

    return {
      r: (bigint >> 16) & 255,
      g: (bigint >> 8) & 255,
      b: bigint & 255,
    }
  }

  public calculateOpacity() {
    const target = this.hexToRgb(this.targetColor)
    const baseRG = this.hexToRgb(this.baseColor)
    const opacities = [
      (target.r - baseRG.r) / (255 - baseRG.r),
      (target.g - baseRG.g) / (255 - baseRG.g),
      (target.b - baseRG.b) / (255 - baseRG.b),
    ]
    const averageOpacity =
      opacities.reduce((sum, value) => sum + value, 0) / opacities.length

    return averageOpacity
  }

  public getCssRGBA() {
    const opacity = this.calculateOpacity()

    return `rgba(255, 255, 255, ${opacity.toFixed(2)})` // 덮는 색은 흰색
  }
}

const manipulator = new ColorManipulator('#000000', '#D1D7DE')
const opacity = manipulator.calculateOpacity()
const cssRGBA = manipulator.getCssRGBA() // rgba(255, 255, 255, 0.84)

채널별 α 가 다르면(여기선 0.82·0.84·0.87) 평균 하나로는 정확히 못 맞춘다 — 검정 위 흰색 0.84 는 rgb(214, 214, 214), 목표는 rgb(209, 215, 222).


Footnotes

  1. Compositing and Blending Level 1 §5.1 Simple alpha compositing - W3C: “co = Cs x αs + Cb x αb x (1 - αs)” — 바탕이 불투명(αb = 1)이면 Cs·α + Cb·(1−α). ↩

#341