JS 就能实现吸管工具功能?来试试 EyeDropper API 👏

3,722 阅读3分钟

前言

使用 JS 就能实现吸管工具功能?没错,随着 Chrome 95 的推出, EyeDropper API 能够帮助我们轻松地在 Web 应用中创建吸管工具 😄

问题/动机

许多生产力应用程序允许用户从应用程序窗口的部分甚至整个屏幕中选择颜色,如 Photoshop,这一功能通常被称作吸管工具。但如果开发类似的 Web 应用,使用现有的 Web 技术无法做到。

在之前分享的《一些你可能不知道但非常有用的 HTML 标签》中提到,使用 <input type="color"> 标签可以在 Chromium 系浏览器中实现取色器功能,但它不是标准的,在 Firefox、Safari 下表现不一致,且并没有内置吸管工具。

此外,最重要的一点是, <input type="color"> 很难使用 CSS 定制样式 🥲

所以,最好的方式是可以直接使用 JS 实现这一功能。好在 Chromium 95 为我们提供了 EyeDropper API,可以非常轻松的实现一个吸管工具。

使用

EyeDropper API 使用非常简单,仅需创建一个 EyeDropper实例,然后调用其 open() 方法即可:

const eyeDropper = new EyeDropper();
const result = await eyeDropper.open();

像许多其他现代 Web API 一样,它是异步工作的,因此不会阻塞主线程。事实上,所有与用户交互有关的 API 都应该是非阻塞的。

open() 方法将返回一个 Promise,在用户选择完屏幕上的像素后,resolve 像素的颜色值(sRGBHex 格式)。如果用户通过按 esc 键退出吸管模式,则该 Promise 将被 reject。

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.
}

下面是实际使用效果,你可以在 eyedropper-sample.glitch.me/ 上体验这个例子:

eyedropper.gif

事实上,吸管工具不仅能捕获当前页面的像素点颜色值,而是可以捕获整个屏幕,因此你可以通过 tab 切换应用,来完成对任意像素的颜色获取。

取消吸管工具,也可以使用 AbortController 对象的 signal 并将其传递给 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();

隐私与安全问题

隐私与安全问题,EyeDropper API 的设计者们也考虑到了:

  1. open() 方法只有在用户采取一些明确的操作下才会调用,例如用户点击了按钮。因此没有用户交互,EyeDropper API 是不会有任何效果的。
  2. open() 方法只有在用户交互的情况下返回像素信息,移动过程中不会记录像素值,当用户点击完像素才会返回颜色值,因此,吸管工具不能在用户没有注意到的情况下在后台使用。
  3. 为了让用户更容易注意到吸管模式,进入吸管模式后,鼠标光标会在短暂延迟后消失,随后出现放大镜🔍。
  4. 通过按 esc 键,用户可以随时取消吸管模式,因此应用可以适当提醒用户这一点。

结论

虽然 EyeDropper API 目前仅在 Chromium 95 浏览器(Chrome, Microsoft Edge)中才能使用,但 EyeDropper API 初始化的草案和规范已完成,相信在不久之后将在各大现代浏览器中见到它的身影。感兴趣的小伙伴可以尝试在 Chrome 插件或 Electron 应用中集成体验 😉

参考文章

[1] Picking colors of any pixel on the screen with the EyeDropper API

本文由推啊前端团队 @Winter97 整理撰写