从零开始用electron手撸一个截屏工具的示例代码

最近在尝试利用 electron 将一个 web 版的聊天工具包装成一个桌面 APP。作为一个聊天工具,截屏可以说是一个必备功能了。不过遗憾的是没有找到很成熟的库来用,也可能是打开方式不对,总之呢没看到现成的,于是就想从头撸一个简单的截图工具。下面就进入正题吧!

思路

electron 提供了截取屏幕的 API,可以轻松的获取每个屏幕(存在外接显示器的情况)和每个窗口的图像信息。

把图片截取出来,然后创建一个全屏的窗口盖住整个屏幕,将截取的图片绘制在窗口上,然后再覆盖一层黑色半透明的元素,看起来就像屏幕定住了一样;

在窗口上增加交互制作选区的效果;

点击确定,利用 canvas 对应选区的位置截取图片内容,写入剪贴板和保存图片。

搭建项目

首先创建 package.json 填写项目的必要信息, 注意 main 为入口文件。

{ "name": "electorn-capture-screen", "version": "1.0.0", "main": "main.js", "repository": "https://github.com/chrisbing/electorn-capture-screen.git", "author": "Chris", "license": "MIT", "scripts": { "start": "electron ." }, "dependencies": { "electron": "^3.0.2" } }

创建 main.js , 代码来自 electron 官方文档

const { app, BrowserWindow, ipcMain, globalShortcut } = require('electron') const os = require('os') // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. let win function createWindow() { // 创建浏览器窗口。 win = new BrowserWindow({ width: 800, height: 600 }) // 然后加载应用的 index.html。 win.loadFile('index.html') // 打开开发者工具 win.webContents.openDevTools() // 当 window 被关闭,这个事件会被触发。 win.on('closed', () => { // 取消引用 window 对象,如果你的应用支持多窗口的话, // 通常会把多个 window 对象存放在一个数组里面, // 与此同时,你应该删除相应的元素。 win = null }) } // Electron 会在初始化后并准备 // 创建浏览器窗口时,调用这个函数。 // 部分 API 在 ready 事件触发后才能使用。 app.on('ready', createWindow) // 当全部窗口关闭时退出。 app.on('window-all-closed', () => { // 在 macOS 上,除非用户用 Cmd + Q 确定地退出, // 否则绝大部分应用及其菜单栏会保持激活。 if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', () => { // 在macOS上,当单击dock图标并且没有其他窗口打开时, // 通常在应用程序中重新创建一个窗口。 if (win === null) { createWindow() } })

创建 index.html , html 中放了一个按钮, 用来触发截屏操作

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Hello World!</title> </head> <body> <button>Capture Screen</button> <script> const { ipcRenderer } = require('electron') document.getElementById('js-capture').addEventListener('click', ()=>{ ipcRenderer.send('capture-screen') }) </script> </body> </html>

这样一个简单的 electron 项目就完成了, 执行 yarn start 或者 npm start 即可看到一个窗口, 窗口中有一个按钮

从零开始用electron手撸一个截屏工具的示例代码

触发截屏

截屏是一个相对独立的功能, 并且有可能会有全局快捷键以及菜单触发等脱离窗口的情况, 所以截屏的触发应该放在 main 进程中来实现

在 renderer 进程中可以通过 ipc 通讯来完成, 在页面的代码中使用 ipcRenderer 发送事件, 而在 main 中使用 ipcMain 接收事件

// index.html const { ipcRenderer } = require('electron') document.getElementById('js-capture').addEventListener('click', ()=>{ ipcRenderer.send('capture-screen') })

在 main 进程中接收 capture-screen 事件

// main.js // 接收事件 ipcMain.on('capture-screen', captureScreen)

同时加入全局快捷键触发和取消截屏

// main.js // 注册全局快捷键 // globalShortcut 需要在 app ready 之后 globalShortcut.register('CmdOrCtrl+Shift+A', captureScreen) globalShortcut.register('Esc', () => { if (captureWin) { captureWin.close() captureWin = null } })

通过快捷键和事件来触发截屏方法 captureScreen , 接下来实现这个方法来创建一个截屏窗口

创建截屏窗口

截屏窗口是要创建一个全屏的窗口, 并且把屏幕图片绘制在窗口上, 再通过鼠标拖拽等交互操作选出特定区域的图像.

第一步是要创建窗口

// main.js let captureWin = null const captureScreen = (e, args) => { if (captureWin) { return } const { screen } = require('electron') let { width, height } = screen.getPrimaryDisplay().bounds captureWin = new BrowserWindow({ // window 使用 fullscreen, mac 设置为 undefined, 不可为 false fullscreen: os.platform() === 'win32' || undefined, // win width, height, x: 0, y: 0, transparent: true, frame: false, skipTaskbar: true, autoHideMenuBar: true, movable: false, resizable: false, enableLargerThanScreen: true, // mac hasShadow: false, }) captureWin.setAlwaysOnTop(true, 'screen-saver') // mac captureWin.setVisibleOnAllWorkspaces(true) // mac captureWin.setFullScreenable(false) // mac captureWin.loadFile(path.join(__dirname, 'capture.html')) // 调试用 // captureWin.openDevTools() captureWin.on('closed', () => { captureWin = null }) }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/6f6d25db319421e0a45c6456910ef6c6.html