How to prevent randomly positioned images from overlapping using Angular


Tags: javascript,html,css,angularjs

Problem :

I have an Angular application that loads multiple images on to the page at random locations by utilizing the following code:

HTML:

<div ng-repeat="s in selectedImages" class="container">
    <img ng-src="{{s.img}}" class="sImage" ng-style="s.pos"/>
</div>

CSS:

.wordImage {
    position:absolute; 
    width:100px;
}

JS Controller:

function loadImages() {
    $scope.myImages = ['img1.png', 'img2.png', 'img3.png', 'img4.png', 'img5.png']
    $scope.selectedImages = [];
    for (i in $scope.myImages) {
        $scope.selectedImages.push(addRandomLocationToImage($scope.myImages[i]));
    }
}

function addRandomLocationToImage(image) {
    image.pos = {};
    var preTop  = getRandomHeight(); // get Height for this image
    var preLeft = getRandomWidth(); // get Width for this image
    image.pos = {top:preTop,
                left:preLeft};
    return image; // returns the same image object but contains pos{} for ng-style
}

function getRandomHeight() {
    var imgHeight = 100;
    var winHeight = $(window).height();
    var randomH   = Math.random() * (winHeight - 100); // subtract 100 for the header. and also footer padding
    if (randomH < 150) {
        randomH += 150;  // add to keep it out of the header
    }
    if(winHeight - randomH < 100) { // if image will be on bottom edge of page
        randomW -= imgHeight; // subtract 100 because that is the height of the images, this will prevent them from being partially off the page
    } 
    return randomH;
}

function getRandomWidth() {
    var imgWidth  = 100; 
    var winWidth  = $(window).width(); 
    var randomW   = Math.random() * winWidth;
    if (randomW < 0) { // make sure it is not less than zero, then assign new number until it is greater than zero
        while (randomW < 0) {
            randomW = Math.random() * winWidth;
        }
    }
    if (winWidth - randomW < 100) { // if image will be on right edge of page
        randomW -= imgWidth; // subtract 100 because that is the width of the images, this will prevent them from being partially off the page
    }     
    return randomW;    
}

loadImages();

This definitely generates random images on a page...but they overlap very easily. My question is, how can I prevent them from overlapping? Here is some code that I have been working on.

var newLeft = currentImage.pos.left;
var newTop = currentImage.pos.top;
for (i in $scope.selectedImages) {
    var originalLeft = $scope.selectedImages[i].pos.left;
    var originalTop  = $scope.selectedImages[i].pos.top;
    if ((originalLeft - newLeft < 100 && originalLeft - newLeft > -100) && // could overlap horizontally
        (originalTop  - newTop  < 100 && originalTop  - newTop  > -100)) { // could overlap vertically
            //do something to select a new random location.
    }
}


Solution :

Basically you have to check a image position with every other image. You can use Array.some for this:

Considering that you store the image position in the image object as x and y properties

function checkCollision(testImage) {
  return $scope.myImages.some(function(img) {
    if (img == testImage)
      return false;

    if (!img.x || !img.y) // Image has no position yet
      return false;

    return
      testImage.x < img.x + imgWidth &&
      testImage.x + imgWidth > img.x &&
      testImage.y < img.y + imgHeight &&
      testImage.y + imgHeight > img.y;
  });
}

You have to be aware that depending of the available space and image sizes there might be a situation where is not possible to find a suitable position for a image.

I made a functional example.


    CSS Howto..

    How to style using d3's .style() method instead of using CSS in style tags for .axis path {}?

    How to take a div that is off screen and translate it to the middle of the screen using translateX()

    How to dynamically import javascript and css files

    How to fade out text on top of semi-transparent div using CSS?

    Selenium: How to get text from within an html tag which has another tag in it

    css: How to make elements not to overlap + automatically place them in a relevant position

    I can't make the a Background image display & and can't figure out how to fit text into the image

    How to make a content property in css use php

    How to size images loaded from other users such that dimensions are maintained yet a max width and height are set with css? (HTML/JS/CSS)

    Rails 4: How to style navigation for current page using jQuery

    How can I produce an nested list in XHTML strict without giving the nested lists first element a double bullet?

    How to center text inside a div element? [duplicate]

    How do I select immediate children in jQuery [closed]

    How to enable Stylus url() rewrites

    CSS Styles How to make this table not fill the entire page width?

    How can I use CSS to keep content in its own column?

    How to change color of text from left to right along with the background?

    style a navigation link when a particular div is shown

    How can I see “:hover” and “:active” properties of elements on a webpage? [duplicate]

    IE10 has extra margin above an inline header. How do I remove it?

    How do I center content and extend the background color to 100% of the page?

    How to make an image resize to the screens height with CSS?

    how to print no blur content over a blurred div

    how to style margins between items in a
    list?

    How to use regex to match css elements

    How to Hide Specific Part of Flash Object Using CSS?

    How to add contact details next to responsive Google Map

    How to get ratio of scale image, when it's autoscaled by background-cover?

    How do you get a Radio Button to change text color in html with jquery?

    how to use linked animated css?