Files
DadaoTask/tools/make-icons.py
T
steven d7c9670880
CI / backend (push) Canceled after 0s
feat(design): 主色改靛蓝 #4F46E5,Web 与安卓及 Logo 同步
- primary 换成 Indigo 阶(600 即 #4F46E5),中性色转 Slate 轴、纸面更冷更白
- 实心主色面(主按钮、工作区选中)用 600,链接/浅底文字仍用 700 保对比度
- 信息色 sky 调深到 #16697C,与靛蓝同屏能分清
- Logo / favicon / PWA 图标 / 安卓自适应图标统一为靛蓝底 + 白线 + 淡紫点,tools/make-icons.py 重新生成
- 文档与 e2e 断言同步(主题色 #4f46e5)
2026-11-02 15:33:26 +08:00

77 lines
2.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""按 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 = "#4F46E5"
LINE = "#FFFFFF"
DOT = "#C7D2FE"
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()