Skip to content

Commit 5a0c45b

Browse files
committed
support svg placeholder
1 parent 0ddfca6 commit 5a0c45b

File tree

4 files changed

+83
-5
lines changed

4 files changed

+83
-5
lines changed

README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ I developed this package with the highest degree of flexibility possible and I h
4444
- [Manually generate conversions](#manually-generate-conversions)
4545
- [Format Media Url](#format-media-url)
4646

47+
1. [Conversions Presets](#conversions-presets)
48+
49+
- [Image Placeholder](#image-placeholder)
50+
4751
1. [Customization](#customization)
4852

4953
- [Custom Media Model](#custom-media-model)
@@ -733,6 +737,73 @@ This package comes with 3 formatters out of the box:
733737

734738
Feel free to implement your own formatter by extending `\Elegantly\Media\UrlFormatters\AbstractUrlFormatter`.
735739

740+
## Conversions Presets
741+
742+
### Image Placeholder
743+
744+
When loading images on the web, it’s common to show a low-resolution blurred placeholder first, then swap it with the full-resolution image once it’s ready. This improves perceived performance, reduces layout shifts, and gives a polished feel to your UI.
745+
746+
This package includes a ready-to-use preset for generating these placeholders in Base64-encoded format. The placeholder is tiny in size, quick to load, and designed to be displayed while the actual image is being fetched.
747+
748+
#### Defining the Placeholder Conversion
749+
750+
To create a placeholder, simply define a media conversion using the `MediaImagePlaceholderConverter`:
751+
752+
```php
753+
namespace App\Models;
754+
755+
use Illuminate\Database\Eloquent\Model;
756+
use Elegantly\Media\Concerns\HasMedia;
757+
use Elegantly\Media\Contracts\InteractWithMedia;
758+
use Elegantly\Media\MediaCollection;
759+
use Elegantly\Media\MediaConversionDefinition;
760+
use Elegantly\Media\Converters\MediaImagePlaceholderConverter;
761+
762+
class User extends Model implements InteractWithMedia
763+
{
764+
use HasMedia;
765+
766+
public function registerMediaCollections(): array;
767+
{
768+
return [
769+
new MediaCollection(
770+
name: 'avatar',
771+
single: true,
772+
conversions: [
773+
new MediaConversionDefinition(
774+
name: 'placeholder',
775+
converter: fn ($media) => new MediaImagePlaceholderConverter($media),
776+
),
777+
]
778+
)
779+
];
780+
}
781+
}
782+
```
783+
784+
#### Using the Placeholder in Your Views
785+
786+
If you’re using the built-in <x-media::img> Blade component, you can directly specify the placeholder conversion name:
787+
788+
```html
789+
<x-media::img
790+
:media="$user->getFirstMedia('avatar')"
791+
placeholder="placeholder"
792+
/>
793+
```
794+
795+
This will automatically load the blurred placeholder as a background-image.
796+
797+
#### Retrieving the Base64 Value Directly
798+
799+
If you need to manually work with the placeholder (e.g., for API responses or inline styles), you can retrieve it like this:
800+
801+
```php
802+
$placeholder = $media->getConversion('placeholder');
803+
804+
$base64Image = $placeholder?->contents;
805+
```
806+
736807
## Customization
737808

738809
### Custom Media Model

resources/views/components/img.blade.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,16 @@
88
'src' => null,
99
'width' => null,
1010
'height' => null,
11+
'placeholder' => null,
1112
])
1213

14+
@php
15+
$placeholder = $placeholder === true ? 'placeholder' : $placeholder;
16+
$placeholderValue = $placeholder ? $media->getConversion($placeholder)?->contents : null;
17+
@endphp
18+
1319
<img {!! $attributes !!} loading="{{ $loading }}" src="{!! $src ?? $media->getUrl($conversion, $fallback, $parameters) !!}"
1420
height="{{ $height ?? $media->getHeight($conversion, $fallback) }}"
1521
width="{{ $width ?? $media->getWidth($conversion, $fallback) }}"
16-
alt="{{ $alt ?? $media->getName($conversion, $fallback) }}">
22+
alt="{{ $alt ?? $media->getName($conversion, $fallback) }}"
23+
@if ($placeholderValue) style="background-size:cover;background-image: url(data:image/jpeg;base64,{{ $placeholderValue }})" @endif>

src/Converters/Image/MediaSvgPlaceholderConverter.php renamed to src/Converters/Image/MediaImagePlaceholderConverter.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
use Spatie\Image\Image;
1616
use Spatie\TemporaryDirectory\TemporaryDirectory as SpatieTemporaryDirectory;
1717

18-
class MediaSvgPlaceholderConverter extends MediaConverter
18+
class MediaImagePlaceholderConverter extends MediaConverter
1919
{
2020
public function __construct(
2121
public readonly Media $media,
22-
public int $blur = 50,
22+
public int $blur = 20,
2323
public int $width = 20,
2424
public ?int $height = 20,
2525
) {}

tests/Models/TestConverters.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Elegantly\Media\Converters\Audio\MediaMp3Converter;
88
use Elegantly\Media\Converters\Audio\MediaWavConverter;
99
use Elegantly\Media\Converters\Image\MediaImageConverter;
10-
use Elegantly\Media\Converters\Image\MediaSvgPlaceholderConverter;
10+
use Elegantly\Media\Converters\Image\MediaImagePlaceholderConverter;
1111
use Elegantly\Media\Converters\Pdf\MediaPdfToImageConverter;
1212
use Elegantly\Media\Converters\Video\MediaFrameConverter;
1313
use Elegantly\Media\Converters\Video\MediaMp4Converter;
@@ -80,7 +80,7 @@ public function registerMediaCollections(): Arrayable|iterable|null
8080
name: 'svg',
8181
immediate: false,
8282
queued: false,
83-
converter: fn ($media) => new MediaSvgPlaceholderConverter(
83+
converter: fn ($media) => new MediaImagePlaceholderConverter(
8484
media: $media,
8585
)
8686
),

0 commit comments

Comments
 (0)