跳转到内容

取色器封装

刀刀

1/8/2025

0 字

0 分钟

原生 HTML 中,input 设置 typecolor 时可以变为颜色筛选器,用于选取颜色。缺点是只能选取组件提供的颜色,不可吸取组件外的颜色,甚至浏览器外的颜色。

EyeDropper

在浏览 MDN 文档时,有一个 API 吸引了我的注意,EyeDropper 。MDN 描述它为是一个接口,表示一个拾色器工具的实例,用户可以打开并使用它从屏幕上选择颜色。

使用方式如下:

  1. 通过关键字 new 创建一个构造函数
  2. 调用其 open() 方法,该方法是一个异步任务
  3. 回调函数中接收参数,参数的 sRGBHex 属性就是颜色的值

他也提供了用户取消拾色器模式的方法:signal :终止取色的标识,类似于 fetch 的 signal

基础使用代码如下:

查看代码
html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>取色器</title>
  </head>
  
  <body>
    <button id="start-button">打开拾色器</button>
    <span id="result"></span>
    
    <script>
      document.getElementById("start-button").addEventListener("click", () => {
  		const resultElement = document.getElementById("result");

  		if (!window.EyeDropper) {
    		resultElement.textContent = "你的浏览器不支持 EyeDropper API";
    		return;
  		}

  		const eyeDropper = new EyeDropper();
  		const abortController = new AbortController();

  		eyeDropper
    		.open({ signal: abortController.signal })
    		.then((result) => {
      		resultElement.textContent = result.sRGBHex;
      		resultElement.style.backgroundColor = result.sRGBHex;
    		})
    		.catch((e) => {
      		resultElement.textContent = e;
    		});

  		setTimeout(() => {
    		abortController.abort();
  		}, 2000);
		});
    </script>
  </body>
</html>

封装函数

封装成一个 hook 供外部使用,需要注意浏览器兼容性:

查看代码
js
import { ref } from 'vue'

/**
 * @param initialValue string
 */
export function useEyeDropper(options = {}) {
  const { initialValue = '' } = options
  const isSupported = window.EyeDropper
  const sRGBHex = ref(initialValue)

  async function open(openOptions) {
    if (!isSupported.value) return new Error('浏览器不支持取色器')
    const eyeDropper = new window.EyeDropper()
    const result = await eyeDropper.open(openOptions)
    sRGBHex.value = result.sRGBHex
    return result
  }

  return { isSupported, sRGBHex, open }
}

浏览器兼容性

兼容性

总体效果