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 @@ - + pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy