Author: Simon Pieters
Users want to be able to pick a color from the screen, e.g. in a painting or photo editor web app in order to use a color from the current canvas/photo or possibly from another application. Typically this is done with a button to activate “eyedropper mode” where the cursor becomes an eyedropper to pick a color. Existing web APIs don’t provide a way to read pixel data outside of <canvas>.
Research the UX of existing eyedropper color selectors in native apps and web apps. Is it activated from a button, keyboard shortcut, etc? Is it closed when a color is picked, or stays open? How are non-sRGB colors handled? Can colors outside the viewport be picked? Are colors picked continuously while hovering, or only when clicking? Make sure the proposed solution is sufficiently rich to be adopted, but also doesn’t introduce privacy or security issues.
The proposed solution should be such that it does not duplicate effort when improving aspects of other color features, e.g. wide gamut for <input type=color>. Ideally, the proposed solution will build on and work with existing color features in the platform.
The proposed solution should be easy to use and style declaratively without needing to implement a custom button with JS, and advance our vision for the Declarative Web.
Proposal: <input type=color> hint for eyedropper-only was filed in May 2020, and is essentially the same as the proposal in this explainer.
The EyeDropper API proposal was created in August 2020, which was moved to WICG in August 2021. The <input type=color> proposal was closed without further discussion. Chromium shipped EyeDropper API in M95.
iam-medvedev/eyedropper-polyfill is a JS-based polyfill for the EyeDropper API.
Building a wide-gamut colour picker is a JS-based color picker with P3 support (not an eyedropper).
The EyeDropper API only supports sRGB. <input type=color> also currently only supports sRGB, but there’s an issue to add wide-gamut support.
The EyeDropper API has no declarative button built-in.
See Consider extending <input type=color> instead.
Minimal HTML example:
<input type=color eyedropper onchange="setPaintColor(this.value)">
Existing EyeDropper API code would continue to work (assuming no renaming), but the constructor would create an <input type=color eyedropper> element.
// Create an EyeDropper object (<input type=color eyedropper>)
let eyeDropper = new EyeDropper();
// Enter eyedropper mode
let icon = document.getElementbyId("eyeDropperIcon")
icon.addEventListener('click', e => {
eyeDropper.open()
.then(colorSelectionResult => {
// returns hex color value (#RRGGBB) of the selected pixel
console.log(colorSelectionResult.sRGBHex);
})
.catch(error => {
// handle the user choosing to exit eyedropper mode without a selection
});
});
The “open” method is a bit generic for HTMLInputElement. Maybe it can be renamed?
<input> is mainly event-based, and the current EyeDropper API is promise-based. Is it reasonable to do both?
The EyeDropper API uses [SecureContext], which might be hard with <input>. Is it needed?
To be written.
Incubation could be in WICG/eyedropper-api, standardization in WHATWG HTML.