使用Electron开发一个吸色工具的心路历程

为什么要(zuo)

”世界上只有一种英雄主义,那就是认清自己的发际线之后依然热爱撸码“ -- 欧大强·罗兰

Electron是一个非常有趣的开源项目,“它可以让你使用纯 JavaScript 调用丰富的原生(操作系统) APIs 来创造桌面应用”。光看这官方简介就让人不住跃跃欲试,再加上市面上没找到能让我中意的桌面吸色工具,所以我决定使用Electron来开发一款。
下载地址:

需求与界面

我的软件,界面一定要好看,LOGO一定要大气,主色调要那种低沉性感又不失庄重,气势磅礴的黑。

(献丑了。果然设计师不是随便就能做的)

功能大致包括以下几点

  • 支持快捷键操作并可自定义。
  • 有历史选色记录。
  • 能自由切换色值。
  • 在已知透明度和背景色的条件下计算出当前取色器的rgba色值。
  • 支持最小化到托盘

基本思路

Electron没有API可以直接拿到当前指针所在位置的色值,但是提供了获取桌面资源的方法。在执行取色操作时使用desktopCapturer将当前桌面截图,然后在canvas上展示并使用getImageData() 获取指定色值。Easy。

遇到的问题

关于Electron的介绍网络有很多,上手难度也不算高,线程之间的关系与操作还有API文档写的非常详细,但这不意味着你(zuo)起来就能一帆风顺了。

Global变量无法获取

通过ipc和global我们很容易就能实现一个简易的状态管理机制,在这里我碰到了第一个坑。
因为remote复制对象而不是提供引用,所以在渲染进程中操作的global对象需要提前在主进程中定义初始值。
main process:

global.sharedObj = {prop1: null};
复制代码

renderer process:

remote.getGlobal('sharedObj').prop1 = 125;
复制代码

使用desktopCapturer截图有色差

通过desktopCapturer.getSources()API我们可以得到一个DesktopCapturerSource对象,再配合getUserMedia我们可以很方便的获取当前可用资源。

// In the renderer process.
const { desktopCapturer } = require('electron')

desktopCapturer.getSources({ types: ['window', 'screen'] }, (error, sources) => {
  ...
  navigator.mediaDevices.getUserMedia({
    ...
    video: {
      mandatory: {
        chromeMediaSource: 'desktop',
        chromeMediaSourceId: sources[0].id,
        ...
      }
    }
  }).then((stream) => {
    const video = document.querySelector('video')
    video.srcObject = stream
  }).catch((e) => ...)
})

复制代码

以上是官方给的使用文档,将video的第一帧绘制到canvas上便成功对当前桌面进行截图。但事情并没有这么简单,在我阅片无数的双眼下,任何细微的差别都无处遁行,使用getUserMedia得到的图像竟然有色差


我测算了一下,截图得到的图片和原图相比,绿色通道的值要高一些,所以我猜测造成色差的原因可能是由于浏览器使用的是 sRGB色域,而显示器使用的是aRGB色域(希望有大佬能帮忙指正)。
虽然通过 DesktopCapturerSource对象上的 thumnail(NativeImage)能直接得到当前桌面的缩略图(截图)并且没有色差, 但是desktopCapturer在工作中是会阻塞进程的,不推荐直接通过 thumnail来获取百分百比例的桌面截图。所以最后我选择使用 desktop-screenshot这个第三方node库来实现截图步骤。

写入文件路径报错

我使用了lowdb这个node库来储存设置的快捷键和历史色值,开发的时候一切正常,可打包后在Mac上运行起来就会报错EROFS: read-only file system


未签名的app似乎在mac上很不招待见,好在Electron提供了 app.getPath(name)来获取文件路径的,我们无法确定用户会将软件放到哪个目录,所以我建议将需要被修改的文件放入系统文件夹或临时文件夹。

  app.getPath(name) // Electron
  or
  os.tmpdir() // node原生模块获得临时文件路径
复制代码

打包优化

除了尽可能减少dependencies的依赖之外,基本无解。别问,问就是100M起。

结尾

虽然这是一个简单的项目,还有很多没来得及深入发掘。
虽然常伴小坑,但总的来说瑕不掩瑜,体验还是相当到位的。 如果你也想体验一把桌面应用开发,Electron是个非常靠谱的选择。
github

参考资料:

转载于:https://juejin.im/post/5caa0af1e51d452b45296484

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于使用 Electron 开发一个 Markdown 工具,你可以按照以下步骤进行操作: 1. 首先,确保你已经安装了 Node.js 和 npm(Node.js 包管理器)。 2. 创建一个空文件夹,并在终端中进入该文件夹。 3. 执行以下命令来初始化一个新的 npm 项目: ``` npm init ``` 4. 安装 Electron 依赖: ``` npm install electron ``` 5. 创建一个主文件(例如 `main.js`),并在其中编写 Electron 的主进程代码。这个文件将负责创建和控制应用程序的窗口,以及处理与 Markdown 文件相关的逻辑。 6. 创建一个 HTML 文件作为应用程序的界面,例如 `index.html`。在这个文件中,你可以使用 HTML、CSS 和 JavaScript 来设计和实现 Markdown 编辑器的界面。 7. 在 `main.js` 中,使用 `electron` 模块来创建一个新的 Electron 应用程序窗口,并加载你的 `index.html` 文件: ```javascript const { app, BrowserWindow } = require('electron'); function createWindow() { // 创建浏览器窗口 const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); // 加载 index.html 文件 win.loadFile('index.html'); } // 当 Electron 完成初始化并且准备创建浏览器窗口时调用 createWindow 函数 app.whenReady().then(createWindow); ``` 8. 运行你的应用程序: ``` electron . ``` 这只是一个简单的示例,你还可以根据自己的需求添加更多功能,比如保存和导出 Markdown 文件,实时预览等等。希望这些步骤对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值