在Chrome浏览器中最快速实现拾色器(吸管)的方法

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 介绍一种网页拾色器(颜色吸管工具)在前端的快速实现方法。

说到网页拾色器(颜色吸管工具)在前端的实现方法,通常我们会想到先进行网页截图,然后通过Canvas绘制截图,此时利用Canvas所提供的的API即可解析出图片每个像素点颜色,最后通过获取鼠标定位,得到当前的坐标来进行颜色选择。

在这种方式下通常问题出在第一个步骤,就是进行网页截图的方法,在前端网页截图常见的工具有:html2canvasdom-to-image 等,然而这些库的实现原理都是通过解析DOM然后转换语法(CanvasSvg)绘制再导出图片,虽然这是目前实现截图操作的唯一出路,但我们要清楚的是这样做不可避免会出现以下问题:

  1. 对于复杂网页场景解析可能会出现缺失或错误
  2. 无法避免 CanvasSvg 的渲染结果与网页呈现效果存在差异的问题
  3. 生成效率太慢,解析绘制过程会造成卡顿,非常影响用户体验

所以基于此思路做出来的颜色吸色器尽管在设计初期就考虑可用性,也仍然无法避免上述问题,最多只能应用于简单网页的场景当中,但这通常又与事实相违背——因为简单的网页往往极少有使用到吸色器的业务场景。

原生方案

如果说 JS 的实现方法是令人绝望的,那么把问题交给浏览器原生方法可能是未来最好的解决方案之一,事实上原生 HTML 早已提供了一种实现颜色选择的元素,它就是我们所熟悉的 input 标签。

<input type="color">元素<input>元素中的一个特定种类,用来创建一个允许用户使用颜色选择器,或输入兼容 CSS 语法的颜色代码的区域。(不支持 Alpha 通道)

