Web 前端系统级取色器 EyeDropper API

2025-06-20 前端

一、什么是 EyeDropper API?

EyeDropper API 是浏览器提供的一个系统级取色器接口,允许用户从屏幕上的任意位置(包括浏览器外部)拾取颜色。它不需要任何第三方依赖库,是 Web 平台原生的取色解决方案。

1.1 传统取色方案的痛点

在 EyeDropper API 出现之前,Web 前端要实现取色功能通常有以下几种方式:

  • 第三方库:如 Pickr、iro.js 等,体积较大且功能冗余
  • HTML5 Canvas 方案:截取页面截图后用 Canvas 分析像素颜色,实现复杂且只能取页面内的颜色
  • input[type=color]:只能取色板中的颜色,无法从屏幕任意位置取色

这些方案要么依赖外部库,要么功能受限,都无法做到真正的"系统级取色"。

1.2 EyeDropper 的优势

特性 EyeDropper 第三方库 Canvas 方案
系统级取色(屏幕任意位置) ✅ ❌ ❌
原生支持,零依赖 ✅ ❌ ✅
跨浏览器 有限(Chrome 为主) ✅ ✅
使用复杂度 ⭐ 简单 ⭐⭐ 中等 ⭐⭐⭐ 复杂
性能开销 极低 中等 较高

二、基础用法

2.1 浏览器兼容性检查

在使用 EyeDropper API 之前,首先需要检测浏览器是否支持:

const isSupported = 'EyeDropper' in window;

if (!isSupported) {
    console.warn('当前浏览器不支持 EyeDropper API');
    // 可以降级使用 input[type=color] 或第三方库
}

2.2 基本使用流程

EyeDropper API 的使用非常简洁,只需三步:

// 1. 创建 EyeDropper 实例
const eyeDropper = new EyeDropper();

// 2. 打开取色器(用户选择颜色)
eyeDropper.open()
    .then(result => {
        // 3. 获取拾取的颜色(sRGB 十六进制格式)
        console.log(result.sRGBHex); // 例如: '#3366ff'
    })
    .catch(error => {
        // 用户取消或取色失败
        console.error('取色取消:', error);
    });

2.3 完整示例:点击按钮取色


三、进阶用法

3.1 颜色格式转换

EyeDropper 返回的颜色格式为 sRGB 十六进制(如 #3366ff),但实际开发中可能需要其他格式:

3.2 配合 AbortController 实现超时控制

某些情况下,你可能希望在用户长时间不取色时自动取消:

function pickColorWithTimeout(timeout = 30000) {
    if (!('EyeDropper' in window)) {
        return Promise.reject(new Error('不支持 EyeDropper'));
    }

    const controller = new AbortController();
    const eyeDropper = new EyeDropper();
    const timer = setTimeout(() => controller.abort(), timeout);

    return eyeDropper.open({ signal: controller.signal })
        .then(result => {
            clearTimeout(timer);
            return result.sRGBHex;
        })
        .catch(err => {
            clearTimeout(timer);
            throw err;
        });
}

// 使用
pickColorWithTimeout(10000)
    .then(color => console.log('取色结果:', color))
    .catch(err => console.log('取色取消或超时'));

3.3 取色历史记录

实现取色历史记录功能,方便用户重复使用最近拾取的颜色:


四、实际应用场景

4.1 设计工具中的取色器

class DesignTool {
    constructor() {
        this.selectedColor = '#000000';
    }

    async pickColor() {
        if (!('EyeDropper' in window)) return null;
        const eyeDropper = new EyeDropper();
        try {
            const result = await eyeDropper.open();
            this.selectedColor = result.sRGBHex;
            this.updateUI();
            return result.sRGBHex;
        } catch {
            return null;
        }
    }

    updateUI() {
        document.querySelectorAll('.color-display').forEach(el => {
            el.style.background = this.selectedColor;
            el.querySelector('.color-label').textContent = this.selectedColor;
        });
    }
}

4.2 主题定制器

4.3 无障碍颜色对比度检测

结合取色器和对比度检测,帮助用户选择无障碍友好的颜色组合:

function getLuminance(hex) {
    const rgb = hexToRgb(hex);
    const [r, g, b] = [rgb.r, rgb.g, rgb.b].map(c => {
        c = c / 255;
        return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
    });
    return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}

function getContrastRatio(hex1, hex2) {
    const l1 = getLuminance(hex1);
    const l2 = getLuminance(hex2);
    const lighter = Math.max(l1, l2);
    const darker = Math.min(l1, l2);
    return (lighter + 0.05) / (darker + 0.05);
}

// WCAG 标准检测
function checkWCAG(hex1, hex2) {
    const ratio = getContrastRatio(hex1, hex2);
    return {
        ratio: ratio.toFixed(2) + ':1',
        passesAA: ratio >= 4.5,
        passesAAA: ratio >= 7
    };
}

五、浏览器兼容性与降级方案

5.1 当前浏览器支持情况

浏览器 支持版本 状态
Chrome 95+ ✅ 完整支持
Edge 95+ ✅ 完整支持
Opera 81+ ✅ 完整支持
Firefox ❌ 未实现
Safari ❌ 未实现
IE ❌ 不支持

5.2 优雅降级


六、安全与隐私

6.1 安全限制

  1. 必须由用户手势触发:open() 必须在点击、触摸等用户事件中调用
  2. 需要 HTTPS:API 仅在安全上下文(HTTPS)中可用
  3. 取色范围无限制:可以取屏幕任意位置的颜色,包括其他应用窗口

6.2 隐私保护

  • EyeDropper 不会自动捕获屏幕内容
  • 取色完成后仅返回颜色值,不返回任何屏幕截图或像素数据
  • 应用无法在后台悄悄取色
  • 取色器打开时,鼠标指针变为放大镜样式,用户可见取色操作

七、总结

EyeDropper API 为 Web 前端提供了一个原生、高效、零依赖的系统级取色方案。主要优势:

  1. 系统级取色:从屏幕任意位置(包括其他应用)拾取颜色
  2. 极简 API:new EyeDropper().open() 三步搞定
  3. 用户体验好:鼠标放大镜预览、实时颜色显示
  4. 安全可靠:必须用户手势触发,无法后台取色

目前虽仅 Chromium 内核支持,但结合降级方案已可在实际项目中使用。

参考链接