Adjust Image Path based on Device Retina Ratio

605 Views Asked by At

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'
        }));
    }

    });
});
1

There are 1 best solutions below

2
Ciprian On

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/[email protected]"