4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【JavaScript】写真の一覧表示を画面に合わせて最適な大きさにして全部表示したい

Last updated at Posted at 2024-02-29

はじめに

モニターの画面いっぱいに写真の一覧を表示したい!という思いがあり、記事にしてみました!

モニターの大きさって色々あるので固定値ではなく、画面の大きさによって写真の大きさが一番大きく出るようにしたいです。

20枚でも40枚でも画面いっぱいにスクロールなしで、写真を見れるようにします。

結論

  function optimalWidth(photoNum, aspectRatio, allWidth, allHeight) {
    var resultWidth = 0;
    for (let i = 1; i <= photoNum; i++) {
      var w = allWidth / i;
      var heightNum = Math.ceil(photoNum / i);
      var h = allHeight / heightNum;
      var aspectH = w * aspectRatio * heightNum;
      var widthFromeight = h / aspectRatio;
      var aspectW = widthFromeight * i;
      if (allHeight >= aspectH && w > resultWidth) {
        resultWidth = w;
      }
      if (allWidth >= aspectW && widthFromeight > resultWidth) {
        resultWidth = widthFromeight;
      }
    }
    return resultWidth;
  }

こんな感じで作成しました。(わかりづらくてすみません)

optimalWidth関数に

第1引数:並ばせたい写真の数
第2引数:表示させる領域の縦横比
第3引数:写真を並ばせたい領域の横幅
第4引数:写真を並ばせたい領域の縦幅

をいれると、写真1枚の適切な横幅が返ってきます。

例えば、縦幅500pxと横幅500pxの領域に 縦:横 = 9:16 で5枚の写真を置きたいとすると、以下のように呼び出します。

var result = optimalWidth(5, 9/16, 500, 500);

// result = 250 が返却される

そうすると、その条件で一番写真が大きくなるような横幅が返ってきます。

それを写真1つ1つに横幅と縦幅を設定してあげると、最大サイズで画面に並ばせることができます。
image.png

こんな感じです。(真ん中ぞろえとかにはしてないのでお好みで)

もう一つやってみます。

縦幅500pxと横幅600pxの領域に 縦:横 = 9:16 で5枚の写真を置きたいとすると、

var result = optimalWidth(5, 9/16, 500, 500);

// result = 296.2962962962963 が返却される

image.png

こんな感じになります。

画面の横幅が変わった時

ウィンドウのサイズが変化したときの状態を感知して写真の大きさを変えたいというときがあるかもしれません。

そのために、ウィンドウのサイズが変わった時を検知するには以下のようにするといいです。

  var isPendding = false;
  function resizeWindow() {
    if (isPendding) {
      return;
    }
    isPendding = true;
    window.setTimeout(function () {
      isPendding = false;
    }, 50);
    console.log("サイズが変わりました");
  }
  window.addEventListener("resize", resizeWindow);

isPenddingを用意したのは、画面サイズが変わるときに何度も関数が呼ばれてしまい、無駄な計算が走りまくってしまうので、0.05秒のクールタイムを設けています。

ソース

念のため作成したソースを全て載せておきます。

<!DOCTYPE html>
<html>
 <head>
   <meta charset="UTF-8" />
   <meta name="viewport" content="width=device-width" />
   <title></title>
   <script src="https://cdn.tailwindcss.com"></script>
 </head>
 <body class="bg-gray-100 font-serif text-xl">
   <div
     id="all-area"
     class="w-[500px] h-[500px] flex flex-row flex-wrap bg-red-500"
   >
     <div class="js-photo-area bg-black border-white border"></div>
     <div class="js-photo-area bg-black border-white border"></div>
     <div class="js-photo-area bg-black border-white border"></div>
     <div class="js-photo-area bg-black border-white border"></div>
     <div class="js-photo-area bg-black border-white border"></div>
   </div>
   <script>
     function optimalWidth(photoNum, aspectRatio, allWidth, allHeight) {
       var resultWidth = 0;
       for (let i = 1; i <= photoNum; i++) {
         var w = allWidth / i;
         var heightNum = Math.ceil(photoNum / i);
         var h = allHeight / heightNum;
         var aspectH = w * aspectRatio * heightNum;
         var widthFromeight = h / aspectRatio;
         var aspectW = widthFromeight * i;
         if (allHeight >= aspectH && w > resultWidth) {
           resultWidth = w;
         }
         if (allWidth >= aspectW && widthFromeight > resultWidth) {
           resultWidth = widthFromeight;
         }
       }
       return resultWidth;
     }

     var photoNum = 5;
     var aspectRatio = 9 / 16;
     let allWidth = document.getElementById("all-area").clientWidth;
     let allHeight = document.getElementById("all-area").clientHeight;

     let optimalW = optimalWidth(photoNum, aspectRatio, allWidth, allHeight);

     var photoAreas = document.getElementsByClassName("js-photo-area");
     Array.from(photoAreas).forEach((photArea) => {
       console.log("s");
       photArea.style.width = optimalW + "px";
       photArea.style.height = optimalW * aspectRatio + "px";
     });

     var isPendding = false;
     function resizeWindow() {
       if (isPendding) {
         return;
       }
       isPendding = true;
       window.setTimeout(function () {
         isPendding = false;
       }, 50);
       console.log("サイズが変わりました");
     }
     window.addEventListener("resize", resizeWindow);
   </script>
 </body>
</html>

さいごに

いろいろ見ずらいコードを書いてしまったと思います。

もしもっといい書き方を知っている方や、間違っているよというような指摘をしてくれる方がいましたら、教えていただけると助かります。

最後まで読んでいただきありがとうございました。

4
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?