diff --git a/src/index-fn.js b/src/index-fn.js index 2713901a8..ecb79d889 100644 --- a/src/index-fn.js +++ b/src/index-fn.js @@ -15,6 +15,7 @@ export {default as inGamut} from "./inGamut.js"; export {default as toGamut} from "./toGamut.js"; export {default as distance} from "./distance.js"; export {default as equals} from "./equals.js"; +export {default as over} from "./over.js"; export {default as contrast} from "./contrast.js"; export {default as clone} from "./clone.js"; export { diff --git a/src/index.js b/src/index.js index ae4abf24f..01c6607f6 100644 --- a/src/index.js +++ b/src/index.js @@ -15,6 +15,9 @@ Color.extend(deltaE); import * as variations from "./variations.js"; Color.extend(variations); +import over from "./over.js"; +Color.extend(over); + import contrast from "./contrast.js"; Color.extend(contrast); diff --git a/src/over.js b/src/over.js new file mode 100644 index 000000000..22193fbe8 --- /dev/null +++ b/src/over.js @@ -0,0 +1,47 @@ +import getColor from "./getColor.js"; +import ColorSpace from "./space.js"; +import xyz_d65 from "./spaces/xyz-d65.js"; +import to from "./to.js"; + +export default function over (source, backdrop, { + space = xyz_d65, + outputSpace = source.space, +} = {}) { + source = getColor(source); + backdrop = getColor(backdrop); + + space = ColorSpace.get(space); + outputSpace = ColorSpace.get(outputSpace); + + if (space.isPolar) { + throw new Error("Compositing in polar color spaces is not supported."); + } + + let result; + + if (source.alpha === 0) { + result = backdrop; + } + else if (source.alpha === 1 || backdrop.alpha === 0) { + result = source; + } + else { + let source_xyz = to(source, space); + let backdrop_xyz = to(backdrop, space); + + result = { + space, + coords: source_xyz.map((s, i) => { + let b = backdrop_xyz[i]; + return s + b * (1 - source.alpha); + }), + alpha: source.alpha + backdrop.alpha * (1 - source.alpha) + } + } + + return to(result, outputSpace); +} + +export function register (Color) { + Color.defineFunction("over", over, {returns: "color"}); +} \ No newline at end of file diff --git a/types/src/over.d.ts b/types/src/over.d.ts new file mode 100644 index 000000000..7eabcc12d --- /dev/null +++ b/types/src/over.d.ts @@ -0,0 +1,12 @@ +import Color, { ColorTypes } from "./color"; + +export interface OverOptions { + space?: string | ColorSpace | undefined; + outputSpace?: string | ColorSpace | undefined; +} + +export function over( + source: ColorTypes, + backdrop: ColorTypes, + options?: OverOptions +) : ColorTypes \ No newline at end of file