From 38cf4a8d7a31f2e0a9628f85df594141555c26f6 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Wed, 21 Aug 2024 17:56:42 -0600 Subject: [PATCH] raster colorSpace --- docs/marks/raster.md | 3 ++- src/marks/raster.d.ts | 8 ++++++++ src/marks/raster.js | 4 +++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/marks/raster.md b/docs/marks/raster.md index ae1c8cf11a..bcf506dfcd 100644 --- a/docs/marks/raster.md +++ b/docs/marks/raster.md @@ -286,11 +286,12 @@ If **width** is specified, **x1** defaults to 0 and **x2** defaults to **width** The following raster-specific constant options are supported: +* **colorSpace** - the [color space](https://developer.mozilla.org/en-US/docs/Web/API/ImageData/colorSpace) * **interpolate** - the [spatial interpolation method](#spatial-interpolators) * **imageRendering** - the [image-rendering attribute](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/image-rendering); defaults to *auto* (bilinear) * **blur** - a non-negative pixel radius for smoothing; defaults to 0 -The **imageRendering** option may be set to *pixelated* for a sharper image. The **interpolate** option is ignored when **fill** or **fillOpacity** is a function of *x* and *y*. +The **colorSpace** may be set to *display-p3* for the Display P3 color space. The **imageRendering** option may be set to *pixelated* for a sharper image. The **interpolate** option is ignored when **fill** or **fillOpacity** is a function of *x* and *y*. ## raster(*data*, *options*) {#raster} diff --git a/src/marks/raster.d.ts b/src/marks/raster.d.ts index 8a1a9248d6..d9795208ae 100644 --- a/src/marks/raster.d.ts +++ b/src/marks/raster.d.ts @@ -145,6 +145,14 @@ export interface RasterOptions extends Omit */ imageRendering?: string; + /** + * The [color space][1] of the backing canvas. Defaults to *srgb*; set to + * *display-p3* for the Display P3 color space. + * + * [1]: https://developer.mozilla.org/en-US/docs/Web/API/ImageData/colorSpace + */ + colorSpace?: "srgb" | "display-p3" | string; + /** * The fill, typically bound to the *color* scale. Can be specified as a * constant, a channel based on the sample *data*, or as a function *f*(*x*, diff --git a/src/marks/raster.js b/src/marks/raster.js index 2d5662ede7..2e6c4369aa 100644 --- a/src/marks/raster.js +++ b/src/marks/raster.js @@ -36,6 +36,7 @@ export class AbstractRaster extends Mark { y1 = y == null ? 0 : undefined, x2 = x == null ? width : undefined, y2 = y == null ? height : undefined, + colorSpace = "srgb", pixelSize = defaults.pixelSize, blur = 0, interpolate @@ -79,6 +80,7 @@ export class AbstractRaster extends Mark { this.pixelSize = number(pixelSize, "pixelSize"); this.blur = number(blur, "blur"); this.interpolate = x == null || y == null ? null : maybeInterpolate(interpolate); // interpolation requires x & y + this.colorSpace = String(colorSpace); } } @@ -129,7 +131,7 @@ export class Raster extends AbstractRaster { const canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; - const context2d = canvas.getContext("2d"); + const context2d = canvas.getContext("2d", {colorSpace: this.colorSpace}); const image = context2d.createImageData(w, h); const imageData = image.data; let {r, g, b} = rgb(this.fill) ?? {r: 0, g: 0, b: 0};