Files
opencode/services/site/script/measure-logos.ts

56 lines
2.5 KiB
TypeScript

#!/usr/bin/env bun
// Measures the home logo row's logos and the tool wordmarks with logo-soup (https://github.com/johannschopplich/logo-soup)
// and writes their metrics to src/component/site/logo-metrics.ts, where LogoWall sizes them.
// logo-soup and sharp install into a temporary folder, so the app takes no dependency on them.
// Run from packages/console/app: bun script/measure-logos.ts
import { mkdtemp, rm } from "fs/promises"
import { tmpdir } from "os"
import { dirname, join } from "path"
import { fileURLToPath } from "url"
const root = join(dirname(fileURLToPath(import.meta.url)), "..")
const tmp = await mkdtemp(join(tmpdir(), "logo-soup-"))
await Bun.$`bun add logo-soup@0.2.3`.cwd(tmp).quiet()
const soup: {
analyzeDirectory: (
dir: string,
options: { extensions: string[] },
) => Promise<Map<string, { contentRatio: number; pixelDensity: number; visualCenterY: number }>>
} = await import(join(tmp, "node_modules/logo-soup/dist/index.mjs"))
const round = (value: number) => Math.round(value * 1000) / 1000
const folders = await Promise.all(
[
["companies", "companies"],
["providers", "providers"],
["toolWordmarks", "tools/wordmarks"],
].map(async ([key, folder]) => {
const metrics = await soup.analyzeDirectory(join(root, "public/logos", folder), { extensions: ["svg"] })
return [
` ${key}: {`,
...[...metrics]
.toSorted(([a], [b]) => a.localeCompare(b))
.map(
([file, item]) =>
` "${file.replace(/\.svg$/, "")}": { aspect: ${round(item.contentRatio)}, density: ${round(item.pixelDensity)}, centerY: ${round(item.visualCenterY)} },`,
),
" },",
]
}),
)
await rm(tmp, { recursive: true, force: true })
await Bun.write(
join(root, "src/component/site/logo-metrics.ts"),
[
"// Generated by script/measure-logos.ts with logo-soup. Do not edit; rerun the script after changing",
"// public/logos/companies, public/logos/providers or public/logos/tools/wordmarks. aspect is the ink's width / height (each SVG's",
"// viewBox is cropped to its ink), density the share of that box that is ink, and centerY the visual",
"// centre's offset from the box centre in fractions of the height.",
"export const logoMetrics: Record<string, Record<string, { aspect: number; density: number; centerY: number }>> = {",
...folders.flat(),
"}",
"",
].join("\n"),
)
await Bun.$`bunx prettier --write src/component/site/logo-metrics.ts`.cwd(root).quiet()
console.log(`Wrote ${folders.flat().length} lines to src/component/site/logo-metrics.ts`)