bcf99ec454
deploy werewolf / build-and-deploy (push) Successful in 1m1s
- vite-plugin-pwa(injectManifest)自定义 SW:install 逐个抓取并向页面广播进度, cache-first 服务,导航离线回退 index.html,缓存版本随清单哈希自动淘汰旧缓存 - 全屏 modal 进度条(src/pwa.ts),反映首屏预缓存真实下载进度 - 牌图 mozjpeg 压缩 + 限长边 900px,每张 ≤200K(21.2MB→2.8MB) - 生成 PWA 图标 + manifest + apple-touch meta,index.html 接入 - 新增脚本:npm run gen:icons / compress:images
47 lines
1.9 KiB
JavaScript
47 lines
1.9 KiB
JavaScript
// 从 public/werewolf/back.jpg 生成 PWA 图标。
|
|
// 运行: npm run gen:icons
|
|
import sharp from 'sharp'
|
|
import { mkdir } from 'node:fs/promises'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { dirname, resolve } from 'node:path'
|
|
|
|
const here = dirname(fileURLToPath(import.meta.url))
|
|
const pub = resolve(here, '../public')
|
|
const src = resolve(pub, 'werewolf/back.jpg')
|
|
|
|
// 卡背是竖图,狼头菱形大致在水平居中、垂直 ~46% 处。
|
|
// 裁一个聚焦狼头 logo 的方形区域作为图标基底(按实际尺寸夹紧,避免越界)。
|
|
const meta = await sharp(src).metadata()
|
|
const SIDE = Math.min(meta.width, Math.round(meta.width * 0.82), meta.height)
|
|
const left = Math.round(Math.max(0, Math.min(meta.width - SIDE, meta.width / 2 - SIDE / 2)))
|
|
const top = Math.round(Math.max(0, Math.min(meta.height - SIDE, meta.height * 0.46 - SIDE / 2)))
|
|
const square = await sharp(src)
|
|
.extract({ left, top, width: SIDE, height: SIDE })
|
|
.toBuffer()
|
|
|
|
const RED = { r: 0xc0, g: 0x39, b: 0x2b, alpha: 1 } // 贴近卡面红,用于 maskable 安全区留白
|
|
|
|
async function out(name, size, { maskable = false } = {}) {
|
|
await mkdir(pub, { recursive: true })
|
|
const target = resolve(pub, name)
|
|
if (maskable) {
|
|
// maskable: 内容缩到 ~80%,四周用卡红留白,保证安全区不被裁切
|
|
const inner = Math.round(size * 0.8)
|
|
const fg = await sharp(square).resize(inner, inner).toBuffer()
|
|
await sharp({ create: { width: size, height: size, channels: 4, background: RED } })
|
|
.composite([{ input: fg, gravity: 'center' }])
|
|
.png()
|
|
.toFile(target)
|
|
} else {
|
|
await sharp(square).resize(size, size).png().toFile(target)
|
|
}
|
|
console.log('wrote', name)
|
|
}
|
|
|
|
await out('pwa-192x192.png', 192)
|
|
await out('pwa-512x512.png', 512)
|
|
await out('maskable-icon-512x512.png', 512, { maskable: true })
|
|
await out('apple-touch-icon-180x180.png', 180)
|
|
await out('favicon-48x48.png', 48)
|
|
console.log('done')
|