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

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

什么是 EyeDropper API?

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

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

如果您正在使用网络技术构建广告素材应用,则可能需要向用户提供类似的功能。不过,在 Web 上执行此操作很难,甚至根本无法执行,尤其是在您想要从整个设备屏幕(例如,从其他应用)中采样颜色,而不仅仅是从当前浏览器标签页中采样颜色时。没有浏览器提供的取色器工具可供 Web 应用根据自己的需求使用。

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

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

Chromium 颜色选择器。

如何使用 EyeDropper API

浏览器支持

浏览器支持

  • Chrome:95。
  • 边缘:95。
  • Firefox:不受支持。
  • Safari:不受支持。

来源

功能检测和浏览器支持

首先,请确保 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,经过解析的值提供对 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 或更高版本打开某个 EyeDropper 演示

颜色游戏演示为例,点击开始按钮,然后在有限的时间内,尝试从底部的列表中选择与顶部的彩色方块匹配的颜色。

Color 游戏演示。

隐私权和安全注意事项

这个看似简单的 Web API 背后隐藏着潜在的有害隐私和安全问题。如果恶意网站开始从您的屏幕上看到像素,该怎么办?

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

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

反馈

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

请向我们说明 API 设计

API 是否有什么无法按预期运行?或者,您是否缺少实现想法所需的方法或属性?对安全模型有疑问或意见?在 API 的 GitHub 代码库中提交规范问题,或者添加您对现有问题的看法。

报告实现方面的问题

您是否发现了 Chromium 实现中的 bug?或者实现方式是否与规范不同? 请访问 new.crbug.com 提交 bug。请务必提供尽可能详细的信息、简单的重现说明,并在 Components 框中输入 Blink>Forms>ColorGlitch 非常适用于分享轻松快速的重现问题。

显示对该 API 的支持

您打算使用 EyeDropper API 吗?您的公开支持有助于 Chromium 团队确定功能的优先级,并向其他浏览器供应商表明支持这些功能的重要性。使用 #EyeDropper 标签向 @ChromiumDev 发送推文,告诉我们您在哪里以及如何使用该工具。

实用链接

致谢

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