APP下载
报价宝  ›  科技  › 

用 Electron 开发桌面效率工具

报价宝 来源:baojiabao.com 发布时间:2019-07-28 19:56:00 10月03日更新
报价宝综合消息用 Electron 开发桌面效率工具

用 Electron 开发桌面效率工具

Electron 已经不算新技术,最早是 github 从 Atom 编辑器衍生出来的框架。通过编写 Javascript, HTML, CSS 能快速编译出跨系统的桌面 app。Electron 的出现使得作为前端开发工程师的我们输出范围更广。

分享最近用 Electron 做的一个基于番茄工作法的小应用,由于实现难度不大,市面上已经有非常多类似的app。我们尝试用 Electron 来实现一个。

最终效果预览:

工作法

番茄工作法的核心是将任务颗粒拆分到单位时间内(25分钟)可以完成,在这25分钟内专注在这个任务三,不允许做任何与任务无关的事,在任务任务完成之后可以短暂休息一会,再继续工作。

所以这个 app 的重点是让你建立任务,⏳ 25分钟,帮让 focus on 当前在做的任务。

站在巨人的肩膀上开发

尝试新技术的时候,不要从零开始学习如何搭建技术栈,先做出来,遇到问题再查。 Electron 社群有很多优秀的沉淀,工具,模板,元件,教程等等。

搜寻 react 关键字,找到了 electron-react-boilerplate 这个样板库, 这个库已经集成了 react, redux, sass, flow, hmr webpack 等工具,同时准备好 electron-builder 打包工具,作为 electron 新手,我们优先选择开箱即用的工具,快速开启业务开发。

SVG 和 React Component

大概画了一下草图,准备进入开发阶段。考虑后面会用到 svg icon,先在 FlatIcon 上找些免费的图示,下载 SVG 档案。

通过 SVGR 线上工具汇入 svg 内容生成 React Component 程式码。(svgr 也有 cli 等工具)

用 SVG Component 的好处是可以在程式码上更灵活地控制样式,相比 png 图示可互动性强,复用率高。

托盘和托盘弹窗

这个 app 启动的时候就隐藏在托盘选单的一角,点选的时候显示 BrowserWindow,通过 Electron 提供的方法,可以获得托盘和托盘弹窗的 Bounds 资讯,设定座标位置。

// main.js

const tray = new Tray(path.join(__dirname, '../static', 'tray.png'));

const mainWindow = new BrowserWindow({

// ...others

frame: false,

resizable: true,

transparent: true

});

const showWindow = () => {

const { x, y } = getPositionFromActiveDisplay();

mainWindow.setPosition(x, y, true);

mainWindow.show();

};

const getPositionFromActiveDisplay = () => {

const trayBounds = tray.getBounds();

const windowBounds = mainWindow.getBounds();

const x = Math.round(trayBounds.x + trayBounds.width / 2 - windowBounds.width / 2);

const y = Math.round(trayBounds.y + trayBounds.height);

return { x, y };

};

图的三角是由前端程式码绘制的,加上 frame 和 electron 背景色,应该长这样。

渲染执行绪和主执行绪

app 需要倒计时功能,告诉使用者距离任务完成时间还有多久。Electron 有渲染程序和主执行绪,BrowserWindow 不可见的时候,渲染程序会尽量减少消耗,所以如果 Tick 在渲染程序的话,当 app 处于后台时会出现非常大的时间偏差。这里使用 Electron 提供的 ipcMain 和 ipcRenderer 做程序通讯。

在主执行绪每秒传送 Tick 事件

// main.js

ipcMain.once('store-ready', event => {

const run = () => {

setTimeout(() => {

run();

event.sender.send('tick');

}, 1000);

};

run();

});

复制程式码

渲染程序就收事件并将 dispatch TICK action。

// app/index.js

const store = configureStore({

tasks: electronStore.getTasks()

});

ipcRenderer.send('store-ready');

ipcRenderer.on('tick', () => {

store.dispatch({

type: TICK

});

});

