Jump to content

PageimageSource


nbcommunication

Recommended Posts

Hi @uiui,

I've added in this option and released v1.0.4.

From the README:

Use for all dimensions?

If enabled, a set rule will be used regardless of whether it is wider or higher than the dimensions of the original image.

To use this on a srcset call, enable the allSets option:

$srcset = $image->srcset('4096, 2048, 1024, 512, 256', [
	'allSets' => true,
]);
// If passing an image 2000px in width, the above would return a srcset with set rules for each given width
// Without 'allSets' enabled, the srcset generation would terminate at 4096w

 

I hope that is useful!

Cheers,

Chris

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

17 hours ago, fuzenco said:

@nbcommunication Don’t you mean it would terminate at 1024? That’s the next stop down from the 2000 original width.

No, it would terminate at 4096. Because this width is greater than the original, it won't generate a variation and it'll output the original as the source for 4096w. It then wouldn't make sense to output the original as the source for 2048w as it has already been used. This makes more sense in the smallest to largest context:

256 - variation generated
512 - variation generated
1024 - variation generated
2048 - width > than original, original used
4096 - set not output as original already used for 2048w.

I hope that makes sense.

Cheers,

Chris

  • Like 1
Link to comment
Share on other sites

Thx @nbcommunication for the module. It looks great. It's my first time using responsive image sizes (shame on me) and I have a question:

I'm using this ruleset:

Quote

320
640
1024
2048 2x

On a 500px screen with 1x pixel ratio this loads the 640 image. Great.

But on a 2x pixel ratio screen it always loads the 2048 image. Not so great ? 

Can I somehow tell my browser to load a 1280 (2*640) image on 500 pixel screen?

Link to comment
Share on other sites

Hi @bernhard,

Honestly, I find the way in which browsers actually implement srcset and sizes to be really confusing. In the previous PageimageSrcset I included a bit of javascript for debugging, as I found it was sometime difficult to even tell which image was being used (if they were just different width variations). What complicates debugging is that the browser will use the largest image it has in the cache, so if you've loaded the page at desktop width and then try to see how it'll respond at a smaller screen size, it will still display the larger image.

What happens if you add 1280 2x into the set?

Cheers,

Chris

  • Like 3
Link to comment
Share on other sites

2 hours ago, nbcommunication said:

Hi @bernhardWhat complicates debugging is that the browser will use the largest image it has in the cache, so if you've loaded the page at desktop width and then try to see how it'll respond at a smaller screen size, it will still display the larger image.

I use Firefox when debugging srcset as unlike Chrome it doesn't do this!

  • Like 3
Link to comment
Share on other sites

  • 4 weeks later...
On 10/13/2022 at 11:53 AM, bernhard said:

Thx @nbcommunication for the module. It looks great. It's my first time using responsive image sizes (shame on me) and I have a question:

I'm using this ruleset:

On a 500px screen with 1x pixel ratio this loads the 640 image. Great.

But on a 2x pixel ratio screen it always loads the 2048 image. Not so great ? 

Can I somehow tell my browser to load a 1280 (2*640) image on 500 pixel screen?

@bernhard Imho modifiers like 2x should not be necessary at all. It took me quite some time and testing to wrap my head around responsive images and my experiments with the current browsers showed that whenever my sizes attribute was accurate, the browser chose the closest image resolution from the sourceset taking pixel density of the screen into account automatically.

This is a (rather complex) example for my usage of PageimageSource on a page with a masonry style layout that can have from 1 to 5 columns and the sizes also take padding etc. into account (which might be overkill):

$img_markup = $img->render([
  'picture' => true,
  'srcset' => ['360', '480', '640', '800'], 
  'sizes' => '(max-width: 579px) calc(100vw - (2 * 34px)), 
	(min-width: 580px) and (max-width: 767px) calc(50vw - (1.5 * 34px)),
	(min-width: 768px) and (max-width: 1199px) calc(33.3333vw - (1.33 * 34px)),
	(min-width: 1200px) and (max-width: 1499px) calc(25vw - (1.25 * 34px)),
	(min-width: 1500px) calc(20vw - (1.2 * 34px))',
  'class' => 'teaser-img proportional',
  'alt' => $img->description,
  'markup' => "<img src='{$img->width(480)->url}' alt='{alt}' class='{class}' width='".$img->width(480)->width."' height='".$img->width(480)->height."'>"
]);

Output:

