feat(design): 主色由墨松绿改为景泰蓝蓝系,Logo 与图标同步
CI / backend (push) Canceled after 0s

纸白底改冷调与主色同轴;语义色 sage/wheat/rust 不变,sky 提亮与主色区分。Logo 三段线改浅蓝白、圆点改亮蓝;favicon/PWA 图标/安卓自适应图标/状态栏一并重绘,新增 tools/make-icons.py 作为唯一出处。
This commit is contained in:
2026-11-01 18:48:26 +08:00
parent 694b643683
commit b3cd115bd9
19 changed files with 146 additions and 66 deletions
+76
View File
@@ -0,0 +1,76 @@
"""按 Web Logo(icons.tsx 的 <Logo/>)重绘 PWA 图标:景泰蓝底 + 三条浅蓝白线 + 一点亮蓝。
用法:python tools/make-icons.py
输出覆盖 web/public/icons/*.png(与 SVG 同一套比例:64 画布,rx=18,线宽 4,点半径 6)。
"""
from __future__ import annotations
from pathlib import Path
from PIL import Image, ImageDraw
ROOT = Path(__file__).resolve().parents[1]
OUT = ROOT / "web" / "public" / "icons"
BG = "#274B73"
LINE = "#EAF3FB"
DOT = "#5CA8E8"
SS = 8 # 超采样倍数,边缘才不毛
def draw(size: int, *, rounded: bool, inset: float = 0.0) -> Image.Image:
"""在 size×size 上画 logo。inset 是安全区留白比例(maskable 图标要留)。"""
big = size * SS
img = Image.new("RGBA", (big, big), (0, 0, 0, 0))
d = ImageDraw.Draw(img)
if rounded:
d.rounded_rectangle([0, 0, big - 1, big - 1], radius=big * 18 / 64, fill=BG)
else:
d.rectangle([0, 0, big, big], fill=BG)
# 64 画布坐标 → 像素;inset 让图形整体缩小居中(给 maskable 留安全区)
scale = big / 64 * (1 - 2 * inset)
off = big * inset
def box(x: float, y: float) -> tuple[float, float]:
return off + x * scale, off + y * scale
stroke = max(1, round(4 * scale))
for y, x2 in ((23, 46), (32, 37), (41, 30)):
x1, yy = box(18, y)
d.line([x1, yy, *box(x2, y)], fill=LINE, width=stroke)
# 圆头:PIL 的 line 没有 cap,用小圆补两端
r = stroke / 2
for cx, cy in ((x1, yy), box(x2, y)):
d.ellipse([cx - r, cy - r, cx + r, cy + r], fill=LINE)
cx, cy = box(46, 41)
r = 6 * scale
d.ellipse([cx - r, cy - r, cx + r, cy + r], fill=DOT)
return img.resize((size, size), Image.LANCZOS)
def main() -> None:
OUT.mkdir(parents=True, exist_ok=True)
# 圆角版:favicon 之外的常规 PWA 图标
draw(192, rounded=True).save(OUT / "icon-192.png")
draw(512, rounded=True).save(OUT / "icon-512.png")
# iOS 会自己裁圆角,底图必须是方的
draw(180, rounded=False).save(OUT / "apple-touch-icon.png")
# maskable:图形缩进 12% 安全区
draw(512, rounded=False, inset=0.12).save(OUT / "maskable-512.png")
# 文档里引用的安卓图标预览
preview = ROOT / "2.Design" / "screens" / "android-icon-512.png"
preview.parent.mkdir(parents=True, exist_ok=True)
draw(512, rounded=True).save(preview)
for p in sorted(OUT.glob("*.png")):
print(p.relative_to(ROOT), Image.open(p).size)
print(preview.relative_to(ROOT), Image.open(preview).size)
if __name__ == "__main__":
main()