使用 EyeDropper API 选择屏幕上任何像素的颜色

借助 EyeDropper API,作者可以在构建自定义颜色选择器时使用浏览器提供的取色器。

什么是 EyeDropper API?

许多创意应用都允许用户从应用窗口的各个部分甚至整个屏幕中选择颜色,通常使用滴管隐喻。

例如,Photoshop 可让用户从画布中采样颜色,这样他们就不必猜测颜色,以免出错。PowerPoint 还提供取色器工具,在设置形状的轮廓或填充颜色时非常有用。即使是 Chromium DevTools,也有一个取色器,您可以在 CSS 样式面板中编辑颜色时使用它,这样您就不必记住或从其他位置复制颜色代码。

如果您正在使用 Web 技术构建创意应用,可能需要为用户提供类似的功能。不过,在 Web 上实现这一点非常困难(如果可能的话),尤其是当您想要从整个设备屏幕(例如,从其他应用)而非仅从当前浏览器标签页中采样颜色时。没有浏览器提供的取色器工具可供 Web 应用根据自身需求使用。

<input type="color"> 元素与之类似。在桌面设备上运行的基于 Chromium 的浏览器中,它会在颜色选择器下拉菜单中提供实用的取色器。不过,使用此方法意味着您的应用必须使用 CSS 对其进行自定义,并将其封装在一些 JavaScript 中,以便供应用的其余部分使用。选择此方法还意味着其他浏览器将无法使用该功能。

EyeDropper API 通过提供一种从屏幕中采样颜色的方式来填补这一空白。

Chromium 颜色选择器。

如何使用 EyeDropper API

浏览器支持

Browser Support

  • Chrome: 95.
  • Edge: 95.
  • Firefox: not supported.
  • Safari: not supported.

Source

功能检测和浏览器支持

首先,请确保该 API 可用,然后再使用它。

if ('EyeDropper' in window) {
  // The API is available!
}

自版本 95 起,基于 Chromium 的浏览器(如 Edge 或 Chrome)支持 EyeDropper API。

使用 API

如需使用该 API,请创建一个 EyeDropper 对象,然后调用其 open() 方法。

const eyeDropper = new EyeDropper();

open() 方法会返回一个 promise,该 promise 会在用户选择屏幕上的某个像素后解析,并且解析后的值会提供对该像素颜色的 sRGBHex 格式 (#RRGGBB) 的访问权限。如果用户按 esc 键离开滴管模式,则该 promise 会被拒绝。

try {
  const result = await eyeDropper.open();
  // The user selected a pixel, here is its color:
  const colorHexValue = result.sRGBHex;
} catch (err) {
  // The user escaped the eyedropper mode.
}

应用的相应代码也可以取消取色器模式。如果应用的状态发生重大变化,这会非常有用。可能会显示一个弹出式对话框,要求用户输入内容。此时,取色器模式应停止。

如需取消取色器,您可以使用 AbortController 对象的信号并将其传递给 open() 方法。

const abortController = new AbortController();

try {
  const result = await eyeDropper.open({signal: abortController.signal});
  // ...
} catch (err) {
  // ...
}

// And then later, when the eyedropper mode needs to be stopped:
abortController.abort();

综合来看,您可以在下方找到一个可重复使用的异步函数:

async function sampleColorFromScreen(abortController) {
  const eyeDropper = new EyeDropper();
  try {
    const result = await eyeDropper.open({signal: abortController.signal});
    return result.sRGBHex;
  } catch (e) {
    return null;
  }
}

试试看!

在 Windows 或 Mac 上,使用 Microsoft Edge 或 Google Chrome 95 或更高版本打开其中一个颜色提取器演示

不妨试试颜色游戏演示版。点击播放按钮,然后在有限的时间内尝试从底部列表中采样一种颜色,使其与顶部的彩色方块相匹配。

颜色游戏演示。

隐私权和安全注意事项

在这个看似简单的 Web API 背后,隐藏着潜在的隐私和安全问题。如果恶意网站可以开始查看您屏幕上的像素,会发生什么情况?

为解决此问题,API 规范要求采取以下措施:

  • 首先,该 API 实际上不允许在没有用户意图的情况下启动取色器模式。open() 方法只能在响应用户操作(例如点击按钮)时调用。
  • 其次,在没有用户意图的情况下,无法再次检索任何像素信息。open() 返回的 promise 仅在响应用户操作(点击像素)时解析为颜色值。因此,在用户不知情的情况下,无法在后台使用取色器。
  • 为了帮助用户轻松注意到取色器模式,浏览器必须让该模式显而易见。 因此,正常鼠标光标会在短暂延迟后消失,并显示专用界面。此外,在启动取色器模式和用户可以选择像素之间也存在延迟,以确保用户有时间看到放大镜。
  • 最后,用户可以随时取消取色器模式(按 esc 键)。

反馈

Chromium 团队希望了解您在使用 EyeDropper API 方面的体验。

请告诉我们有关 API 设计的信息

API 是否存在未按预期运行的情况?或者,是否有缺少的方法或属性需要您来实现自己的想法?对安全模型有疑问或意见?在 API 的 GitHub 代码库中提交规范问题,或在现有问题中添加您的想法。

报告实现方面的问题

您是否发现 Chromium 的实现存在 bug?或者,实现是否与规范不同? 在 new.crbug.com 上提交 bug。请务必尽可能详细地说明问题,提供简单的重现说明,并在组件框中输入 Blink>Forms>Color

显示对 API 的支持

您是否打算使用 EyeDropper API?您的公开支持有助于 Chromium 团队确定功能优先级,并向其他浏览器供应商展示支持这些功能的重要性。使用 #EyeDropper 主题标签向 @ChromiumDev 发送推文,告诉我们您在何处以及如何使用它。

实用链接

致谢

EyeDropper API 由 Microsoft Edge 团队的 Ionel Popescu 规范和实现。此博文由 Joe Medley 审核。