前言

为了进一步提高开发工作效率,最近我们基于 electron 开发了一款媲美 uTools 的开源工具箱 rubick。该工具箱不仅仅开源,最重要的是可以使用 uTools 生态内所有开源插件!这将是巨大的能力,意味着 uTools 生态内所有插件可以无差异化使用到 rubick 中。

设计交互上为了更能提高用户的使用效率,我们又尝试去实现了 uTools 中非常优秀的一些设计,比如:全局取色和截屏。全局取色在获取一些图片、其他App应用的颜色时非常有用。截屏虽然可以使用钉钉或者微信自带的截图功能,但是为了更加符合 uTools 用户习惯,我们也顺便实现了一下。

接下来进入主题,我们来基于 rubick 来一步步实现一个取色和截屏能力。

代码仓库

Rubick github

功能演示:

QQ20210707-170430.gif

实现取色

要实现屏幕取色能力,主要核心能力步骤如下:

  1. 跟随鼠标移动,获取当前屏幕鼠标位置
  2. 获取当前坐标的颜色

1. 获取鼠标移动的坐标

要获取系统鼠标移动的坐标,electron 本身没有提供相关的函数和能力,所以要实现跟随获取系统鼠标位置,可能要调用原生能力。好在有一个 iohook 这样一个强大的系统调用工具,可以帮助我们监听系统鼠标操作以及按键操作。所以我们可以基于 iohook 来实现位置坐标获取。在 electron 中按照 iohook,在 npm install iohook 之前,需要在 package.json 中配置:

"iohook": {
  "targets": [
    "node-72",
    "electron-85"
  ],
  "platforms": [
    "win32",
    "darwin",
    "linux"
  ],
  "arches": [
    "x64",
    "ia32"
  ]
}

后面在 install 的时候会为我们按照所需下载通过 node-gyp 编译好的 node 可调用的包。如果需要重新编译,需要再重新执行命令:

"rebuild": "npm rebuild --runtime=electron --target=5.0.0 --disturl=https://atom.io/download/atom-shell --abi=80"

具体需要哪个版本的 nodeelectron 可以参考这篇文章

准备工作做完之后,接下来就是调用 iohook 获取鼠标移动位置:

 ioHook.on('mousemove', ({x, y}) => {
  // todo
})

2. 获取当前坐标位置颜色

这里,需要利用到另一个库 robotjs,该库提供了强大的系统操作能力,最最最重要的是他可以获取到像素点的色彩,这就很关键了。这个正好是我们需要的:

 let color = "#" + robot.getPixelColor(parseInt(x), parseInt(y));

到这里就基本上完成了。

另一种实现方案

上面是一种比较常规的做法,但除了上面的方式,还有没有其他的方式呢?当时我也想了很久,后来仔细想想,electron 虽然获取不到系统鼠标位置和点击以及系统级别的像素,但是如果我们的屏幕本身就是一个 electronbrowserWindow 那就可以通过 DOM 来实现啦!

确实这是一个思路,核心步骤拆解下来就是:

  1. 根据当前显示器个数渲染对应个数 browserWindow
  2. 每个 browserWindow 尺寸设置成透明全屏的
  3. 获取每个 screen 的全屏截图
  4. 绘制截图到 browserWindow 的 canvas 上
  5. 从系统级操作转成 electron 内部操作

具体的实现方式这里就不细说,因为下面截屏采用的就是这种方案。

实现系统截屏

系统截屏就可以参考上面所述,采用分屏渲染子窗口,再操作子窗口的方式来实现,这里我也是参考了:从零开始用 electron 手撸一个截屏工具

最后

本篇主要介绍如何实现一个类似于 utools 的取色、截屏能力,当然这远远不是 utools 的全部,下期我们再继续介绍如何实现 utools 其他能力。欢迎大家前往体验 Rubick 有问题可以随时提 issue 我们会及时反馈。

另外,如果觉得设计实现思路对你有用,也欢迎给个 Star:https://github.com/clouDr-f2e/rubick