diff --git a/README.md b/README.md index 6e558a4e..8867fc87 100644 --- a/README.md +++ b/README.md @@ -43,29 +43,32 @@ The `user` field is the only required option. All other fields are optional. If the `theme` parameter is specified, any color customizations specified will be applied on top of the theme, overriding the theme's values. -| Parameter | Details | Example | -| :------------------: | :----------------------------------------------: | :------------------------------------------------------------------------------------------------: | -| `user` | GitHub username to show stats for | `DenverCoder1` | -| `theme` | The theme to apply (Default: `default`) | `dark`, `radical`, etc. [🎨➜](./docs/themes.md) | -| `hide_border` | Make the border transparent (Default: `false`) | `true` or `false` | -| `border_radius` | Set the roundness of the edges (Default: `4.5`) | Number `0` (sharp corners) to `248` (ellipse) | -| `background` | Background color (eg. `f2f2f2`, `35,d22,00f`) | **hex code** without `#`, **css color**, or gradient in the form `angle,start_color,...,end_color` | -| `border` | Border color | **hex code** without `#` or **css color** | -| `stroke` | Stroke line color between sections | **hex code** without `#` or **css color** | -| `ring` | Color of the ring around the current streak | **hex code** without `#` or **css color** | -| `fire` | Color of the fire in the ring | **hex code** without `#` or **css color** | -| `currStreakNum` | Current streak number | **hex code** without `#` or **css color** | -| `sideNums` | Total and longest streak numbers | **hex code** without `#` or **css color** | -| `currStreakLabel` | Current streak label | **hex code** without `#` or **css color** | -| `sideLabels` | Total and longest streak labels | **hex code** without `#` or **css color** | -| `dates` | Date range text color | **hex code** without `#` or **css color** | -| `date_format` | Date format pattern or empty for locale format | See note below on [📅 Date Formats](#-date-formats) | -| `locale` | Locale for labels and numbers (Default: `en`) | ISO 639-1 code - See [🗪 Locales](#-locales) | -| `type` | Output format (Default: `svg`) | Current options: `svg`, `png` or `json` | -| `mode` | Streak mode (Default: `daily`) | `daily` (contribute daily) or `weekly` (contribute once per Sun-Sat week) | -| `exclude_days` | List of days of the week to exclude from streaks | Comma-separated list of day abbreviations (Sun,Mon,Tue,Wed,Thu,Fri,Sat) e.g. `Sun,Sat` | -| `disable_animations` | Disable SVG animations (Default: `false`) | `true` or `false` | -| `card_width` | Width of the card in pixels (Default: `495`) | Integer greater than or equal to `290` | +| Parameter | Details | Example | +| :------------------------: | :----------------------------------------------: | :------------------------------------------------------------------------------------------------: | +| `user` | GitHub username to show stats for | `DenverCoder1` | +| `theme` | The theme to apply (Default: `default`) | `dark`, `radical`, etc. [🎨➜](./docs/themes.md) | +| `hide_border` | Make the border transparent (Default: `false`) | `true` or `false` | +| `border_radius` | Set the roundness of the edges (Default: `4.5`) | Number `0` (sharp corners) to `248` (ellipse) | +| `background` | Background color (eg. `f2f2f2`, `35,d22,00f`) | **hex code** without `#`, **css color**, or gradient in the form `angle,start_color,...,end_color` | +| `border` | Border color | **hex code** without `#` or **css color** | +| `stroke` | Stroke line color between sections | **hex code** without `#` or **css color** | +| `ring` | Color of the ring around the current streak | **hex code** without `#` or **css color** | +| `fire` | Color of the fire in the ring | **hex code** without `#` or **css color** | +| `currStreakNum` | Current streak number | **hex code** without `#` or **css color** | +| `sideNums` | Total and longest streak numbers | **hex code** without `#` or **css color** | +| `currStreakLabel` | Current streak label | **hex code** without `#` or **css color** | +| `sideLabels` | Total and longest streak labels | **hex code** without `#` or **css color** | +| `dates` | Date range text color | **hex code** without `#` or **css color** | +| `date_format` | Date format pattern or empty for locale format | See note below on [📅 Date Formats](#-date-formats) | +| `locale` | Locale for labels and numbers (Default: `en`) | ISO 639-1 code - See [🗪 Locales](#-locales) | +| `type` | Output format (Default: `svg`) | Current options: `svg`, `png` or `json` | +| `mode` | Streak mode (Default: `daily`) | `daily` (contribute daily) or `weekly` (contribute once per Sun-Sat week) | +| `exclude_days` | List of days of the week to exclude from streaks | Comma-separated list of day abbreviations (Sun, Mon, Tue, Wed, Thu, Fri, Sat) e.g. `Sun,Sat` | +| `disable_animations` | Disable SVG animations (Default: `false`) | `true` or `false` | +| `card_width` | Width of the card in pixels (Default: `495`) | Positive integer, minimum width is 100px per column | +| `hide_total_contributions` | Hide the total contributions (Default: `false`) | `true` or `false` | +| `hide_current_streak` | Hide the current streak (Default: `false`) | `true` or `false` | +| `hide_longest_streak` | Hide the longest streak (Default: `false`) | `true` or `false` | ### 🖌 Themes diff --git a/src/card.php b/src/card.php index efdece2d..8dc15b35 100644 --- a/src/card.php +++ b/src/card.php @@ -279,11 +279,16 @@ function getTranslations(string $localeCode): array /** * Get the card width from params taking into account minimum and default values + * + * @param array $params Request parameters + * @param int $numColumns Number of columns in the card + * @return int Card width */ -function getCardWidth(array $params): int +function getCardWidth(array $params, int $numColumns = 3): int { - // minimum width = 290, default width = 495 - return max(290, intval($params["card_width"] ?? 495)); + $defaultWidth = 495; + $minimumWidth = 100 * $numColumns; + return max($minimumWidth, intval($params["card_width"] ?? $defaultWidth)); } /** @@ -319,22 +324,36 @@ function generateCard(array $stats, array $params = null): string // read border_radius parameter, default to 4.5 if not set $borderRadius = $params["border_radius"] ?? 4.5; - // read card_width parameter - $cardWidth = getCardWidth($params); + $showTotalContributions = ($params["hide_total_contributions"] ?? "") !== "true"; + $showCurrentStreak = ($params["hide_current_streak"] ?? "") !== "true"; + $showLongestStreak = ($params["hide_longest_streak"] ?? "") !== "true"; + $numColumns = intval($showTotalContributions) + intval($showCurrentStreak) + intval($showLongestStreak); + + $cardWidth = getCardWidth($params, $numColumns); $rectWidth = $cardWidth - 1; - $firstBarOffset = $cardWidth / 3; - $secondBarOffset = ($cardWidth * 2) / 3; - $firstColumnOffset = $cardWidth / 6; - $centerOffset = $cardWidth / 2; - $thirdColumnOffset = ($cardWidth * 5) / 6; + $columnWidth = $numColumns > 0 ? $cardWidth / $numColumns : 0; - // if direction is rtl, swap first and third column offsets + // offsets for the bars between columns + $barOffsets = [-999, -999]; + for ($i = 0; $i < $numColumns - 1; $i++) { + $barOffsets[$i] = $columnWidth * ($i + 1); + } + // offsets for the text in each column + $columnOffsets = []; + for ($i = 0; $i < $numColumns; $i++) { + $columnOffsets[] = $columnWidth / 2 + $columnWidth * $i; + } + // reverse the column offsets if the locale is right-to-left if ($direction === "rtl") { - $firstColumnOffset = ($cardWidth * 5) / 6; - $thirdColumnOffset = $cardWidth / 6; + $columnOffsets = array_reverse($columnOffsets); } - // Set Background + $nextColumnIndex = 0; + $totalContributionsOffset = $showTotalContributions ? $columnOffsets[$nextColumnIndex++] : -999; + $currentStreakOffset = $showCurrentStreak ? $columnOffsets[$nextColumnIndex++] : -999; + $longestStreakOffset = $showLongestStreak ? $columnOffsets[$nextColumnIndex++] : -999; + + // set background $backgroundParts = explode(",", $theme["background"] ?? ""); $backgroundIsGradient = count($backgroundParts) >= 3; @@ -376,7 +395,7 @@ function generateCard(array $stats, array $params = null): string } // if the translations contain over max characters or a newline, split the text into two tspan elements - $maxCharsPerLineLabels = intval(floor($cardWidth / 22)); + $maxCharsPerLineLabels = intval(floor($cardWidth / $numColumns / 7.5)); $totalContributionsText = splitLines($localeTranslations["Total Contributions"], $maxCharsPerLineLabels, -9); if ($stats["mode"] === "weekly") { $currentStreakText = splitLines($localeTranslations["Week Streak"], $maxCharsPerLineLabels, -9); @@ -387,7 +406,7 @@ function generateCard(array $stats, array $params = null): string } // if the ranges contain over max characters, split the text into two tspan elements - $maxCharsPerLineDates = intval(floor($cardWidth / 18)); + $maxCharsPerLineDates = intval(floor($cardWidth / $numColumns / 6)); $totalContributionsRange = splitLines($totalContributionsRange, $maxCharsPerLineDates, 0); $currentStreakRange = splitLines($currentStreakRange, $maxCharsPerLineDates, 0); $longestStreakRange = splitLines($longestStreakRange, $maxCharsPerLineDates, 0); @@ -427,7 +446,7 @@ function generateCard(array $stats, array $params = null): string - + @@ -435,26 +454,26 @@ function generateCard(array $stats, array $params = null): string - - + + - + {$totalContributions} - + {$totalContributionsText} - + {$totalContributionsRange} @@ -462,21 +481,21 @@ function generateCard(array $stats, array $params = null): string - + {$currentStreak} - + {$currentStreakText} - + {$currentStreakRange} @@ -484,10 +503,10 @@ function generateCard(array $stats, array $params = null): string - + - + @@ -495,21 +514,21 @@ function generateCard(array $stats, array $params = null): string - + {$longestStreak} - + {$longestStreakText} - + {$longestStreakRange} @@ -734,7 +753,8 @@ function generateOutput(string|array $output, array $params = null): array // output PNG card if ($requestedType === "png") { try { - $cardWidth = getCardWidth($params); + // extract width from SVG + $cardWidth = (int) preg_replace("/.*width=[\"'](\d+)px[\"'].*/", "$1", $svg); $png = convertSvgToPng($svg, $cardWidth); return [ "contentType" => "image/png", diff --git a/src/demo/index.php b/src/demo/index.php index 557a1c15..d6bb72a0 100644 --- a/src/demo/index.php +++ b/src/demo/index.php @@ -164,7 +164,7 @@ function gtag() { - +
âš™ Advanced Options diff --git a/tests/expected/test_card.svg b/tests/expected/test_card.svg index 8e352509..ea6ba662 100644 --- a/tests/expected/test_card.svg +++ b/tests/expected/test_card.svg @@ -26,8 +26,8 @@ - +