此元素的外观会因浏览器不同而不同,可能是简单的验证颜色输入格式的文本框,也可能使用平台原生或自定义样式的颜色选择器。其 UI 除要能接收文本格式的颜色外,未要求其他特性。(更多信息

关于"元素的外观会因浏览器不同而不同",先给大家感受下 Safari 下显示效果,需要额外点击“显示颜色”调出系统调色盘,非常的别扭:

但是谷歌浏览器下的实现体验已经非常好了:

2022-09-06 13.43.45.gif

可以看到原生方式下的吸管工具都是系统级别的,也就是说除了网页上的颜色以外,整个屏幕的任何可见元素都可以吸取,而且启动速度非常快,使用流畅不卡顿。

我在第一次了解该元素时就在想:如果这个原生吸管工具可以单独拿出来用就好了,这样可以通过自己开发一个颜色选择器来弥补原生颜色选择器不支持 Alpha 通道的缺点,而原生吸管工具则可以解决目前 JS 很难实现吸色的问题。于是搜索一番后发现真的有一个 BOM 的构造函数:EyeDropper(),它支持创建吸管工具的实例,以提供用户可使用的颜色选择工具。

注意:该功能仍是一项实验性技术,请谨慎在生产环境中使用,另外如果部署到线上发现失效,请检查站点是否已开启 HTTPS,如不在安全上下文环境中,无论浏览器是否支持该方法都不会生效(本地开发环境似乎不受影响)。

小试牛刀

以 Vue 为例,我们可以像这样编写一个最简单的 Demo

<template>
    <button v-if="hasEyeDrop" @click="nativePick">点击取色</button>
    <input v-else type="color" @input="nativePick" />
</template>

<script>
export default {
  data() {
    return {
      hasEyeDrop: 'EyeDropper' in window
    };
  },
  methods: {
    async nativePick (e){
     const val =  e ? e.target.value : null
      if (val) {
        console.log('获得颜色: ' + val)
      } else {
        const eyeDropper = new window.EyeDropper() // 初始化一个EyeDropper对象
        console.log('按Esc可退出')
        try {
          const result = await eyeDropper.open() // 开始拾取颜色
          console.log('获得颜色: ' + result.sRGBHex)
        } catch (e) {
          console.log('用户取消了取色')
        }
      }
    }
  },
};
</script>
支持吸色器时 不支持则调用原生input
image.png image.png

亲自体验

代码片段

当然我们还可以让原生吸色器补足取色功能的同时,自定义一个透明度滑块来支持改变色值 Alpha 通道,实现更复杂的应用场景:

2022-09-06 15.35.49.gif

适用场景

目前该方法在兼容性方面只有 ChromeEdgeOpera 这三个浏览器在全力支持,所以适用范围并不广泛,但是由于其在谷歌浏览器上体验实在优秀,还是非常推荐在必要时尽可能使用它,真的太香了!

image.png

另外提一嘴,我觉得在 Electron 中应当是非常契合的,虽然 Electron 有打包体积过大的缺点,但这个缺点也意味着它拥有绝对控制浏览器版本的权利,所以能放心地使用新特性,通过它就可以在桌面程序中用三两行代码便利地实现一个流畅的屏幕取色器了!

相关文章
|
3月前
|
Web App开发 数据采集 存储
WebDriver与Chrome DevTools Protocol:如何在浏览器自动化中提升效率
本文探讨了如何利用Chrome DevTools Protocol (CDP) 与 Selenium WebDriver 提升浏览器自动化效率,结合代理IP技术高效采集微博数据。通过CDP,开发者可直接操作浏览器底层功能,如网络拦截、性能分析等,增强控制精度。示例代码展示了如何设置代理IP、cookie及user-agent来模拟真实用户行为,提高数据抓取成功率与稳定性。适用于需要频繁抓取互联网数据的应用场景。
538 3
WebDriver与Chrome DevTools Protocol:如何在浏览器自动化中提升效率
|
1月前
|
Web App开发 缓存 安全
WIN11 Chrome 双击打不开闪退及Chrome浏览器不能拖拽文件crx
【11月更文挑战第6天】本文介绍了 WIN11 系统中 Chrome 浏览器双击打不开闪退及不能拖拽文件 crx 的原因和解决方法。包括浏览器版本过旧、扩展程序冲突、硬件加速问题、缓存过多、安全软件冲突、系统文件损坏、用户配置文件损坏等问题的解决方案,以及 crx 文件的屏蔽、权限问题和文件格式问题的处理方法。
105 2
|
1月前
|
Web App开发 Linux iOS开发
Chrome浏览器如何导出所有书签并导入书签
【11月更文挑战第4天】本文介绍了如何在 Chrome 浏览器中导出和导入书签。导出时,打开书签管理器,点击“整理”按钮选择“导出书签”,保存为 HTML 文件。导入时,同样打开书签管理器,点击“整理”按钮选择“导入书签”,选择之前导出的 HTML 文件即可。其他主流浏览器也支持导入这种格式的书签文件。
151 2
|
1月前
|
Web App开发 JavaScript 前端开发
使用 Chrome 浏览器的内存分析工具来检测 JavaScript 中的内存泄漏
【10月更文挑战第25天】利用 Chrome 浏览器的内存分析工具,可以较为准确地检测 JavaScript 中的内存泄漏问题,并帮助我们找出潜在的泄漏点,以便采取相应的解决措施。
246 9
|
2月前
|
Web App开发 开发者
|
2月前
|
Web App开发 JSON 安全
Chrome浏览器的跨域问题
【10月更文挑战第6天】
|
2月前
|
算法 安全 前端开发
基于postMessage和BroadcastChannel实现浏览器跨Tab窗口通信的方法介绍
基于postMessage和BroadcastChannel实现浏览器跨Tab窗口通信的方法介绍
95 0
|
2月前
|
Web App开发 缓存 安全
Chrome浏览器启动参数大全
这是一组用于定制浏览器行为的命令行参数,包括但不限于:不停用过期插件、放行非安全内容、允许应用中心脚本、停用GPU加速视频、禁用桌面通知、禁用拓展及各类API、调整缓存设置、启用打印预览、隐身模式启动、设定语言、使用代理服务器、无头模式运行等。通过这些参数,用户可以根据需求灵活调整浏览器功能与性能。
|
3月前
|
Web App开发 存储 前端开发
Chrome浏览器的跨域问题
Chrome浏览器的跨域问题
|
4月前
|
Web App开发 JSON 安全
【跨域难题终结者】:一键解锁Chrome浏览器神秘设置,彻底告别开发阶段的跨域烦恼!
【8月更文挑战第20天】跨域是前端开发常遇难题,尤其在前后端分离项目中。浏览器因安全考量会阻止不同源间的请求。本文对比CORS、JSONP、代理服务器等解法,并介绍开发阶段通过调整Chrome设置来临时禁用跨域限制的方法,提供启动Chrome及使用`fetch`API示例,适合快速测试。但请注意这不适用于生产环境,存在一定安全风险。
1127 1