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

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

什么是 EyeDropper API?

许多创新应用允许用户从应用窗口的某些部分甚至整个屏幕中选择颜色,通常使用取色器的比喻。

例如,Photoshop 允许用户从画布中采样颜色,这样他们就不必猜测颜色,并有可能出错。PowerPoint 还包含一个取色器工具,在设置形状的轮廓或填充颜色时非常有用。即便是 Chromium 开发者工具,在 CSS 样式面板中修改颜色时,也可以使用取色器,这样您就不必记住或从其他地方复制颜色代码。

如果您使用 Web 技术构建创意应用,则可能需要为用户提供类似的功能。但是,在 Web 上执行此操作非常困难(如果可能的话),尤其是您想从整个设备屏幕(例如,从其他应用)而不是当前浏览器标签页中对颜色进行采样时。Web 应用没有可供 Web 应用用于自身需求的取色器工具。

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

EyeDropper API 提供了从屏幕对颜色进行采样的方法,以填补此空白。

Chromium 颜色选择器。

如何使用 EyeDropper API

浏览器支持

浏览器支持

  • 95
  • 95
  • x
  • x

来源

功能检测和浏览器支持

首先,在使用之前确保 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 演示

例如,不妨试试颜色游戏演示。点击 Play 按钮,在限定的时间内,尝试从底部的列表中采样一种与顶部的彩色方块匹配的颜色。

彩色游戏演示。

隐私权和安全注意事项

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

为解决这一问题,该 API 规范需要采取以下措施:

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

反馈

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

向我们介绍 API 设计

是否存在 API 行为不符合您预期的情况?或者说,是否缺少某些方法或属性来实现您的想法?如果您对安全模型有疑问或意见,请在该 API 的 GitHub 代码库中提交规范问题,或将您的想法添加到现有问题中。

报告实施方面的问题

您是否发现了 Chromium 实现中存在的错误?或者,实现方式是否不同于规范? 请在 new.crbug.com 提交 bug。请务必提供尽可能多的详情和简单的重现说明,并在组件框中输入 Blink>Forms>ColorGlitch 非常适合快速轻松地分享重现的视频。

显示对该 API 的支持

您打算使用 EyeDropper API 吗?您公开提供的支持有助于 Chromium 团队确定各项功能的优先级,并向其他浏览器供应商说明支持这些功能的重要性。请使用 # 标签 #EyeDropper@ChromiumDev 发送一条推文,告诉我们您使用该推文的位置和方式。

实用链接

致谢

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