我正在使用Electron并尝试开发托盘(菜单栏)应用程序。
我知道如何设置图标:
const {Tray} = require('electron')
appIcon = new Tray('/path/to/my/icon')
如何根据用户选择的主题(正常或黑暗)创建一个会改变颜色的图标(或选择另一个图标)?
在上面的例子中,我使用了一个黑暗的主题,所以我可以创建一个白色图标,但是当用户拥有正常的白色主题时会发生什么?
答案 0 :(得分:6)
你应该使用模板图像(只有黑色和清晰的颜色):https://github.com/electron/electron/blob/master/docs/api/native-image.md#template-image
这样,macOS会在正常主题时自动将托盘图标调整为黑色,在黑暗主题时自动调整为白色。
确保文件名以Template.png
结尾,否则无效!如果您定位hi-dpi设备,还要包含@2x.png
版本。
所以你的文件夹看起来像是:
.
├── main.js
├── IconTemplate.png
└── IconTemplate@2x.png
然后在main.js
:
const {Tray} = require('electron')
appIcon = new Tray('./IconTemplate.png')
答案 1 :(得分:0)
我们将SVG到PNG的托盘图标构建为黑白颜色,如下所示:
"build": "",
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"build": "",
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "12"
},
"main": "index.js",
"dependencies": {
"cookie-parser": "^1.4.5",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"firebase": "^7.22.0",
"firebase-admin": "^9.4.1",
"firebase-functions": "^3.11.0"
},
"devDependencies": {
"eslint": "^5.12.0",
"eslint-plugin-promise": "^4.0.1",
"firebase-functions-test": "^0.2.0"
},
"private": true
}
然后在主题更新中更新托盘图标,如下所示:
// File: build/build_tray_icon.ts
// Command: yarn run ts-node build/build_tray_icon.ts
import path from "path"
import sharp from "sharp";
import jsdom from "jsdom"
import fs from "fs-extra"
export async function generateTrayIcon(
{
outputFilename = "tray_icon", // e.g. output tray_icon_dark@2x.png
svgIconPath = path.resolve(__dirname, "../src/renderer/components/icon/logo.svg"),
outputFolder = path.resolve(__dirname, "./tray"),
dpiSuffix = "2x",
pixelSize = 32,
shouldUseDarkColors = false, // managed by electron.nativeTheme.shouldUseDarkColors
} = {}) {
outputFilename += shouldUseDarkColors ? "_dark" : ""
dpiSuffix = dpiSuffix !== "1x" ? `@${dpiSuffix}` : ""
const pngIconDestPath = path.resolve(outputFolder, `${outputFilename}${dpiSuffix}.png`)
try {
// Modify .SVG colors
const trayIconColor = shouldUseDarkColors ? "white" : "black";
const svgDom = await jsdom.JSDOM.fromFile(svgIconPath);
const svgRoot = svgDom.window.document.body.getElementsByTagName("svg")[0];
svgRoot.innerHTML += `<style>* {fill: ${trayIconColor} !important;}</style>`
const svgIconBuffer = Buffer.from(svgRoot.outerHTML);
// Resize and convert to .PNG
const pngIconBuffer: Buffer = await sharp(svgIconBuffer)
.resize({ width: pixelSize, height: pixelSize })
.png()
.toBuffer();
// Save icon
await fs.writeFile(pngIconDestPath, pngIconBuffer);
console.info(`[DONE]: Tray icon saved at "${pngIconDestPath}"`);
} catch (err) {
console.error(`[ERROR]: ${err}`);
}
}
// Run
const iconSizes: Record<string, number> = {
"1x": 16,
"2x": 32,
};
Object.entries(iconSizes).forEach(([dpiSuffix, pixelSize]) => {
generateTrayIcon({ dpiSuffix, pixelSize, shouldUseDarkColors: false });
generateTrayIcon({ dpiSuffix, pixelSize, shouldUseDarkColors: true });
});