initial commit

This commit is contained in:
2026-08-08 18:34:12 +08:00
commit 0d7438e368
82 changed files with 17407 additions and 0 deletions

94
scripts/gen-tray-icon.mjs Normal file
View File

@@ -0,0 +1,94 @@
import { deflateSync } from 'zlib'
import { writeFileSync, mkdirSync } from 'fs'
import { dirname, resolve } from 'path'
import { fileURLToPath } from 'url'
/** 生成一个简洁的托盘图标(粉色唱片盘),输出到 resources/tray.png */
const __dirname = dirname(fileURLToPath(import.meta.url))
const SIZE = 32
const cx = SIZE / 2 - 0.5
const cy = SIZE / 2 - 0.5
const rOuter = 15
const rHole = 4
function px(x, y) {
const dx = x - cx
const dy = y - cy
const d = Math.sqrt(dx * dx + dy * dy)
// 抗锯齿边缘
const edge = (r) => Math.max(0, Math.min(1, r - d + 0.5))
const inDisc = edge(rOuter)
const inHole = edge(rHole)
if (inDisc <= 0) return [0, 0, 0, 0]
// 唱片主体粉色,中心孔洞白色
const pink = [255, 55, 95]
const white = [255, 255, 255]
const a = Math.round(255 * inDisc)
if (inHole > 0) {
const t = inHole
return [
Math.round(pink[0] * (1 - t) + white[0] * t),
Math.round(pink[1] * (1 - t) + white[1] * t),
Math.round(pink[2] * (1 - t) + white[2] * t),
a
]
}
return [pink[0], pink[1], pink[2], a]
}
// 构造原始 RGBA 扫描行(每行前置 filter 0
const raw = Buffer.alloc((SIZE * 4 + 1) * SIZE)
let p = 0
for (let y = 0; y < SIZE; y++) {
raw[p++] = 0
for (let x = 0; x < SIZE; x++) {
const [r, g, b, a] = px(x, y)
raw[p++] = r
raw[p++] = g
raw[p++] = b
raw[p++] = a
}
}
const crcTable = (() => {
const t = []
for (let n = 0; n < 256; n++) {
let c = n
for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1
t[n] = c >>> 0
}
return t
})()
function crc32(buf) {
let c = 0xffffffff
for (let i = 0; i < buf.length; i++) c = crcTable[(c ^ buf[i]) & 0xff] ^ (c >>> 8)
return (c ^ 0xffffffff) >>> 0
}
function chunk(type, data) {
const len = Buffer.alloc(4)
len.writeUInt32BE(data.length, 0)
const typeBuf = Buffer.from(type, 'ascii')
const body = Buffer.concat([typeBuf, data])
const crc = Buffer.alloc(4)
crc.writeUInt32BE(crc32(body), 0)
return Buffer.concat([len, body, crc])
}
const sig = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])
const ihdr = Buffer.alloc(13)
ihdr.writeUInt32BE(SIZE, 0)
ihdr.writeUInt32BE(SIZE, 4)
ihdr[8] = 8 // bit depth
ihdr[9] = 6 // color type RGBA
const png = Buffer.concat([
sig,
chunk('IHDR', ihdr),
chunk('IDAT', deflateSync(raw)),
chunk('IEND', Buffer.alloc(0))
])
const out = resolve(__dirname, '../resources/tray.png')
mkdirSync(dirname(out), { recursive: true })
writeFileSync(out, png)
console.log('wrote', out, png.length, 'bytes')