<picture>
  <source srcset="/site/assets/files/1200/1_klimanagepasster_wohnunsgbau.360x0-srcset.webp 360w, /site/assets/files/1200/1_klimanagepasster_wohnunsgbau.480x0-srcset.webp 480w, /site/assets/files/1200/1_klimanagepasster_wohnunsgbau.640x0-srcset.webp 640w, /site/assets/files/1200/1_klimanagepasster_wohnunsgbau.800x0-srcset.webp 800w" sizes="(max-width: 579px) calc(100vw - (2 * 34px)), (min-width: 580px) and (max-width: 767px) calc(50vw - (1.5 * 34px)), (min-width: 768px) and (max-width: 1199px) calc(33.3333vw - (1.33 * 34px)), (min-width: 1200px) and (max-width: 1499px) calc(25vw - (1.25 * 34px)), (min-width: 1500px) calc(20vw - (1.2 * 34px))" type="image/webp">
  <source srcset="/site/assets/files/1200/1_klimanagepasster_wohnunsgbau.360x0-srcset.jpg 360w, /site/assets/files/1200/1_klimanagepasster_wohnunsgbau.480x0-srcset.jpg 480w, /site/assets/files/1200/1_klimanagepasster_wohnunsgbau.640x0-srcset.jpg 640w, /site/assets/files/1200/1_klimanagepasster_wohnunsgbau.800x0-srcset.jpg 800w" sizes="(max-width: 579px) calc(100vw - (2 * 34px)), (min-width: 580px) and (max-width: 767px) calc(50vw - (1.5 * 34px)), (min-width: 768px) and (max-width: 1199px) calc(33.3333vw - (1.33 * 34px)), (min-width: 1200px) and (max-width: 1499px) calc(25vw - (1.25 * 34px)), (min-width: 1500px) calc(20vw - (1.2 * 34px))" type="image/jpeg">
  <img src="/site/assets/files/1200/1_klimanagepasster_wohnunsgbau.480x0.jpg" alt="Klimanagepasster Wohnunsgbau" class="teaser-img proportional" width="480" height="282" loading="lazy">
</picture>

@nbcommunication Great module, I like it a lot! Nevertheless my example also shows a little incovenience I experienced when using PageimageSource: I need to output width and height attributes for my img tag and using the markup option (as shown above) was the only way to accomplish this. Using the height and width options of the render method rendered the srcset useless (all the same sizes). Maybe you could implement an option that outputs the size of the first entry from the srcset as width and height attributes of the img? Especially when using lazyloading the width and height attributes serve as proportional placeholders and prevent layout shifts.

Cheers,
Flo

  • Like 2
Link to comment
Share on other sites

Hi @snck,

Thanks for the feedback and the great example!

Unfortunately the issue you've raised is more of an issue with how Pageimage::render() is implemented. Adding 'width' or 'height' options is interpreted as a request to resize the Pageimage, which is not what we want in PageimageSource::render(). The default markup does not include width and height attributes, so the only way to add them without resizing the image is to provide them in a specified markup string.

I have a hook in an internal development module which sets a default markup string with these attributes:

<?php

// Pageimage:render
$this->addHookBefore('Pageimage::render', function(HookEvent $event) {
     $markup = $event->arguments(0);
     $options = $event->arguments(1);
     if(!is_string($markup)) {
        $options = $markup;
        $markup = '<img src="{url}" alt="{alt}" width="{width}" height="{height}">';
     }
     $event->arguments(0, $markup);
     $event->arguments(1, $options);
});

This means I can generally call render() without any options. If your example is something you are doing repeatedly, you could utilise a similar strategy in site/ready.php:

<?php

// /site/ready.php
$wire->addHookBefore('Pageimage::render', function(HookEvent $event) {

	$markup = $event->arguments(0);
	$options = $event->arguments(1);

	if(!is_string($markup)) $options = $markup;

	if($options['masonry'] ?? false) { // a custom option

		$img = $event->object;
		$thumb = $img->width(480);

		$markup = "<img src='$thumb->url' alt='{alt}' class='{class}' width='$thumb->width' height='$thumb->height'>";
		$options = array_merge([
			'picture' => true,
			'srcset' => [360, 480, 640, 800], 
			'sizes' => '(max-width: 579px) calc(100vw - (2 * 34px)), 
				(min-width: 580px) and (max-width: 767px) calc(50vw - (1.5 * 34px)),
				(min-width: 768px) and (max-width: 1199px) calc(33.3333vw - (1.33 * 34px)),
				(min-width: 1200px) and (max-width: 1499px) calc(25vw - (1.25 * 34px)),
				(min-width: 1500px) calc(20vw - (1.2 * 34px))',
			'class' => 'teaser-img proportional',
			'alt' => $img->description,
		], $options);
	}
	
	$event->arguments(0, $markup);
	$event->arguments(1, $options);
});

// In your code
$img->render([
	'masonry' => true,
	'class' => 'overriding-the-default-class',
	'alt' => __('Overriding the default alt text'),
]);

// Not tested!!!

Cheers,

Chris

  • Like 3
Link to comment
Share on other sites

On 11/11/2022 at 11:59 AM, nbcommunication said:

Unfortunately the issue you've raised is more of an issue with how Pageimage::render() is implemented. Adding 'width' or 'height' options is interpreted as a request to resize the Pageimage, which is not what we want in PageimageSource::render(). The default markup does not include width and height attributes, so the only way to add them without resizing the image is to provide them in a specified markup string.

I have a hook in an internal development module which sets a default markup string with these attributes...

@nbcommunication Thank you for clarification and the great example. I will definitely keep this in mind! 🙂

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...