Electron + 磨砂玻璃,做了一套可以贴桌面的「效率小组件」

11 阅读2分钟

背景

作为一个天天对着电脑的程序员,桌面经常被各种窗口堆满,找个天气要切 App,看个待办要点好几次,效率就在这些琐碎里悄悄溜走了。 于是我用 Electron 做了一套桌面小组件,直接贴在桌面上,随取随用。

实现效果

preview-1.jpg

preview-2.png 六个组件:

  • 📋 待办(优先级 + 拖拽排序 + 截止日点击循环)
  • 📅 日历(月视图 + 日程管理)
  • 🌤 天气(wttr.in,10分钟自动刷新)
  • 📝 便签(黄色纸张风格,600ms 防抖自动保存)
  • 🎯 阶段目标(子任务自动算进度)
  • 📁 桌面文件夹(拖文件进去自动整理图标) 核心交互:
  • 拖到屏幕边缘 → 自动贴边变半透明
  • 鼠标悬停 → 恢复显示
  • 置顶 Pin → 置顶时自动禁用吸附
  • 位置/透明度/状态 → 全部持久化

二次开发

每个 widget 都是独立的 HTML 文件,改完保存,窗口自动热更新。用 Cursor 或 OpenClaw 的 Agent 模式,直接说"帮我把天气城市改成上海",它会帮你改好。

待完善

  • 天气城市目前硬编码深圳,暂无 UI 配置入口
  • 便签目前只有一个
  • 待办没有系统通知提醒
  • electron-builder 打包还未配置 欢迎 Star,也欢迎提 Issue 或 PR!

GitHub:github.com/ferralina/d…

技术实现

无边框窗口 + 磨砂玻璃

Electron BrowserWindow 设置透明背景:

new BrowserWindow({
  frame: false,
  transparent: true,
  // ...
})

CSS 加背景模糊:
background: rgba(255, 255, 255, 0.08);
backdrop-filter: blur(20px);
边缘吸附
主进程每 100ms 轮询窗口坐标,判断是否接近屏幕四边:
setInterval(() => {
  const pos = win.getPosition();
  const [x, y] = pos;
  if (y < 5) win.setPosition(x, 0);       // 顶部吸附
  if (y > screenHeight - 50) win.setY(screenHeight - win.getBounds().height); // 底部吸附
}, 100);
跨窗口状态持久化
所有窗口共享同一个 data.json,状态变化时写文件,各窗口监听变化重新读取。
多屏支持
用 win.getScreen()` 获取当前屏幕 bounds,坐标 clamp 在当前屏幕范围内,不会跑到副屏外面去。
项目结构
desk-widgets/
├── main.js              # 主进程(窗口管理/吸附/托盘)
├── preload.js           # 安全桥接层
├── shared/
│   ├── base.css         # 全局样式
│   └── widget.js        # 组件共用逻辑
└── widgets/
    ├── todo/
    ├── calendar/
    ├── goals/
    ├── weather/
    ├── sticky/
    └── launcher/
快速上手
git clone https://github.com/ferralina/desk-widgets.git
cd desk-widgets
npm install
npm start