0

I'm working on a gallery. I would like to show portrait oriented picutres to mobile phone users and landscape oriented pictures to everyone else (tablets, laptops etc).

What I currently have is:

var maxW = window.screen.availWidth * window.devicePixelRatio;

if (maxW <= 767){
    galleryImages = portraitImages;
}else{
    galleryImages = landscapeImages;
};

var portraitImages = [  'https://static.photocdn.pt/images/articles/2016-7/landscape-comp/iStock_000058793850_Medium.jpg',
 'https://keyassets.timeincuk.net/inspirewp/live/wp-content/uploads/sites/12/2016/05/AP_Portrait_Landscapes_Stu_Meech-5.jpg',
 'https://keyassets.timeincuk.net/inspirewp/live/wp-content/uploads/sites/12/2016/05/AP_Portrait_Landscapes_Stu_Meech-16.jpg', 
'https://static.photocdn.pt/images/articles/2016-7/landscape-comp/iStock_000062009934_Medium.jpg']

var landscapeImages = ['https://images.unsplash.com/photo-1506744038136-46273834b3fb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjM3Njd9&w=1000&q=80', 
'https://images.unsplash.com/photo-1506260408121-e353d10b87c7?ixlib=rb-1.2.1&w=1000&q=80', 
'https://www.tom-archer.com/wp-content/uploads/2017/03/landscape-photography-tom-archer-4.jpg', 
'https://s.yimg.com/uu/api/res/1.2/DdytqdFTgtQuxVrHLDdmjQ--~B/aD03MTY7dz0xMDgwO3NtPTE7YXBwaWQ9eXRhY2h5b24-/https://media-mbst-pub-ue1.s3.amazonaws.com/creatr-uploaded-images/2019-11/7b5b5330-112b-11ea-a77f-7c019be7ecae', 
'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/hbx030117buzz14-1550595844.jpg']

Now, lets say, the smallest "resolution" for tablets is 768x1024. When I go to Dev Tools, input 768x1024 in resolution and call alert("MaxW: " + maxW + ",\nMaxH : " + maxH); I get MaxW: 1536, MaxH: 2048 which is caused by the device-pixel ratio.

So, my question, how would I calculate the max screen size for a mobile phone, taking into consideration the device-pixel ratio.

I can't very well say "show picture gallery if max-device width is 2048", since some computer monitors have worse resolution.

I hope I'm getting my meaning across. If I can provide any additional information / explenation, let me know.

Thank you for the help.

DrDoom
  • 287
  • 1
  • 9
  • Does this answer your question? [In javascript 'If mobile phone'](https://stackoverflow.com/questions/9048253/in-javascript-if-mobile-phone) – AndrewL64 Feb 27 '20 at 11:01
  • I'll have to try it out 1st, but this could solve the problem. I don't understand how `/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/` fits into the context, as I have not seen any code writen this way so far. – DrDoom Feb 27 '20 at 11:38

2 Answers2

1

With the innerWidth and innerHeight properties of the window you can calculate the width and height of your screen in pixels. On my 2560x1600 screen it returns the dimensions 1280x800, accounting for the device-pixel ratio.

function getWindowDimensions() {
  const width = window.innerWidth;
  const height = window.innerHeight;
  const ratio = (width / height) * 100;
  return { width, height, ratio };
}

const { width } = getWindowDimensions();

if (width < 768) {
    galleryImages = portraitImages;
} else {
    galleryImages = landscapeImages;
}

Also, instead of selecting your images in JavaScript you could also use the <picture> element and use the srcset attribute. With the <picture> element you can add media queries for showing images based on the condition in that query. This would give you the ability to add both your image sets to the HTML and the browser then decides which image to show based on your query.

<picture>
  <source media="(max-width: 767px)" srcset="portrait.jpg">
  <source media="(min-width: 768px)" srcset="landscape.jpg">
  <img src="landscape.jpg" alt="Your image description">
</picture>

I'd suggest that you create pairs for your images to add the to the picture element. For example in an array of objects with the keys portrait and landscape. Loop over the array and create a <picture> element for each of those pairs with the <source> tags specified to the media query and its corresponding srcset value.

const images = [
  {
    portrait: './portrait-image-1.jpg',
    landscape: './landscape-image-1.jpg'
  },
  {
    portrait: './portrait-image-2.jpg',
    landscape: './landscape-image-2.jpg'
  },
  {
    portrait: './portrait-image-3.jpg',
    landscape: './landscape-image-3.jpg'
  }
];

for (const { portrait, landscape } of images) {

  const picture = document.createElement('picture');
  const sourcePortrait = document.createElement('source');
  const sourceLandscape = document.createElement('source');
  const image = document.createElement('img');

  sourcePortrait.media = '(max-width: 767px)';
  sourcePortrait.srcset = portrait;
  sourceLandscape.media = '(min-width: 768px)';
  sourceLandscape.srcset = landscape;
  image.src = landscape;

  picture.append(sourcePortrait, sourceLandscape, image);
  document.body.append(picture);

}

Otherwise to detect the device that someone is using, like a mobile phone, then check the userAgent for keywords that are recognized as phones. For detecting devices this is good, but for responsive web development, not so much as many other devices and new browser could be added and could break in the future.

Emiel Zuurbier
  • 11,936
  • 2
  • 9
  • 22
  • Hey, thanks for the reply. I have looked into `picture`, `scrset` etc but the probelem is, I have an array, and I don't know how this would work togather. – DrDoom Feb 27 '20 at 11:39
  • Add the array (if it it's a very long one, show only the first couple) to your question above and I'll see what I can do. – Emiel Zuurbier Feb 27 '20 at 11:41
  • These are currently just placeholder images. Thanks for you help! Really appriciate it =) – DrDoom Feb 27 '20 at 11:44
  • You got it, buddy. Just a couple more questions. Are the portrait and landscape photos the same photo but in a different orientation? Do you use a backend language to render your HTML, like PHP or Node.js and are the images available in the backend, for example: in a database? Or do you just have some URLs in the frontend JavaScript and render your images from there? – Emiel Zuurbier Feb 27 '20 at 11:54
  • Yes, the portrait and landscape photos are the same (but different ratios). There is no back-end, html (js) takes the pictures dirrectly from a different website. I think that anwsers everything, or did I forget something. – DrDoom Feb 27 '20 at 12:03
  • To be fair, I guess I could just delete window.devicePixelRatio, and I would get the desired dimension... – DrDoom Feb 27 '20 at 12:06
  • That would be the easiest way, I suppose. Just in case, I've added a functionality of creating the `` elements might you need it. – Emiel Zuurbier Feb 27 '20 at 12:19
  • thank you for the examples and the help.=) saved me some time right now and a lot more in the future. – DrDoom Feb 27 '20 at 12:21
  • I've skimmed the code. just to clarify, did you forget to add image.src = portrait; or is it not needed for some reason? – DrDoom Feb 27 '20 at 12:27
-1

Why are you assuming that portrait=phone and landscape=tablet? I could (and probably would for a gallery) be using my phone in landscape.

Rather than making assumptions about the type of device, check for what the screen is actually doing now, ie is the screen landscape or portrait, and then configure your software accordingly.

Then it will work no matter what device and no matter what orientation.

RAC
  • 156
  • 2