Ogbobe Buko
Ogbobe Buko

Reputation: 89

Display Absolute positioned images inside a div

i am trying to absolute position images at random positions inside a div. i'm not sure how to get the calculations right for 'top' and 'left' but the images on occasions display outside of the div. i want to also prevent the overlapping of the images.

Any ideas would help

(function() {
  //array of links to the images
  var images = ["http://via.placeholder.com/150/800",
    "http://via.placeholder.com/150/080",
    "http://via.placeholder.com/150/008",
    "http://via.placeholder.com/150/880"
  ];

  //function to calculate a random integer
  var getRandomInt = function(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }

  //function to get a top and left value position for each image 
  var pos = function() {
    var wrapWidth = document.getElementById("wrap");
    wrapWidth = $("#wrap").width();
    wrapHeight = $("#wrap").height();

    // Image Position
    var xPos = getRandomInt(0, wrapWidth - 150);
    var yPos = getRandomInt(0, wrapHeight - 150);


    return {
      x: xPos + "px",
      y: yPos + "px"
    }

  }
  var displayImages = function(images) {
    var elementArray = [];
    for (var i = 0; i < images.length; i++) {
      var src = images[i];
      elementArray[i] = '<img class="imagePos" style="top:' + pos().x + '; left:' + pos().y + ' " src="' + src + ' "/>';
    }
    console.log(elementArray);
    elementArray.forEach(function(element) {

      console.log(element);
      $("#wrap").append(element);
    });
  }
  displayImages(images);
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="IntTree">
  <div id="header">
    <h1>Interactive Tree</h1>
  </div>
  <div id="wrap">

  </div>
</div>

Upvotes: 1

Views: 73

Answers (1)

Jason Warta
Jason Warta

Reputation: 450

I'm assuming that you have some css resembling this:

img {
    position: absolute;
    width:150;
    height:150;
}

Regarding your first issue, you appear to have your x and y assignments backwards in the bit where you're adding the elems to the array. Also, you're making 2 times as many calls to pos() as needed.

That line should be:

let position = pos();
elementArray[i] = '<img class="imagePos" style="top:'+position.y+'; left:'+position.x+' " src="'+src+' "/>';

For the second issue, you need to check for each image whether any of the corners overlap a different image. The easy way to achieve this by adding an array to track the positions you've already used, and comparing against the items in the array for subsequent position calculations.

(function (){
//array of links to the images
var images = ["http://via.placeholder.com/150/800",
    "http://via.placeholder.com/150/080",
    "http://via.placeholder.com/150/008",
    "http://via.placeholder.com/150/880"
  ];

//function to calculate a random integer
var getRandomInt = function (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

// array to track previous positions of images
var positions = [];

//function to get a top and left value position for each image 
var pos = function (){

    var wrapWidth = $("#wrap").width();
    var wrapHeight = $("#wrap").height();

    // Image Position
    var xPos = getRandomInt(0, wrapWidth - 150);
    var yPos = getRandomInt(0, wrapHeight - 150);

    var overlapX = true;
    var overlapY = true;

    while(overlapX && overlapY) {
        overlapX = false;
        overlapY = false;

        for(var i = 0; i < positions.length; i++) {

            // check if x coord is inside previously placed image
            if ( (xPos > positions[i].x && xPos < positions[i].x+150) || 
                 (xPos+150 > positions[i].x && (xPos+150) < positions[i].x+150) ){
                overlapX = true;
            }

            // check if y coord is inside previously placed image
            if( (yPos > positions[i].y && yPos < positions[i].y+150) || 
                (yPos+150 > positions[i].y && yPos+150 < positions[i].y+150) ) {
                overlapY = true;
            }
        }
        if (overlapX) {
            xPos = getRandomInt(0, wrapWidth - 150);
        }

        if (overlapY) {
            yPos = getRandomInt(0, wrapHeight - 150);
        }
    }

    positions.push({x:xPos,y:yPos});

    return {
        x: xPos + "px",
        y: yPos + "px"
    }

}
var displayImages = function(images){
    var elementArray = [];
    for (var i = 0; i < images.length; i++) {
        var src = images[i];

    let position = pos();
    elementArray[i] = '<img class="imagePos" style="top:'+position.y+'; left:'+position.x+' " src="'+src+' "/>';
    }
    elementArray.forEach(function(element) {    
        $("#wrap").append(element);
    });
}
displayImages(images);
})();

Upvotes: 1

Related Questions