纸白底改冷调与主色同轴;语义色 sage/wheat/rust 不变,sky 提亮与主色区分。Logo 三段线改浅蓝白、圆点改亮蓝;favicon/PWA 图标/安卓自适应图标/状态栏一并重绘,新增 tools/make-icons.py 作为唯一出处。
This commit is contained in:
@@ -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()
|
||||
Reference in New Issue
Block a user