0

I'm creating a site for a photographer and I'm creating a gallery at the moment. To save me a lot of code I've automated much, including file name, path, width, lightbox class, etc.

In the HTML I simply have to write an <a> with a title and the jQuery takes care of the rest.

HTML

<a alt="All-my-Loving"></a>

jQuery

$(function () {
    $('.imagesContainer a').each(function () {
        var $link = $(this),
            title = $link.attr('alt'),
            thumb = 'images/portfolio/thumbs/' + title + '.jpg';

    $link.attr('data-target', 'flare');          // for gallery plugin
    $link.attr('data-flare-scale', 'fitmax');    // for gallery plugin
    $link.attr('data-flare-thumb', thumb);       // for gallery plugin
    $link.attr('data-flare-gallery', 'main');    // for gallery plugin
    $link.addClass('item');                      // for IsoTope/Packery/Masonry
    $link.attr('href', 'images/portfolio/full/' + title + '.jpg'); // Link to full image

    $link.append($('<img>', {
      src     : 'images/portfolio/thumbs/' + title + '.jpg'    // Link to thumbnail image in gallery
    }));
    });
});

The problem:
However, the image path leads to regular (@1x) images and as I want to make this site retina-proof the path should lead to an @2x or @3x image when the device has an retina screen.

As far as I know, although haven't exactly tried, Retina.js is not an option since this only works for inline-images, but all images get their src image path after the above script is executed.

One single must:
It doesn't matter how to achieve retina images instead of regular ones for retina devices, as long as not a single image is downloaded twice (1x and 2x, simultaneously).

Who got a clue?


Possible (theoretically) solution:
In addition to the above JS script, simply have an IF statement

If (window.devicePixelRatio > 1) {
    $link.append($('<img>', {
      src     : 'images/portfolio/thumbsRETINA/' + title + '.jpg'
    }));
} else {
    $link.append($('<img>', {
      src     : 'images/portfolio/thumbsREGULAR/' + title + '.jpg'
    }));
}

And apply that IF statement to check if the device is Retina to each ImagePath request.


Update
I've applied the above IF statement and it's working. The RetinaFolders are empty and my iPhone 6 is showing no images (as there are none). I'm just not sure if that's the right way to go. The new script becomes:

$(function () {
    $('.imagesContainer a').each(function () {
        var $link = $(this),
            title = $link.attr('alt'),
            thumb = 'images/portfolio/thumbs/' + title + '.jpg';
            retinaThumb = 'images/portfolio/thumbs-retina/' + title + '.jpg';

    // regular tags
    $link.attr('data-target', 'flare');
    $link.attr('data-flare-scale', 'fitmax');
    $link.attr('data-flare-gallery', 'main');
    $link.addClass('item');
    $link.attr('href', 'images/portfolio/full/' + title + '.jpg');

    // Retina tags
    if (window.devicePixelRatio > 1) {                  // If the device has retina graphics
        $link.attr('data-flare-thumb', retinaThumb);
        $link.attr('href', 'images/portfolio/full-retina/' + title + '.jpg');
        $link.append($('<img>', {
          src     : 'images/portfolio/thumbs-retina/' + title + '.jpg'
        }));
    } else {                                            // If the device does not has retina graphics
        $link.attr('data-flare-thumb', thumb);
        $link.attr('href', 'images/portfolio/full/' + title + '.jpg');
        $link.append($('<img>', {
          src     : 'images/portfolio/thumbs/' + title + '.jpg'
        }));
    }

    });
});
Sander Schaeffer
  • 2,757
  • 7
  • 28
  • 58
  • I usually just load a 2x image at a 1x (50%) resolution. This is definitely an interesting problem in FE though. – Christopher Marshall Apr 22 '15 at 15:13
  • @ChristopherMarshall That's indeed how it works. However, loading 2X images for a 1X device (regular 1080p desktop) is a waste of bandwidth. Combine that with hundreds of images, both thumbnail and full size, is a waste of tens to hundreds of MB's per page view. :) Therefor looking for a waste-free solution. – Sander Schaeffer Apr 22 '15 at 15:15
  • @RoryMcCrossan, I don't see how that would fit my solution, since I (think I) can't apply that to the above JS script / images.. – Sander Schaeffer Apr 22 '15 at 15:16
  • 1
    @SanderSchaeffer I completely agree on the waste of bandwidth. I have not found an easy-to-implement solution yet though for this issue. :| – Christopher Marshall Apr 22 '15 at 15:16

1 Answers1

1

Here's a theoretical answer. You will have to adapt it to your needs.

Add a data-retina-src attribute to each image (works in jQuery):

<img src="image.jpg" data-retina-src="image2X.jpg" alt="">

Use jQuery media queries and switch image source with data-retina-src source.

EDIT 1:

Check these links for jQuery retina detection:

http://egorkhmelev.github.io/retina/

What is the best way to detect retina support on a device using JavaScript?

EDIT 2:

Use this script - http://imulus.github.io/retinajs/ - and check for alternate images automatically:

For example, if you have an image on your page that looks like this: <img src="/images/my_image.png" />

The script will check your server to see if an alternative image exists at this path: "/images/my_image@2x.png"

Community
  • 1
  • 1
Ciprian
  • 872
  • 1
  • 10
  • 30