|
| 1 | +/** |
| 2 | + * Calculates the ideal cover image dimensions based on the cover type, |
| 3 | + * page layout, and viewport constraints. |
| 4 | + * |
| 5 | + * The dimensions are optimized for: |
| 6 | + * - Hero covers: max-w-3xl (768px) on regular pages, max-w-screen-2xl (1536px) on wide pages |
| 7 | + * - Full covers: Can expand to full viewport width with negative margins (up to ~1920px+ on large screens) |
| 8 | + * - Responsive sizes: 768px (mobile), 1024px (tablet), up to 1920px+ (large desktop) |
| 9 | + * |
| 10 | + * The recommended aspect ratio is optimized to work well across all these scenarios. |
| 11 | + */ |
| 12 | + |
| 13 | +export const DEFAULT_COVER_HEIGHT = 240; |
| 14 | + |
| 15 | +/** |
| 16 | + * Calculate recommended cover image dimensions based on actual rendering widths. |
| 17 | + * |
| 18 | + * Analysis of actual rendering widths: |
| 19 | + * - Hero, regular page: max-w-3xl = 768px |
| 20 | + * - Hero, wide page: max-w-screen-2xl = 1536px |
| 21 | + * - Full cover (mobile): ~768px (full viewport minus padding) |
| 22 | + * - Full cover (tablet): ~1024px (full viewport minus padding) |
| 23 | + * - Full cover (desktop): Can be 768px (hero regular) to ~1920px (full wide) on large screens |
| 24 | + * |
| 25 | + * The recommended aspect ratio (4:1) is a standard format that works well for: |
| 26 | + * - Default height of 240px → 960px width (close to tablet size of 1024px) |
| 27 | + * - Works well when cropped to 768px (hero regular), 1024px (tablet), 1536px (hero wide), and 1920px (full wide) |
| 28 | + * - With `object-cover`, images maintain their natural aspect ratio while filling the container, |
| 29 | + * so the 4:1 ratio provides good coverage across all scenarios |
| 30 | + * |
| 31 | + * This ratio ensures images look good across all scenarios (hero/full, regular/wide, all viewports) |
| 32 | + * while maintaining good image quality for responsive srcSet generation and being easy to remember. |
| 33 | + * |
| 34 | + * @param height - The cover height in pixels (default: 240) |
| 35 | + * @returns Recommended width and height for the cover image |
| 36 | + */ |
| 37 | +export function getRecommendedCoverDimensions(height: number = DEFAULT_COVER_HEIGHT): { |
| 38 | + width: number; |
| 39 | + height: number; |
| 40 | +} { |
| 41 | + // Standard 4:1 aspect ratio - a common and easy-to-work-with format |
| 42 | + // At 240px height: 960px width |
| 43 | + // This ratio works well for: |
| 44 | + // - Hero covers on regular pages (768px width) - image will scale to cover |
| 45 | + // - Hero covers on wide pages (1536px width) - image will scale to cover |
| 46 | + // - Full covers across all breakpoints (768px - 1920px+) - image will scale proportionally |
| 47 | + // |
| 48 | + // Since we use `object-cover`, the image will scale to fill the container while maintaining |
| 49 | + // its aspect ratio, so the 4:1 ratio provides excellent coverage across all scenarios. |
| 50 | + // |
| 51 | + // Examples for different heights: |
| 52 | + // - 240px height → 960px width (recommended for default) |
| 53 | + // - 400px height → 1600px width (recommended for taller covers) |
| 54 | + // - 500px height → 2000px width (recommended for very tall covers) |
| 55 | + const aspectRatio = 4; |
| 56 | + |
| 57 | + return { |
| 58 | + width: Math.round(height * aspectRatio), |
| 59 | + height, |
| 60 | + }; |
| 61 | +} |
| 62 | + |
| 63 | +/** |
| 64 | + * Get the maximum cover width based on cover type and page layout. |
| 65 | + * Used for determining the upper bound of image dimensions. |
| 66 | + */ |
| 67 | +export function getMaxCoverWidth(coverType: 'hero' | 'full', isWidePage: boolean): number { |
| 68 | + if (coverType === 'hero') { |
| 69 | + // Hero covers: max-w-3xl (768px) or max-w-screen-2xl (1536px) |
| 70 | + return isWidePage ? 1536 : 768; |
| 71 | + } |
| 72 | + // Full covers can expand to viewport width, typically up to 1920px on large screens |
| 73 | + // Accounting for some margins, we use 1920px as the maximum |
| 74 | + return 1920; |
| 75 | +} |
0 commit comments