nbcommunication Posted October 6, 2022 Author Share Posted October 6, 2022 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 1 1 Link to comment Share on other sites More sharing options...
Fuzen Posted October 6, 2022 Share Posted October 6, 2022 3 hours ago, nbcommunication said: // Without 'allSets' enabled, the srcset generation would terminate at 4096w @nbcommunication Don’t you mean it would terminate at 1024? That’s the next stop down from the 2000 original width. Link to comment Share on other sites More sharing options...
nbcommunication Posted October 7, 2022 Author Share Posted October 7, 2022 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 1 Link to comment Share on other sites More sharing options...
Fuzen Posted October 7, 2022 Share Posted October 7, 2022 7 hours ago, nbcommunication said: 4096 - set not output as original already used for 2048w. I hope that makes sense. @nbcommunication Ah, that makes sense now. Appreciate the clarification. 1 Link to comment Share on other sites More sharing options...
bernhard Posted October 13, 2022 Share Posted October 13, 2022 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 More sharing options...
nbcommunication Posted October 14, 2022 Author Share Posted October 14, 2022 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 3 Link to comment Share on other sites More sharing options...
taotoo Posted October 14, 2022 Share Posted October 14, 2022 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! 3 Link to comment Share on other sites More sharing options...
snck Posted November 10, 2022 Share Posted November 10, 2022 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 2 Link to comment Share on other sites More sharing options...
nbcommunication Posted November 11, 2022 Author Share Posted November 11, 2022 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 3 Link to comment Share on other sites More sharing options...
snck Posted November 14, 2022 Share Posted November 14, 2022 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 More sharing options...
Stefanowitsch Posted December 19, 2022 Share Posted December 19, 2022 I have a question about a possible feature. I read that you are using UIKit. UIkit offers the possibility to use multiple image sources and resolutions for one image. Like this: (example taken from: https://getuikit.com/docs/image) <div class="uk-height-medium uk-flex uk-flex-center uk-flex-middle uk-background-cover uk-light" sources="srcset: https://images.unsplash.com/photo-1464621922360-27f3bf0eca75?fit=crop&w=650&h=433&q=80 650w, https://images.unsplash.com/photo-1464621922360-27f3bf0eca75?fit=crop&w=1300&h=866&q=80 1300w; media: (min-width: 1200px)" data-src="https://images.unsplash.com/photo-1472803828399-39d4ac53c6e5?fit=crop&w=650&h=433&q=80" data-srcset="https://images.unsplash.com/photo-1472803828399-39d4ac53c6e5?fit=crop&w=650&h=433&q=80 650w, https://images.unsplash.com/photo-1472803828399-39d4ac53c6e5?fit=crop&w=1300&h=866&q=80 1300w" sizes="(min-width: 650px) 650px, 100vw" uk-img> <h1>Background Image</h1> </div> I would like to achieve the same markup but with the use of your module. Would this be possible? Right now I use a device check (mobile, tablet, desktop) to see which image resolution I want to use and render the image that way: <?php echo $image->size($imgFormat)->srcset() ?> The set rules are defined globally in the module settings. So the image gets cropped into the desired format (=custom resolution), then the srcset is generated. I am using different resolutions for different screen sizes: 16:9 on desktop, 4:3 on Tablet, 1:1 on mobile (for example) so just downscaling the image would not work for me. The problem is that this approach is not responsive in that way that the image format automatically changes when resizing the viewport. In fact you have to reload the page so that the new image format is applied and rendered. Link to comment Share on other sites More sharing options...
nbcommunication Posted December 19, 2022 Author Share Posted December 19, 2022 Hi @Stefanowitsch, I've used this UIkit implementation in a few recent projects, I wrote up how I did it here: Hope that helps! Cheers, Chris 1 Link to comment Share on other sites More sharing options...
Stefanowitsch Posted December 19, 2022 Share Posted December 19, 2022 1 hour ago, nbcommunication said: Hi @Stefanowitsch, I've used this UIkit implementation in a few recent projects, I wrote up how I did it here: Hope that helps! Cheers, Chris I am able to get this code to work. But I don't know where to put the information for which picture source to use. On smaller screens I want to display a different image. Link to comment Share on other sites More sharing options...
nbcommunication Posted December 20, 2022 Author Share Posted December 20, 2022 Hi @Stefanowitsch, A different variation of the Pageimage, or a totally different Pageimage? Cheers, Chris Link to comment Share on other sites More sharing options...
Stefanowitsch Posted December 20, 2022 Share Posted December 20, 2022 1 hour ago, nbcommunication said: Hi @Stefanowitsch, A different variation of the Pageimage, or a totally different Pageimage? Cheers, Chris Basically the same image but in a more mobile friendly aspect ratio. Link to comment Share on other sites More sharing options...
nbcommunication Posted December 21, 2022 Author Share Posted December 21, 2022 Hi @Stefanowitsch, Try: <?php $img = $image->render([ 'srcset' => [ 'rules' => '320x569, 640x1138, 768x1365, 1024, 1366, 1600, 1920', // first three rules here are for portrait images 'options' => [ 'upscaling' => true, 'hidpi' => true, ], ], 'sizes' => '(orientation: portrait) and (max-width: 640px) 50vw', ]); This is adapted from an example in the README which itself was adapted from an implementation in PageimageSrcset - I can't remember exactly how this works but I have used it in the past for portrait images on mobile. Cheers, Chris 1 Link to comment Share on other sites More sharing options...
Stefanowitsch Posted December 21, 2022 Share Posted December 21, 2022 2 hours ago, nbcommunication said: Hi @Stefanowitsch, Try: <?php $img = $image->render([ 'srcset' => [ 'rules' => '320x569, 640x1138, 768x1365, 1024, 1366, 1600, 1920', // first three rules here are for portrait images 'options' => [ 'upscaling' => true, 'hidpi' => true, ], ], 'sizes' => '(orientation: portrait) and (max-width: 640px) 50vw', ]); This is adapted from an example in the README which itself was adapted from an implementation in PageimageSrcset - I can't remember exactly how this works but I have used it in the past for portrait images on mobile. Cheers, Chris Hi Chris! Thanks, now I get where my problem lies. Can you answer me one question: The rules that are defined here do crop the image, right? Does it work the same as using the Pageimage:size() method? $image->size(400, 300); I am worrying if the focus point which can be set for one image individually will still be used when cropping via the srcet rule. Another thing: When scaling down the browser window from very large (1920+) to mobile-small (640) the image which is loaded does not change. Even if I define custom aspect ratios. This is the intended and normal behaviour of a browser I guess. A large image that is loaded will look good on a small viewport too. So there is no need to load a new version. The other way around it works as you would expect: Going from a small viewport to a large one the image updates to larger versions step by step. I would like to update the image if the viewport shrinks, too. Which seems to work together with UIKit. Link to comment Share on other sites More sharing options...
nbcommunication Posted December 22, 2022 Author Share Posted December 22, 2022 Hi @Stefanowitsch 20 hours ago, Stefanowitsch said: The rules that are defined here do crop the image, right? Does it work the same as using the Pageimage:size() method? Yes, and the same focus point would be used. I think if you are looking for a different focus point / crop you might be better off trying to output the <picture> html manually. I see from the source code that the 2nd argument (options) is passed to the size() call. Might be worth trying adding 'cropping' to this - https://processwire.com/api/ref/pageimage/size/ - and see if it works! As for updating the image when the viewport shrinks... I've no idea I'm afraid. If the UIkit implementation can do this - that is it doesn't use the largest image loaded but always the one specified by sizes - you'd need to ask their devs if it isn't working. Actually come to think of it, why not render two images and use uk-hidden@s and uk-visible@s classes to toggle between them? Cheers, Chris 1 Link to comment Share on other sites More sharing options...
snck Posted June 20, 2023 Share Posted June 20, 2023 Hey @nbcommunication, I have a strange problem here. I am using the following code: $img->render([ 'picture' => true, 'srcset' => [ 'rules' => ['800x267', '1600x534'], 'options' => [ 'upscaling' => true, ], ], 'allSets' => true, 'sizes' => '(max-width: 900px) 100vw, ((min-width: 901px) and (max-width: 1200px)) 67vw, ((min-width: 1201px) and (min-width: 1201px)) 50vw', 'class' => $img_class, 'alt' => $alt, 'markup' => "<img src='".$img->size($img_tag_width, $img_tag_height)->url."' alt='{alt}' class='{class}' width='".$img->size($img_tag_width, $img_tag_height)->width."' height='".$img->size($img_tag_width, $img_tag_height)->height."'>", ]); My image has a width of 1600px, but a different aspect ratio (original dimensions: 1600 x 1093). I am expecting to get two variations rendered ('800x267', '1600x534'), but instead of a scaled/cropped 1600px wide version, I get the original image, which is bad, because it has the wrong aspect ratio. How can I force PageimageSource to generate the variation with the correct dimensions? Thank you in advance! Link to comment Share on other sites More sharing options...
nbcommunication Posted June 20, 2023 Author Share Posted June 20, 2023 Hi @snck, This is definitely a bug. The quick solution would be to resize your image before calling render (e.g. $img->size(1600, 534)) but I've pushed a fix which should resolve this. Please download the latest version (1.0.5) and let me know if that hasn't fixed it for you. If not could you please let me know what the values for $img_tag_width and $img_tag_height are in the 'markup' option as I'll need this to debug further. Cheers, Chris 2 Link to comment Share on other sites More sharing options...
snck Posted June 21, 2023 Share Posted June 21, 2023 On 6/20/2023 at 11:46 PM, nbcommunication said: Please download the latest version (1.0.5) and let me know if that hasn't fixed it for you. Hi @nbcommunication, thanks for the quick reaction! The update fixed it for me. ? Cheers, Flo 2 Link to comment Share on other sites More sharing options...
Krlos Posted June 25, 2023 Share Posted June 25, 2023 On 6/1/2022 at 4:42 AM, Stefanowitsch said: I was in the need for using this module together with background images too - but in the "classic" way without any components. I am using the famous Lazysizes JS Plugin for lazyloading the images. To create responsive background images with the PageImageSouce module I also included the lazysizes bgset extension So the code in my template file looks like this: <div class="img-title-wrapper lazyload" data-sizes="auto" data-bgset="<?php echo $image->size($imgFormat)->srcset() ?>"> /* your content */ </div> The wrapper element then gets it's height either via CSS (height: 100vh for a big introduction title image) or through the elements inside the container. Adjust the background image styles to your needs (e.g. background-size:cover). Hi, @Stefanowitsch, can you please explain how you managed to use the module for background images? I have tried to use, but I only get the code for <img> and I'm trying to add my background images using inline css to make it work with Tailwindcss. Thank you. Link to comment Share on other sites More sharing options...
nbcommunication Posted June 26, 2023 Author Share Posted June 26, 2023 Hi @Krlos, On 6/25/2023 at 3:21 AM, Krlos said: I have tried to use, but I only get the code for <img> Can you please post a code example? Are you are just calling render() without providing a markup template? Cheers, Chris Link to comment Share on other sites More sharing options...
Stefanowitsch Posted June 26, 2023 Share Posted June 26, 2023 On 6/25/2023 at 4:21 AM, Krlos said: Hi, @Stefanowitsch, can you please explain how you managed to use the module for background images? I have tried to use, but I only get the code for <img> and I'm trying to add my background images using inline css to make it work with Tailwindcss. Thank you. To use background images I use the following plugins: 1. Lazysizes: https://github.com/aFarkas/lazysizes 2. The Lazysizes bgset extension: https://github.com/aFarkas/lazysizes/tree/gh-pages/plugins/bgset Note: The bgset extension must be loaded before the Lazysizes plugin. That's why I disabled the "Use Lazy Loading" in the module settings and load both files above manually in the correct order. To make use of a background image this code here works for me: <div class="img-title-wrapper lazyload" data-sizes="auto" data-bgset="<?php echo $image->size($imgFormat)->srcset() ?>"> /* your content */ </div> 1 Link to comment Share on other sites More sharing options...
Krlos Posted June 27, 2023 Share Posted June 27, 2023 On 6/26/2023 at 2:54 AM, nbcommunication said: Hi @Krlos, Can you please post a code example? Are you are just calling render() without providing a markup template? Cheers, Chris Hi @nbcommunication, yes I'm using: <section class="about-section pt-48 pb-48" style="background-image: url(<?php echo $page->images->render(); ?>); background-repeat: no-repeat; background-size: cover; background-position: center;"> I'm doing it wrong? I thought it was enough to define the sizes in the module configuration. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now