复制程式码

redux store 里面判断当前执行的任务计算倒计时时间。

switch (action.type) {

case TICK:

return {

...state,

rows: state.rows.map(task =>

task.id === state.currentId

? {

...task,

remain: Math.max(task.remain - 1, 0)

}

: task

)

};

复制程式码

资料持久储存

资料持久化有很多种方案,因为是前端浏览器,我们可以选择 localStorage, Cookie,indexDB 等等。考虑可靠性,持久化以及储存空间,还可以通过 Electron 写档案的方式,把资料写入到应用路径下。这样即使 app 被解除安装了,只要资料没被清空,使用者资料还在。

通过 Electron app getPath 可以获得应用储存路径

import { app } from 'electron';

app.getPath('userData');

复制程式码

mac 下应用 app 的路径是 /Users/user/Library/Application Support/focus。更简单的方式可以直接用开源库 electron-store,以 key-value 的格式储存 json 档案。

{

"tasks": {

"rows": [

{

"name": "任务名称",

"id": "91ac7f05-76f4-46ea-addb-f392a3a29b54",

"created_at": 1553398427806,

"plan": 1500,

"remain": 0,

"done": true

}

],

"currentId": "91ac7f05-76f4-46ea-addb-f392a3a29b54"

}

}

复制程式码

倒计时 UI

有些样式可能用 css 实现难度较大,而用 svg 的方式实现起来非常简单。比如倒计时 UI,路径圆角和路径长度用 CSS 实现复杂度较高。可以在 Sketch 上直接绘制处理,汇出成 svg,直接通过 react 程式码控制。

export default function(props: Props) {

const offset = percentage * totalLength;

const cx =

Math.cos(percentage * Math.PI * 2 - Math.PI * 0.5) * radius + radius;

const cy =

Math.sin(percentage * Math.PI * 2 - Math.PI * 0.5) * radius + radius;

return (

...others

id="path-1"

cx={cx}

cy={cy}

r="32"

fill="white"

style={{ transition: '1s linear' }}

/>

...others

strokeLinecap="round"

strokeDasharray={totalLength}

strokeDashoffset={offset}

style={{ transition: '1s linear' }}

/>

);

}

复制程式码

临界状态判断

app 在任务时间结束时需要有 Notification,由于的 Tick 设计,判断任务是否完成可以放在 redux middleware 上。

// middlewares/tasks

export default ({ getState }) => next => action => {

if (typeof action === 'object' && action.type === 'TICK') {

const beforeCount = getTimeEndTaksCount(getState);

next(action);

const afterCount = getTimeEndTaksCount(getState);

if (beforeCount !== afterCount) {

new Notification('Focus,任务完成了吗?');

}

} else {

next(action);

}

};

经过一个 Tick action 之后,判断任务完成数是否有变化,并使用 HTML5 Notification 通知使用者。

Travis CI

功能开发完毕之后,使用 electron-builder 进行打包释出,构建之后推到 github release 下,使用者可以直接在这下载到最新的包。

同样的, boilerplate 已经准备好 .travis.yml 档案,唯一需要我们操作的是在 github.com/settings/to… 上生成 token,在 www.travis-ci.org/ 构建之前配置 Environment Variables,GH_TOKEN

tirgger build, 成功之后就能看到构建成功过的包,下载使用

总结

使用 Electron,前端开发者可以使用自己的武器构建跨系统的桌面端应用,而且不用学习其他技术,缺点是一个小小的功能打包完的体积是 70M。

这个 app 从有想法到最终实现比预期的简单,感兴趣的同学也可以自己 DIY 些小玩意儿。完整的程式码在 github 上github.com/HelKyle/foc…,欢迎体验,同时也欢迎 star~

文章标签: 报价宝 降噪耳机价格 耳机价格 红米手机价格 华为手机价格 小米手机价格 电视机价格 笔记本电脑价格 笔记本价格 汽车价格 数码相机价格 手机价格 笔记本价格 电视机价格 降噪耳机价格