spatie / statamic-responsive-images

Responsive images for Statamic 3
MIT License
99 stars 29 forks source link

Extensible dimension calculators #193

Closed ncla closed 1 year ago

ncla commented 1 year ago

Described in #167, this allows developers to bind their own customized DimensionCalculator if they have different needs.

This required to move a few things around, as some things were tied to "ratios". Breakpoints have been separted of their srcSets, and I have introduced separate Source to handle it instead (it represents tag in a way). For GraphQL the ratio property will be present if using default, filesize aspect-ratio based dimension calculator.

I introduced an object class Dimensions to better contain width and height, as having an array was a bit ugly for my liking.

If developers want to customize dimension calculations, they need to implement DimensionsCalculator interface with following three methods:

All of these receive Breakpoint/Source objects, so developers should have plentiful freedom when it comes to calculating dimensions, as from there you can access breakpoint params and original asset.

Here is how developers can bind their implementation in AppServiceProvider, example:

        $this->app->bind(DimensionCalculator::class, function () {
            return new class extends ResponsiveDimensionCalculator {
                public function calculateForBreakpoint(Source $source): Collection
                {
                    // Disable JPG sources
                    if ($source->getFormat() === 'original') {
                        return collect([]);
                    }

                    // Create widths from 100 to 2000 in 100px increments with fixedHeight passed from params
                    return collect(range(100, 2000, 100))
                        ->map(function ($width) use ($source) {
                            return new Dimensions($width, $source->breakpoint->params['fixedHeight']);
                        });
                }
            };
        });

The original dimension calculator has remained unchanged. I do not currently have an idea how to solve #167 width calculations elegantly, so this is up to the individual developer, now they have the freedom to do so. Or we can improve this in a later update.

Additional side-quests:

Breaking changes:

TODO: