import { internalRoundColorFloat } from "../internal.ts" import type { XyChromaticityValue, XyzColorValue } from "../types.ts" import { createXyzColorValue } from "./construct.ts" const internalGetNormalizedXyzColorData = ( color: XyzColorValue, ): { color: XyzColorValue; tristimulusSum: number } => { const normalizedColor = createXyzColorValue(color) const tristimulusSum = internalRoundColorFloat( normalizedColor.x + normalizedColor.y + normalizedColor.z, ) return { color: normalizedColor, tristimulusSum, } } /** * @description 读取 XYZ 颜色值的相对亮度。 * * 在当前模块约定下,`Y` 通道直接表示相对亮度。 * * @example * ``` * // Expect: 0.3 * const example1 = xyzColorValueToRelativeLuminance({ x: 0.25, y: 0.3, z: 0.4, alpha: 1 }) * * // Expect: 0 * const example2 = xyzColorValueToRelativeLuminance({ x: 0, y: 0, z: 0, alpha: 1 }) * ``` */ export const xyzColorValueToRelativeLuminance = (color: XyzColorValue): number => { return createXyzColorValue(color).y } /** * @description 读取 XYZ 颜色值的三刺激总量。 * * 在当前模块约定下,结果等于 `x + y + z`。 * * @example * ``` * // Expect: 0.95 * const example1 = xyzColorValueToTristimulusSum({ x: 0.25, y: 0.3, z: 0.4, alpha: 1 }) * * // Expect: 0 * const example2 = xyzColorValueToTristimulusSum({ x: 0, y: 0, z: 0, alpha: 1 }) * ``` */ export const xyzColorValueToTristimulusSum = (color: XyzColorValue): number => { return internalGetNormalizedXyzColorData(color).tristimulusSum } /** * @description 读取 XYZ 颜色值对应的 `xy` 色度坐标。 * * 当三刺激总量为 `0` 时,该结果没有定义,因此会抛出异常。 * * @example * ``` * // Expect: { x: 0.263158, y: 0.315789 } * const example1 = xyzColorValueToXyChromaticityValue({ x: 0.25, y: 0.3, z: 0.4, alpha: 1 }) * * // Expect: { x: 0.64, y: 0.33 } * const example2 = xyzColorValueToXyChromaticityValue({ x: 0.412456, y: 0.212673, z: 0.019334, alpha: 1 }) * ``` */ export const xyzColorValueToXyChromaticityValue = (color: XyzColorValue): XyChromaticityValue => { const normalizedData = internalGetNormalizedXyzColorData(color) if (normalizedData.tristimulusSum === 0) { throw new RangeError("XYZ tristimulus sum must be greater than 0 to compute xy chromaticity") } return { x: internalRoundColorFloat(normalizedData.color.x / normalizedData.tristimulusSum), y: internalRoundColorFloat(normalizedData.color.y / normalizedData.tristimulusSum), } }