web関連

【javascript】ランダム配置した画像が極力位置が被らないように調整

2020/05/22

/

画像をランダム配置したときに結構な確率で画像同士が被ったりするので極力被らないように調整してみた

ソース

通常のランダムで画像を均等に配置してみたかったので作った

ランダム配置した画像が極力被らないようにしたデモ
たまに無限ループ?起こす…
<div class="container">
  <ul class="imgList">
    <li><img src="https://twotone.me/wp-content/uploads/2020/05/img_cloud01.png" alt="雲1" /></li>
    <li><img src="https://twotone.me/wp-content/uploads/2020/05/img_cloud01.png" alt="雲2" /></li>
    <li><img src="https://twotone.me/wp-content/uploads/2020/05/img_cloud01.png" alt="雲3" /></li>
    <li><img src="https://twotone.me/wp-content/uploads/2020/05/img_cloud01.png" alt="雲4" /></li>
    <li><img src="https://twotone.me/wp-content/uploads/2020/05/img_cloud01.png" alt="雲5" /></li>
    <li><img src="https://twotone.me/wp-content/uploads/2020/05/img_cloud01.png" alt="雲6" /></li>
    <li><img src="https://twotone.me/wp-content/uploads/2020/05/img_cloud01.png" alt="雲7" /></li>
    <li><img src="https://twotone.me/wp-content/uploads/2020/05/img_cloud01.png" alt="雲8" /></li>
    <li><img src="https://twotone.me/wp-content/uploads/2020/05/img_cloud01.png" alt="雲9" /></li>
    <li><img src="https://twotone.me/wp-content/uploads/2020/05/img_cloud01.png" alt="雲10" /></li>
  </ul>
  <div class="bg"></div>
</div>

<script>
jQuery(function($){
  // 引数で渡した範囲内のランダムな整数を生成するための関数
  var getRandomInt = function(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  };

  // 要素の取得
  var $container = $('.container'),
    $imgList = $('.imgList').find('li'),
    containerWidth = $container.width(),//コンテンツ幅取得
    containerHeight = $container.height()/1.75;//コンテンツ高さ取得


  // 前回作成した条件を関数化
  function makeArray(value,list_arr,margin){
    var max_num = value,//ランダムで生成する最大値
      array = [],
      random = getRandomInt(0, max_num),//ランダム数値生成
      num = margin,//範囲数値
      i=0,
      len = array.length,//配列の数
      loop = 0,//無限ループ対策
      max_len = list_arr;//配列の最大数

      array.push(random);
      console.log('初期値'+random+'を生成');

    while(true){
      len = array.length;
      loop = 0;//無限ループ対策
      for (i = 0; i < len; i++) {

        console.log('配列数【'+len+'】の'+i+'回目');
        console.log('【'+array[i]+'】のループ');

        var min = array[i]-num;//範囲の最小値
        var max = array[i]+num;//範囲の最大値
        if(Math.sign(min) == -1){//minが負の数になったときに最小値をに戻す(負の数だと無限ループ入っちゃう)
          min = 0;
        }
        while((random >= min && random <= max) || array.includes(random) || random == 0){//左から:random数値が最小and最大の範囲外かどうか検証 or random数値が配列の数値と被らないか検証 or random数値が0じゃないかどうか検証

          random = getRandomInt(0, max_num);//再度数値をリセット
          console.log('ランダム数値【'+random+'】を生成');
          if(!i == 0){
            i=0;//変数をリセットして配列の一番最初から再スタート
          }

          min = array[i]-num;
          max = array[i]+num;
          if(Math.sign(min) == -1){
            min = 0;
          }

          //①ここから
          console.log('loopは'+loop+'回目');
          if(loop == 30){//無限ループ対策
            loop = 0;
            console.log('無限ループ脱出');
            break;
          }
          loop++;
          //①ここまで

        }
      }
      array.push(random);//配列に被らない数値を追加
      console.log(random+'を追加');

      if(Math.floor(max_len)-1 == len){//最後のループになったらwhileループを抜けるための条件式
        // alert('配列と数値、範囲が被らない数値は【 '+array+' 】です');
        return array;
        break;
      }
    }
  }

  //生成した配列を変数に代入
  var topPos = makeArray(containerHeight,$imgList.length,20);
  var leftPos = makeArray(containerWidth,$imgList.length,80);
  alert('Y軸の数値'+topPos+'\nX軸の数値'+leftPos);


  // ランダム座標を設定
  $imgList.each(function(index) {
    $(this).css({
      top: topPos[index],
      left: leftPos[index]
    });
  });
});
</script>

関数にしている部分は前回作成したものを使ってる

一応これで、当初の目的である
ランダム配置した画像が重なったり、偏ったりしないようにはできたんだけど
ループ抜けるための処理がうまく動かなくなったりして課題だらけ

とてもじゃないけど、仕事で使えるようなレベルじゃないので
時間を空けて再チャレンジしようと思う

 

完全に勉強としてやったけど、一から書こうと思うとうまくいかないね
コロナで時間もあることなので、少しづつでもいいから続けようと思う