alshedivat / al-folio

A beautiful, simple, clean, and responsive Jekyll theme for academics
https://alshedivat.github.io/al-folio/
MIT License
11.37k stars 11.29k forks source link

Publication preview image not enlarged on click #2668

Open WYF99 opened 3 months ago

WYF99 commented 3 months ago

Have you checked that your issue isn't already filed?

Bug description

Publication preview thumbnails are not enlarged and displayed at original size upon mouse click

How to reproduce the bug

  1. Go to any publication entry with a preview image which originally is of larger size than the thumbnail (e.g., any image from my personal site).
  2. Click on the thumbnail to zoom in.
  3. The image is centered but still displayed at the same small (and unreadable) size.

Error messages and logs

No error message.

What operating system are you using?

Not applicable (e.g. you're using GitHub Pages or other hosting)

Where are you seeing the problem on?

Deployed site

More info

A publication thumbnail is displayed at a reduced size by default, which is supposed to be centered, enlarged, and displayed at its original size upon click. In reality, the thumbnail is simply centered without any size change.

According to @george-gca from #2662

imagemagick creates a reduced version of those images, since they are displayed in this location at a really small size, and simply doesn't use the original version.

jcblum commented 2 months ago

I was struggling with the same thing, so I dug into it. I think this is not technically a bug, but instead the interaction of non-obvious expected behavior from two different plugins:

  1. jekyll-imagemagick only scales images down (not up)
  2. medium-zoom calculates the zoomed size based on what's in sizes, not the source image's actual dimensions

jekyll-imagemagick only scales images down (not up)

All the details are in here… It turns out that small original images aren't being resized at all, because `jekyll-imagemagick` is hard-coded to request that Image Magick shrink images, not enlarge them. This is a big part of why the tiny `gif` preview images in the example site content don't enlarge. In the [jekyll-imagemagick source](https://gitlab.com/emmmile/jekyll-imagemagick/-/blob/bd15ef28d59fe3321e5e90e2756f4ff747089eb5/lib/jekyll-imagemagick/convert.rb#L26-36), the line that constructs the Image Magick `-resize` command is: > cmd += "-resize \"#{long_edge}>\" #{resize_flags} " You can also see this by examining what jekyll-imagemagick prints to the Jekyll logs, which looks like: > Imagemagick: Running command "convert "/path/to/assets/img/1.jpg" -quality 85 -resize "1400>" "/path/to/_site/assets/img/1-1400.webp"" The `>` in the geometry "shrinks an image with dimension(s) larger than the corresponding width and/or height argument(s)" ([source](https://legacy.imagemagick.org/script/command-line-processing.php#geometry)).

…but the TL;DR is: images that start out with a width smaller than what's requested in site.imagemagick.widths will be output without any resizing, no matter what their file names claim.

If you inspect the responsive images created by jekyll-imagemagick for the example site content, images that are supposed to be 1400px wide are still 800px wide, since the originals are all 800px wide. This means the default srcset is also mis-specified, since width descriptors are supposed to match the actual image widths.

What to do about it?

Most immediately, perhaps the documentation of this feature in al-folio and the example content could clarify for users what to expect? Namely:

People who are up for customizing might want to look into the other responsive image plugins out there, some of which offer more flexibility.

So for @WYF99, the upper limit on the zoomed thumbnail size will be 480px wide, even though there are images in the srcset that claim to be 800px and 1400px (they aren't – they're all 480px, too). But that doesn't solve the tiny zoom problem, since the zoomed previews often aren't even making it to 480px wide. That's because…

medium-zoom calculates the zoomed size based on what's in sizes, not the source image's actual dimensions

On @WYF99 's page, the thumbnails have been given sizes="200px". The thumbnails actually render at 70px–125px width (depending on viewport size) for the larger Bootstrap breakpoints.

Taking the viewport >1200px case as an example, the concrete size of the thumbnails is 125px wide, while the physical width of the source image is 480px. But instead of the zoom scaling factor being calculated as 480 / 125, it's being calculated as 200 / 125, resulting in a too-small zoomed image.

The gory details are in here… `medium-zoom` uses CSS animation to create the zoom effect. It finds the ratio between the intrinsic size of the image and the concrete size of the image as rendered on the page and then calculates a scaling factor to pass into `transform: scale` (basically — there are a few more twists to the algorithm, [code here](https://github.com/francoischalifour/medium-zoom/blob/35b519fbdef97df69cc1d7daf46988effef0860b/src/medium-zoom.js#L180-L271)). The problem is that for images with a `srcset`, the intrinsic dimensions (`naturalHeight` and `naturalWidth`) are [adjusted based on the `sizes` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#sizes), or the default "100vw" that's assumed if `sizes` is missing. You can check what scaling factor is being applied by bringing up the Javascript console, clicking on a thumbnail, and entering this at the console prompt: ```javascript > document.body.getElementsByClassName('medium-zoom-image--opened')[0].style.transform 'scale(1.59289) translate3d(243.269px, -108.779px, 0px)' ``` The transform is using a `scale` of ~1.6, causing that dinky zoom. To understand where that `scale` number came from, enter this at the console prompt (while the zoom is still displayed!): ```javascript > document.body.getElementsByClassName('medium-zoom-image--hidden')[0].naturalWidth 200 ``` The intrinsic width of the thumbnail image is being reported as 200px instead of 480px, thanks to `sizes`, resulting in the scaling factor being calculated as `200 / 125`. If you read this far, you might also be interested in [this code pen](https://codepen.io/jcblum/full/BagGvem) I made demonstrating how `sizes` affects intrinsic dimensions.

What to do about it?

The second approach is probably easier, since highly granular sizes specs get really verbose and painful to generate, and what you need to get desirable zoom scales might trade off against what you need to optimize page loading speed. Also, you'd still be leaving the browser in charge of picking exactly which size image is used for the zoomed view, which can result in visibly inconsistent behavior.