[6.x] Make SVG dimensions integers so in the meta data you see a nice number#14005
[6.x] Make SVG dimensions integers so in the meta data you see a nice number#14005
Conversation
…r like `400 x 114` rather than `400 × 114.38815`
There was a problem hiding this comment.
Pull request overview
This PR modifies how SVG dimensions are stored and displayed in Statamic's asset management system, converting floating-point values to integers for cleaner presentation in the asset browser metadata.
Changes:
- Modified PHP backend to cast SVG width/height to integers when parsing from both SVG attributes and viewBox
- Added Math.floor() to JavaScript frontend to ensure dimensions display as integers in the asset editor
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/Imaging/Attributes.php | Updated svgAttributes() method to cast width and height values to integers using (int) instead of (float) for both direct attributes and viewBox parsing |
| resources/js/components/assets/Editor/Editor.vue | Added Math.floor() to width and height values in the asset dimensions badge display |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| && is_numeric((string) $svg['width']) | ||
| && is_numeric((string) $svg['height'])) { | ||
| return ['width' => (float) $svg['width'], 'height' => (float) $svg['height']]; | ||
| return ['width' => (int) $svg['width'], 'height' => (int) $svg['height']]; |
There was a problem hiding this comment.
Casting SVG dimensions directly to int truncates decimal values, which can lose precision. For example, 30.5 becomes 30, and 29.9 becomes 29. Consider using round() instead of (int) to round to the nearest integer, which would be more accurate. This affects SVG files that have decimal dimensions in their width/height attributes.
| [,,$width, $height] = preg_split('/[\s,]+/', $svg['viewBox'] ?: ''); | ||
|
|
||
| return compact('width', 'height'); | ||
| return ['width' => (int) $width, 'height' => (int) $height]; |
There was a problem hiding this comment.
Casting viewBox dimensions directly to int truncates decimal values. For example, if a viewBox is "0 0 100.5 200.8", the dimensions will become 100 and 200 instead of 101 and 201. Consider using round() instead of (int) to round to the nearest integer for more accurate dimensions.
| <div class="flex w-full items-center justify-end rounded-b border-t dark:border-gray-700 bg-gray-100 dark:bg-gray-900 px-4 py-3"> | ||
| <div class="hidden h-full flex-1 gap-2 sm:gap-3 py-1 sm:flex"> | ||
| <ui-badge pill v-if="asset.width && asset.height" icon="assets" :text="__('messages.width_x_height', { width: asset.width, height: asset.height })" /> | ||
| <ui-badge pill v-if="asset.width && asset.height" icon="assets" :text="__('messages.width_x_height', { width: Math.floor(asset.width), height: Math.floor(asset.height) })" /> |
There was a problem hiding this comment.
The PHP code uses truncation with (int) cast while the JavaScript uses Math.floor(). While Math.floor() always rounds down toward negative infinity, the (int) cast in PHP truncates toward zero. For positive numbers they behave the same, but this inconsistency could cause confusion. Consider using floor() in PHP to match the JavaScript behavior, or preferably use round() in both places for more accurate rounding.
| <ui-badge pill v-if="asset.width && asset.height" icon="assets" :text="__('messages.width_x_height', { width: Math.floor(asset.width), height: Math.floor(asset.height) })" /> | |
| <ui-badge pill v-if="asset.width && asset.height" icon="assets" :text="__('messages.width_x_height', { width: Math.round(asset.width), height: Math.round(asset.height) })" /> |
| && is_numeric((string) $svg['width']) | ||
| && is_numeric((string) $svg['height'])) { | ||
| return ['width' => (float) $svg['width'], 'height' => (float) $svg['height']]; | ||
| return ['width' => (int) $svg['width'], 'height' => (int) $svg['height']]; |
There was a problem hiding this comment.
The existing test expects floating-point values for SVG dimensions when width and height attributes are present (line 120 expects 30.0 and 60.0). This PR changes the code to return integers, which will break this test. The test file at tests/Assets/AttributesTest.php will need to be updated to expect integers instead of floats.
jasonvarga
left a comment
There was a problem hiding this comment.
I think we should leave the floats in PHP and just do the rounding in JavaScript.
You should use Math.round() so it rounds in the right direction. Math.floor() rounds down.
If you undo the PHP changes you can ignore all the copilot suggestions.
Description of the Problem
SVGs can sometimes show as having floating decimals in the asset browser, like this:
What this PR Does
Forces an integer like this:
How to Reproduce