chore(branding): replace application logo with approved icon pack
Co-Authored-By: Claude Code <noreply@anthropic.com>
No files matched your search
|
Before Width: | Height: | Size: 288 KiB After Width: | Height: | Size: 291 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 283 KiB |
|
Before Width: | Height: | Size: 318 KiB After Width: | Height: | Size: 887 KiB |
|
Before Width: | Height: | Size: 318 KiB After Width: | Height: | Size: 887 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 918 B After Width: | Height: | Size: 867 B |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 229 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 508 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,47 @@
|
|||||||
|
Ycode 软件图标资源包
|
||||||
|
==================
|
||||||
|
|
||||||
|
采用版本
|
||||||
|
--------
|
||||||
|
本包采用“朝你举手的象牙精灵.png”,即用户指定的大圆脸、身体饱满、举手末端圆润的原版。
|
||||||
|
原始图片为 1254 × 1254 像素;所有尺寸均由同一原图导出,没有重新生成角色。
|
||||||
|
|
||||||
|
快速使用
|
||||||
|
--------
|
||||||
|
Windows 应用、可执行文件和安装程序:windows/ycode.ico
|
||||||
|
软件界面、侧边栏、关于页:按显示尺寸选择 png/ycode-尺寸.png
|
||||||
|
Windows 托盘:按实际 DPI 和所用框架选择 16、20、24、32、40、48 或 64 像素 PNG。
|
||||||
|
网页标签页:web/favicon.ico,也可使用 web/favicon-16.png、favicon-32.png。
|
||||||
|
网页或 PWA 常用图片:web/icon-192.png、web/icon-512.png。
|
||||||
|
网页图片使用现有红色圆角底板;未声明为可任意裁切的 maskable 图标。
|
||||||
|
|
||||||
|
尺寸清单
|
||||||
|
--------
|
||||||
|
PNG(均为正方形,文件名数字即边长):
|
||||||
|
16、20、24、30、32、36、40、48、60、64、72、80、96、128、144、180、192、256、384、512、768、1024。
|
||||||
|
|
||||||
|
Windows ICO 实际内嵌 15 个尺寸:
|
||||||
|
16、20、24、30、32、36、40、48、60、64、72、80、96、128、256。
|
||||||
|
|
||||||
|
favicon.ico 实际内嵌 3 个尺寸:16、32、48。
|
||||||
|
|
||||||
|
文件目录
|
||||||
|
--------
|
||||||
|
png/ 多尺寸 RGBA PNG
|
||||||
|
windows/ Windows 多尺寸应用图标
|
||||||
|
web/ favicon 与网页常用 PNG
|
||||||
|
source/ 1254 像素原图及导出母图
|
||||||
|
Ycode-Icon-Preview.png 浅色/深色背景和小尺寸预览
|
||||||
|
manifest.json 尺寸、格式及导出信息
|
||||||
|
checksums.sha256 包内文件校验值
|
||||||
|
|
||||||
|
导出说明
|
||||||
|
--------
|
||||||
|
PNG 保留红色圆角底板,底板外部透明,精灵为奶白色。
|
||||||
|
导出母图与所选原图逐字节一致,保留原始 RGBA、颜色、姿态、比例和画布尺寸。
|
||||||
|
本包只进行尺寸缩放和格式封装,没有再次生成、重绘、瘦身、改变表情或修改光影。
|
||||||
|
每个 PNG 从 1254 像素导出母图直接缩小,不逐级缩放,不放大低分辨率图片。
|
||||||
|
所有 PNG 为 RGBA;ICO 已逐层检查尺寸与像素。
|
||||||
|
这些是图形资源文件。应用图标如何绑定到窗口、任务栏和安装包,请按项目实际框架配置。
|
||||||
|
|
||||||
|
生成日期:2026-10-21
|
||||||
|
After Width: | Height: | Size: 291 KiB |
@@ -0,0 +1,33 @@
|
|||||||
|
337104a95c7796e5d596ce1d263be5e134380c263251d2c5768de089eba8e06e README.zh-CN.txt
|
||||||
|
58896c8593d7cf424c0f175b1c01c606abeafbce8088be6b54eeac0c3ea17260 Ycode-Icon-Preview.png
|
||||||
|
39cb370f4097e48e93a1ed98711ef392fc62bbc38d1f2d0ad5745cd66a93374c manifest.json
|
||||||
|
b3bfc76d637c4e7fef5c0655079736940b8a560ec19195d25585bd2eaf4a5794 png/ycode-1024.png
|
||||||
|
e3656c1694b3264f4e402b938e447b4ef4ade36dee5970a0add4530c51b6ce73 png/ycode-128.png
|
||||||
|
ab7cac48cae4959d37b27aa495bd183e7da1dea460c66b2e040bd1a521156dd0 png/ycode-144.png
|
||||||
|
17813635b4ebdb738aaf488e9cd90fed8075852b0b4959756498a8cffe828578 png/ycode-16.png
|
||||||
|
72cb2126929685153b2973185630599f703fcfcaba3cfe999da2b6e3f07588f4 png/ycode-180.png
|
||||||
|
268ec5dacee26dfa8472f2ef22e378e9bd077632106e8f999e8fc498bffe3e3b png/ycode-192.png
|
||||||
|
b03f6b2c0cb87d8a4e4dec41e815008bb095d386e83c6d41842a92511c95f920 png/ycode-20.png
|
||||||
|
b0ebfd3208863cd673ba156918395e7cc1b553ec3c52b9b4188e03b4e2cdac9f png/ycode-24.png
|
||||||
|
79af56168bd46ab0a27c203bb7e26ea54fe34ce4b051115927f30b0f15cc9c08 png/ycode-256.png
|
||||||
|
973c76202c110552b8dd19121a155d4200b279382909920d52fbf627149b3d4c png/ycode-30.png
|
||||||
|
9f0aa8db122580dbd444d13451619ca2f67ab000013a7ef798eae3c5a79bf0eb png/ycode-32.png
|
||||||
|
ccd924280b414e3bd29efe94caf94940554bf2f4b45c513d470ddf4769f5eb89 png/ycode-36.png
|
||||||
|
d829d21c7705d7cb1e1203235b326a735cc96b576bf9a84f39f304cf839b2b52 png/ycode-384.png
|
||||||
|
5e88346739baebbdf9952172e7adb7ef2e740dc580a95f3961ff67721fd23c7b png/ycode-40.png
|
||||||
|
b19031f7aa9d1c5f3e6bc5cbf7fc4586fca785e3a89d07178a010ea1fbf0df0c png/ycode-48.png
|
||||||
|
644c0d02e98af33d0d082eb8e980fce2ff4550c40e8727ffd17141d3eccf34e7 png/ycode-512.png
|
||||||
|
36c1e2562e3df995309cc17b4d16e36e0bfee6537907c312d50057a7c298e81c png/ycode-60.png
|
||||||
|
d7f98cf5dd8ec229cb11c5a4fb8d5a644699961bbfea2fcfd13232e5358b9e5b png/ycode-64.png
|
||||||
|
033c89b3e2b9e90d1216ebf3dc5b8fe6be0f582b0a289e8e3c2d6b21cfa94a28 png/ycode-72.png
|
||||||
|
bf1b1d1f3b1e8ea345e6c58b8cade7c43fe230a5a8fb6895eb7f470259906015 png/ycode-768.png
|
||||||
|
b0043bca0aa1436f7ae18ed88812ddbb7db1b5f4f87bc8a21333f571cc31ae05 png/ycode-80.png
|
||||||
|
3275f804551df785f10948af0bbc47a6fd98d0decf14d820443e87e0f3528fc4 png/ycode-96.png
|
||||||
|
ef6dcd133be5e19654d66408875e8d08a10cca6fd066edde3c25b58d05e97e98 source/ycode-approved-original-1254.png
|
||||||
|
ef6dcd133be5e19654d66408875e8d08a10cca6fd066edde3c25b58d05e97e98 source/ycode-export-master-1254.png
|
||||||
|
17813635b4ebdb738aaf488e9cd90fed8075852b0b4959756498a8cffe828578 web/favicon-16.png
|
||||||
|
9f0aa8db122580dbd444d13451619ca2f67ab000013a7ef798eae3c5a79bf0eb web/favicon-32.png
|
||||||
|
9f8b5bb578e08763389cf824f14ac1213149cbdeb7a8fad7f31926d2fc6f3e94 web/favicon.ico
|
||||||
|
268ec5dacee26dfa8472f2ef22e378e9bd077632106e8f999e8fc498bffe3e3b web/icon-192.png
|
||||||
|
644c0d02e98af33d0d082eb8e980fce2ff4550c40e8727ffd17141d3eccf34e7 web/icon-512.png
|
||||||
|
363e95118364550d34d9c2f268f8d8032e400cf4ebdf4594183c643fbf5ac466 windows/ycode.ico
|
||||||
@@ -0,0 +1,205 @@
|
|||||||
|
{
|
||||||
|
"product": "Ycode",
|
||||||
|
"asset_version": "rounded-original-v1",
|
||||||
|
"created_date": "2026-10-21",
|
||||||
|
"source_filename": "朝你举手的象牙精灵.png",
|
||||||
|
"source_dimensions": [
|
||||||
|
1254,
|
||||||
|
1254
|
||||||
|
],
|
||||||
|
"source_sha256": "ef6dcd133be5e19654d66408875e8d08a10cca6fd066edde3c25b58d05e97e98",
|
||||||
|
"png_sizes": [
|
||||||
|
16,
|
||||||
|
20,
|
||||||
|
24,
|
||||||
|
30,
|
||||||
|
32,
|
||||||
|
36,
|
||||||
|
40,
|
||||||
|
48,
|
||||||
|
60,
|
||||||
|
64,
|
||||||
|
72,
|
||||||
|
80,
|
||||||
|
96,
|
||||||
|
128,
|
||||||
|
144,
|
||||||
|
180,
|
||||||
|
192,
|
||||||
|
256,
|
||||||
|
384,
|
||||||
|
512,
|
||||||
|
768,
|
||||||
|
1024
|
||||||
|
],
|
||||||
|
"png_color_mode": "RGBA",
|
||||||
|
"resize_filter": "Lanczos",
|
||||||
|
"upscaled": false,
|
||||||
|
"alpha_cleanup": {
|
||||||
|
"applied": false,
|
||||||
|
"changed_pixels": 0,
|
||||||
|
"visible_artwork_changed": false
|
||||||
|
},
|
||||||
|
"ico_files": [
|
||||||
|
{
|
||||||
|
"path": "windows/ycode.ico",
|
||||||
|
"sizes": [
|
||||||
|
16,
|
||||||
|
20,
|
||||||
|
24,
|
||||||
|
30,
|
||||||
|
32,
|
||||||
|
36,
|
||||||
|
40,
|
||||||
|
48,
|
||||||
|
60,
|
||||||
|
64,
|
||||||
|
72,
|
||||||
|
80,
|
||||||
|
96,
|
||||||
|
128,
|
||||||
|
256
|
||||||
|
],
|
||||||
|
"verified_pixel_exact": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "web/favicon.ico",
|
||||||
|
"sizes": [
|
||||||
|
16,
|
||||||
|
32,
|
||||||
|
48
|
||||||
|
],
|
||||||
|
"verified_pixel_exact": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"path": "README.zh-CN.txt",
|
||||||
|
"bytes": 2175
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "Ycode-Icon-Preview.png",
|
||||||
|
"bytes": 297731
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-1024.png",
|
||||||
|
"bytes": 908586
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-128.png",
|
||||||
|
"bytes": 21738
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-144.png",
|
||||||
|
"bytes": 26190
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-16.png",
|
||||||
|
"bytes": 867
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-180.png",
|
||||||
|
"bytes": 37070
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-192.png",
|
||||||
|
"bytes": 40637
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-20.png",
|
||||||
|
"bytes": 1212
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-24.png",
|
||||||
|
"bytes": 1609
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-256.png",
|
||||||
|
"bytes": 65372
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-30.png",
|
||||||
|
"bytes": 2280
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-32.png",
|
||||||
|
"bytes": 2416
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-36.png",
|
||||||
|
"bytes": 2940
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-384.png",
|
||||||
|
"bytes": 135503
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-40.png",
|
||||||
|
"bytes": 3421
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-48.png",
|
||||||
|
"bytes": 4625
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-512.png",
|
||||||
|
"bytes": 234020
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-60.png",
|
||||||
|
"bytes": 6477
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-64.png",
|
||||||
|
"bytes": 7193
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-72.png",
|
||||||
|
"bytes": 8704
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-768.png",
|
||||||
|
"bytes": 520390
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-80.png",
|
||||||
|
"bytes": 10435
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "png/ycode-96.png",
|
||||||
|
"bytes": 13750
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "source/ycode-approved-original-1254.png",
|
||||||
|
"bytes": 1702366
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "source/ycode-export-master-1254.png",
|
||||||
|
"bytes": 1702366
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "web/favicon-16.png",
|
||||||
|
"bytes": 867
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "web/favicon-32.png",
|
||||||
|
"bytes": 2416
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "web/favicon.ico",
|
||||||
|
"bytes": 15086
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "web/icon-192.png",
|
||||||
|
"bytes": 40637
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "web/icon-512.png",
|
||||||
|
"bytes": 234020
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "windows/ycode.ico",
|
||||||
|
"bytes": 289599
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 887 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 867 B |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 132 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 229 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 508 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 867 B |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 229 KiB |
|
After Width: | Height: | Size: 283 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 229 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
@@ -1,115 +1,32 @@
|
|||||||
/**
|
/**
|
||||||
* 生成 YCode 应用图标资产。
|
* 从已确认的图标包同步 YCode 应用图标,不重新绘制或缩放原图。
|
||||||
*
|
* 输入:resources/branding/(原图、各尺寸 PNG、Windows ICO 和预览)
|
||||||
* 输入:build/icon.svg(唯一矢量源)
|
|
||||||
* 输出:build/icon.ico、build/icon.png、resources/icon.png、build/icon-preview.png
|
|
||||||
*
|
|
||||||
* 图案是深红旗面 + 按国旗制式排布的五颗金星(一大四小,3:1),
|
|
||||||
* 星群坐标由 scripts/star-layout.mjs 算出,这里只负责栅格化与打包。
|
|
||||||
*
|
|
||||||
* 用法:node scripts/gen-icon.mjs
|
* 用法:node scripts/gen-icon.mjs
|
||||||
*/
|
*/
|
||||||
import { Resvg } from '@resvg/resvg-js'
|
import { copyFileSync, mkdirSync, readdirSync } from 'node:fs'
|
||||||
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs'
|
|
||||||
import { dirname, join } from 'node:path'
|
import { dirname, join } from 'node:path'
|
||||||
import { fileURLToPath } from 'node:url'
|
import { fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
const root = join(dirname(fileURLToPath(import.meta.url)), '..')
|
const root = join(dirname(fileURLToPath(import.meta.url)), '..')
|
||||||
const buildDir = join(root, 'build')
|
const packDir = join(root, 'resources', 'branding')
|
||||||
const resourcesDir = join(root, 'resources')
|
|
||||||
|
|
||||||
const masterSvg = readFileSync(join(buildDir, 'icon.svg'), 'utf8')
|
function copy(source, destination) {
|
||||||
|
const target = join(root, destination)
|
||||||
const ICO_SIZES = [16, 24, 32, 48, 64, 128, 256]
|
mkdirSync(dirname(target), { recursive: true })
|
||||||
|
copyFileSync(join(packDir, source), target)
|
||||||
function render(svg, size) {
|
|
||||||
return new Resvg(svg, { fitTo: { mode: 'width', value: size } }).render().asPng()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function pick() {
|
copy('windows/ycode.ico', 'build/icon.ico')
|
||||||
return masterSvg
|
copy('png/ycode-1024.png', 'build/icon.png')
|
||||||
|
copy('png/ycode-512.png', 'resources/icon.png')
|
||||||
|
copy('png/ycode-32.png', 'resources/tray.png')
|
||||||
|
copy('Ycode-Icon-Preview.png', 'build/icon-preview.png')
|
||||||
|
copy('png/ycode-128.png', 'src/renderer/src/assets/ycode.png')
|
||||||
|
copy('web/favicon.ico', 'src/renderer/public/favicon.ico')
|
||||||
|
|
||||||
|
for (const filename of readdirSync(join(packDir, 'png'))) {
|
||||||
|
const match = /^ycode-(\d+)\.png$/.exec(filename)
|
||||||
|
if (match) copy(`png/${filename}`, `build/sizes/icon-${match[1]}.png`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 组装 Windows ICO:每个尺寸内嵌一张 PNG(Vista 及以后支持)。 */
|
console.log('YCode 图标已同步:Windows ICO、窗口、托盘、界面、favicon 和各尺寸 PNG')
|
||||||
function buildIco(entries) {
|
|
||||||
const header = Buffer.alloc(6)
|
|
||||||
header.writeUInt16LE(0, 0)
|
|
||||||
header.writeUInt16LE(1, 2)
|
|
||||||
header.writeUInt16LE(entries.length, 4)
|
|
||||||
|
|
||||||
const dirEntries = []
|
|
||||||
let offset = 6 + 16 * entries.length
|
|
||||||
for (const { size, png } of entries) {
|
|
||||||
const entry = Buffer.alloc(16)
|
|
||||||
entry.writeUInt8(size >= 256 ? 0 : size, 0)
|
|
||||||
entry.writeUInt8(size >= 256 ? 0 : size, 1)
|
|
||||||
entry.writeUInt8(0, 2)
|
|
||||||
entry.writeUInt8(0, 3)
|
|
||||||
entry.writeUInt16LE(1, 4)
|
|
||||||
entry.writeUInt16LE(32, 6)
|
|
||||||
entry.writeUInt32LE(png.length, 8)
|
|
||||||
entry.writeUInt32LE(offset, 12)
|
|
||||||
offset += png.length
|
|
||||||
dirEntries.push(entry)
|
|
||||||
}
|
|
||||||
|
|
||||||
return Buffer.concat([header, ...dirEntries, ...entries.map((e) => e.png)])
|
|
||||||
}
|
|
||||||
|
|
||||||
mkdirSync(resourcesDir, { recursive: true })
|
|
||||||
|
|
||||||
const icoEntries = ICO_SIZES.map((size) => ({ size, png: render(pick(), size) }))
|
|
||||||
writeFileSync(join(buildDir, 'icon.ico'), buildIco(icoEntries))
|
|
||||||
|
|
||||||
writeFileSync(join(buildDir, 'icon.png'), render(masterSvg, 1024))
|
|
||||||
writeFileSync(join(resourcesDir, 'icon.png'), render(masterSvg, 512))
|
|
||||||
// 托盘:Windows 通知区域按 16/20/24/32 取用,给 32px 让系统自行缩放
|
|
||||||
writeFileSync(join(resourcesDir, 'tray.png'), render(masterSvg, 32))
|
|
||||||
|
|
||||||
// 备用图:常用尺寸各出一张 PNG,供托盘、商店页、文档等场景直接取用
|
|
||||||
const PNG_SIZES = [16, 20, 24, 32, 40, 48, 64, 96, 128, 180, 256, 512, 1024]
|
|
||||||
const sizesDir = join(buildDir, 'sizes')
|
|
||||||
mkdirSync(sizesDir, { recursive: true })
|
|
||||||
for (const size of PNG_SIZES) {
|
|
||||||
writeFileSync(join(sizesDir, `icon-${size}.png`), render(pick(), size))
|
|
||||||
}
|
|
||||||
|
|
||||||
// 对照表:浅色与深色背景下,各尺寸的真实观感
|
|
||||||
const sampleSizes = [128, 64, 48, 32, 16]
|
|
||||||
function tile(size) {
|
|
||||||
return render(pick(), size).toString('base64')
|
|
||||||
}
|
|
||||||
const rows = [
|
|
||||||
{ label: '浅色任务栏', bg: '#FFFFFF', fg: '#475467' },
|
|
||||||
{ label: '深色任务栏', bg: '#202124', fg: '#D0D5DD' }
|
|
||||||
]
|
|
||||||
let y = 78
|
|
||||||
const rowSvg = rows
|
|
||||||
.map((row) => {
|
|
||||||
let x = 150
|
|
||||||
const imgs = sampleSizes
|
|
||||||
.map((size) => {
|
|
||||||
const markup = `<image x="${x}" y="${y + (128 - size) / 2}" width="${size}" height="${size}" href="data:image/png;base64,${tile(size)}"/>`
|
|
||||||
x += size + 28
|
|
||||||
return markup
|
|
||||||
})
|
|
||||||
.join('')
|
|
||||||
const label = `<text x="40" y="${y + 68}" font-size="13" fill="${row.fg}" font-family="system-ui, 'Microsoft YaHei', sans-serif">${row.label}</text>`
|
|
||||||
const block = `<rect x="20" y="${y}" width="640" height="128" rx="10" fill="${row.bg}"/>${label}${imgs}`
|
|
||||||
y += 152
|
|
||||||
return block
|
|
||||||
})
|
|
||||||
.join('')
|
|
||||||
|
|
||||||
const previewSvg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 680 ${y + 10}" width="680" height="${y + 10}">
|
|
||||||
<rect width="680" height="${y + 10}" fill="#F7F8FA"/>
|
|
||||||
<text x="20" y="34" font-size="15" font-weight="500" fill="#1F2328" font-family="system-ui, 'Microsoft YaHei', sans-serif">YCode 图标:128 / 64 / 48 / 32 / 16 px 实际尺寸对照</text>
|
|
||||||
<text x="20" y="56" font-size="12" fill="#667085" font-family="system-ui, 'Microsoft YaHei', sans-serif">五颗星按国旗制式:一大四小(3:1),四颗小星各有一角尖对准大星中心;旗面为深红渐变+柔和光泽</text>
|
|
||||||
${rowSvg}
|
|
||||||
</svg>`
|
|
||||||
|
|
||||||
writeFileSync(join(buildDir, 'icon-preview.png'), new Resvg(previewSvg, { fitTo: { mode: 'width', value: 1360 } }).render().asPng())
|
|
||||||
|
|
||||||
console.log('icon.ico', icoEntries.length, 'sizes')
|
|
||||||
console.log('icon.png / resources/icon.png / icon-preview.png done')
|
|
||||||
console.log('build/sizes/icon-{', PNG_SIZES.join(','), '}.png done')
|
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
http-equiv="Content-Security-Policy"
|
http-equiv="Content-Security-Policy"
|
||||||
content="default-src 'self'; script-src 'self' 'unsafe-inline'; worker-src 'self' blob:; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https: http:; font-src 'self' data:; connect-src 'self' ws: http://localhost:*; object-src 'none'; base-uri 'none'"
|
content="default-src 'self'; script-src 'self' 'unsafe-inline'; worker-src 'self' blob:; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https: http:; font-src 'self' data:; connect-src 'self' ws: http://localhost:*; object-src 'none'; base-uri 'none'"
|
||||||
/>
|
/>
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
<title>YCode</title>
|
<title>YCode</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 21 KiB |
@@ -1,5 +1,6 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import type { AppInfo } from '@shared/types'
|
import type { AppInfo } from '@shared/types'
|
||||||
|
import ycodeLogo from '../assets/ycode.png'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onClose(): void
|
onClose(): void
|
||||||
@@ -18,7 +19,7 @@ export default function AboutDialog({ onClose }: Props): React.JSX.Element {
|
|||||||
<h2 className="dialog__title">关于 YCode</h2>
|
<h2 className="dialog__title">关于 YCode</h2>
|
||||||
|
|
||||||
<div className="about__brand">
|
<div className="about__brand">
|
||||||
<span className="about__logo">Y</span>
|
<img className="about__logo" src={ycodeLogo} alt="YCode" />
|
||||||
<div>
|
<div>
|
||||||
<div className="about__name">{info?.name ?? 'YCode'}</div>
|
<div className="about__name">{info?.name ?? 'YCode'}</div>
|
||||||
<div className="about__version">版本 {info?.version ?? '—'}</div>
|
<div className="about__version">版本 {info?.version ?? '—'}</div>
|
||||||
|
|||||||
@@ -1315,13 +1315,8 @@ html[data-theme='dark'] .btn-stop {
|
|||||||
width: var(--yc-size-10);
|
width: var(--yc-size-10);
|
||||||
height: var(--yc-size-10);
|
height: var(--yc-size-10);
|
||||||
flex: none;
|
flex: none;
|
||||||
display: grid;
|
display: block;
|
||||||
place-items: center;
|
object-fit: contain;
|
||||||
border-radius: var(--yc-radius-xl);
|
|
||||||
background: var(--yc-brand-8);
|
|
||||||
color: var(--yc-white-100);
|
|
||||||
font-size: var(--yc-font-size-8, 20px);
|
|
||||||
font-weight: var(--yc-font-weight-700);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.about__name {
|
.about__name {
|
||||||
|
|||||||