1

I would like to display a picture gallery. The picture shown would be either a portrait or a landscape, depending on the screen orientation. The pictures are landscape and portrait pictures identical, except their dimension.

I've searched SO, and so far I've found this gem.

@media only screen and (orientation: portrait){
.land{display: none;}
.port{display: inline-block;}
}
@media only screen and (orientation: landscape){
.land{display: inline-block;}
.port{display: none;}
}

I would like to append to my array of images either a .land or .port class, depending on their dimensions, so that the approriate picture(s) are shown, depening on the orientation of the screen.

How would I do this?

If I can provide any additional information, let me know.

Thank you

Edit: I would like to thank everyone for the examples shown so far. What I have not mentioned before (and I guess I should have) is that my gallery has a next and a previous button. The images change constantly and as far as I understand, changing the class of the picture shown will not change the image shown, it will just change a class which does not help in this case.

Or am I missing something vital here?

Wouldn't it make more sense to have two arrays and on orientation change just change the array from which the picture is taken?

Or maybe have an object, something like this

let pictures = [
{
port: './imgs/port-pic1.jpg',
land: './imgs/land-pic1.jpg'
},{
port: './imgs/port-pic2.jpg',
land: './imgs/land-pic2.jpg'
}
]
DrDoom
  • 325
  • 1
  • 2
  • 12

3 Answers3

2

You can detect the screen width and height, and based upon that, you can iterate through all images and give them the appropriate class.

let width = window.innerWidth;
let height = window.innerHeight;
let screenClass = "portrait"; // by default


if (width>height) {
    screenClass = "landscape";
}

let images = document.querySelectorAll("img");

for(let i=0; i<images.length; i++) {
  let imageClass = "port"; // by default
  let img = images[i];
  if (img.width>img.height) {
      imageClass = "land";
  }
  // combine the class for the screen orientation, plus the image 
  // orientation, for more customization

  img.className = screenClass + " " + imageClass;

}

Edit

Based on the edit of the question, as far as I understood, the user has an existing array of images stored in an array of objects. Each object has two properties, port and land. Maybe these are the same image but in different modes, or maybe these are two different images in two different modes. In anycase, the array is expected to be iterated through and the images stored in the properties are to be parsed depending on the device orientation. If that is what the case is, then here is how to achieve that:

let pictures = [ {
                  port: './imgs/port-pic1.jpg',
                  land: './imgs/land-pic1.jpg'
                 },{
                   port: './imgs/port-pic2.jpg',
                   land: './imgs/land-pic2.jpg'
                }];

let width = window.innerWidth;
let height = window.innerHeight;
let screenClass = "port"; // by default


if (width>height) {
    screenClass = "land";
}

pictures.forEach( pic => {
   let url = pic[screenClass];  // this will either be value of land 
                                //  or  value of port
    // do whatever with the url

    let img = document.createElement("img");
    img.src = url;
    img.className = "whatever";

    document.querySelector("body").appendChild(img);

});
Ahmad
  • 12,336
  • 6
  • 48
  • 88
  • thanks. this looks promising. I assume I would need to add an event listener to detect the change of orientation? – DrDoom Mar 05 '20 at 09:03
  • @DrDoom yes, you will need to detect orientation changes – Ahmad Mar 05 '20 at 09:03
  • actually, lets say I have two picture of a mountain. One is a "portrait" and one is a "landscape". I have those two pictures in an array. I would like to append a `.port` class to the portrait picture and a `.land` class to the landscape picutre. How would this code help me achive that? – DrDoom Mar 05 '20 at 09:07
  • @DrDoom I modified my answer to accommodate image's width vs height – Ahmad Mar 05 '20 at 09:14
  • could you check my question again. I added an Edit part. Thank you. – DrDoom Mar 05 '20 at 09:37
  • @DrDoom I updated my answer again. You should post another question which better describes the issue you are having and share some of the existing HTML code to help understand your goal – Ahmad Mar 05 '20 at 09:54
  • I though the question was self explanitory. I guess I was mistaken. I tend to overcomplicate things too much. Thank you for the help. Much appriciate it =) – DrDoom Mar 05 '20 at 10:01
1

You can do it like

window.onorientationchange = function() { 
    if(window.innerHeight > window.innerWidth){
        //$("img.land").removeClass("land").addClass("port");
        var element = document.querySelectorAll("img.land");
        element.classList.remove("land");
        element.classList.add("port");
    }else{
        //$("img.port").removeClass("port").addClass("land");
        var element = document.querySelectorAll("img.port");
        element.classList.remove("port");
        element.classList.add("land");
    }
  console.log("the orientation of the device is now " + screen.orientation.angle);
};

jQuery Mobile has an event that handles the change of this property... if you want to warn if someone rotates later - orientationchange

Also check out window.orientation

Rohit.007
  • 3,414
  • 2
  • 21
  • 33
0

You can achieve this by using toggle on the classList of an element:

function doOnOrientationChange() {
  const isLandscape = window.orientation == -90 || window.orientation == 90;
  document.querySelectorAll('img.land').forEach(e => e.classList.toggle('land', isLandscape));
  document.querySelectorAll('img.port').forEach(e => e.classList.toggle('port', !isLandscape));
}

window.addEventListener('orientationchange', doOnOrientationChange);

Orientation from How do I correctly detect orientation change using Phonegap on iOS? Toggle from How to toggle class using pure javascript in html

aloisdg
  • 22,270
  • 6
  • 85
  • 105