From 567032296aecaad13408bdc17d108ec7c57fb4a8 Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Mon, 3 Nov 2025 08:31:01 -0600 Subject: [PATCH] feat: dynamically crop favicon to active beads for maximum size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement bounding box calculation to crop the favicon SVG to show only the active beads, maximizing their size within the 100x100 icon canvas. Algorithm: 1. Parse rendered SVG to find all active bead positions (via regex) 2. Calculate bounding box with 15px padding 3. Compute optimal scale to fit within 96x96 (leaving border room) 4. Apply transform: translate + scale + translate to crop and center Results: - Day 1-9 (few beads): scale ~1.14 (2.4x larger than before) - Day 31 (many beads): scale ~0.74 (1.5x larger than before) - Original fixed scale: 0.48 This uses no external dependencies - just regex parsing of the rendered SVG to extract active bead coordinates. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- apps/web/scripts/generateDayIcon.tsx | 68 ++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/apps/web/scripts/generateDayIcon.tsx b/apps/web/scripts/generateDayIcon.tsx index eaa502ab..453ad387 100644 --- a/apps/web/scripts/generateDayIcon.tsx +++ b/apps/web/scripts/generateDayIcon.tsx @@ -19,6 +19,48 @@ function extractSvgContent(markup: string): string { return svgMatch[1] } +// Calculate bounding box of active beads from rendered SVG +interface BoundingBox { + minX: number + minY: number + maxX: number + maxY: number +} + +function getActiveBeadsBoundingBox(svgContent: string, scaleFactor: number): BoundingBox { + // Parse all active bead transforms: + const activeBeadRegex = + / - - + + ${svgContent}