2

I want to place several elements of one class randomly on the page with Javascript / jQuery. My idea is to generate random values for margin-top, margin-left and z-index. The problem is that I need to generate values in between negative and positive (like from -150px to 300px) and I don't understand how to make it with the code I use:

$(".randomnumber").each(function () {
    var randomtop = Math.floor(Math.random() * 101);
    var randomleft = Math.floor(Math.random() * 101);
    var randomzindex = Math.floor(Math.random() * 101);
    $(this).css({
        "margin-top": randomtop,
        "margin-left": randomleft,
        "z-index": randomzindex
    });
});

http://jsfiddle.net/7JGqZ/651/

So the problems I have:

  1. Don't know how to make it work with negative values — for example I need the top-margin to be from -150px to 300px.

  2. The elements in the fiddle beave a bit strange, like their positions are not really random or like they're connected to each other...

Update:

Made it work, but still don't like the result, I actually would like elements to be placed randomly so they would fit the page size, I mean that elements would be placed all over the page, not going too far above the edge of the page. Now I have a parent element that is fixed in the centre of the page (has width and height = 0, top and bottom = 50%), and my idea was to position its child elements with generating top and left margins somehow like this:

$(document).ready(function(){
    $(".mood-img").each(function () {
        var height = $(window).height();
        var halfheight = height/2;
        var margintop = halfheight-400;
        var width = $(window).width();
        var halfwidth = width/2;
        var marginleft = halfwidth-500;
        var randomtop = getRandomInt(halfheight, margintop);
        var randomleft = getRandomInt(halfwidth, marginleft);
        var randomzindex = getRandomInt(1, 30);


        $(this).css({
            "margin-top": randomtop,
            "margin-left": randomleft,
            "z-index": randomzindex
        });
    });

    function getRandomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1) + min);
    }
});

http://jsfiddle.net/7JGqZ/657/

Kostsei
  • 99
  • 3
  • 8
  • 1
    As for #2, there is no true random when it comes to coding. As for #1, you could generate a random number from 0 to 450 then subtract 150... – Zach Saucier Nov 28 '13 at 20:57
  • For #1 you could generate random numbers between 0-450 and then subtract 150 to get at your desired range. – aztechy Nov 28 '13 at 20:59
  • Well, I've heard about that, but what I mean here is that elements are always placed in a group, not far from each other. – Kostsei Nov 28 '13 at 21:00
  • read this article [Math.random](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) – Givi Nov 28 '13 at 21:02
  • Can you please give me an example of how the code should look with those 0-450 - 150? – Kostsei Nov 28 '13 at 21:03
  • I've read that article, but still do not understand this subject well enough, sorry. – Kostsei Nov 28 '13 at 21:05
  • 1
    [jsFiddle](http://jsfiddle.net/GKDev/trdht/1/) ***Updated*** – Givi Nov 28 '13 at 21:06
  • @Zeaklous - then post it as an answer, not just a comment. – adeneo Nov 28 '13 at 21:07

1 Answers1

7

As for #1, you could generate a random number from 0 to 450 then subtract 150

$(".randomnumber").each(function () {
    var randomtop = Math.floor(Math.random() * 450 - 150);
    var randomleft = Math.floor(Math.random() * 450 - 150);
    var randomzindex = Math.floor(Math.random() * 450 - 150);
    $(this).css({
        "margin-top": randomtop,
        "margin-left": randomleft,
        "z-index": randomzindex
    });
});

Updated jsFiddle

If you want the elements to be randomly placed throughout the entire screen without overlapping the edges, you can use the following instead: Demo (I cleaned it up a bit too)

As for #2, there is no true random when it comes to coding. Most randoms, like Math.random are derived from the time. From Mozilla:

Returns a pseudo-random number in the range [0,1) — that is, between 0 (inclusive) and 1 (exclusive). The random number generator is seeded from the current time, as in Java.

The numbers are as random as possible in javascript. Google more information and alternates if you don't believe me

To demonstrate how well Math.random works, I edited the project to allow any number of element, set by numElems. Try it a few times, it works pretty well. Demo here

EDIT

I'd also recommend using scrollHeight and scrollWidth as opposed to using jQuery's width() and height() because it is more inclusive, thus giving a more accurate top value

Community
  • 1
  • 1
Zach Saucier
  • 24,871
  • 12
  • 85
  • 147
  • Thanks! I made it work, but still don't understand how these random values are generated, it seems like the elements are in some kind of interconnections which make it look not random enough(: I've tried to include page size calculation in script code, but can't make it work: http://jsfiddle.net/7JGqZ/656/ – Kostsei Nov 28 '13 at 22:07
  • 1
    @Kostsei Updated my answer again with a demo allowing `x` number of elements. Test `Math.random()`'s randomness with it – Zach Saucier Nov 28 '13 at 23:13
  • I believe you about randomness, I've actually meant that may be there's a problem with CSS positioning itself or I just don't calculate those random values right. Anyway, thank you so much for your help, I think I'll figure out how to make it all work as I want. – Kostsei Nov 29 '13 at 06:53
  • What seemed strange to me is that elements look like always positioning in a group when I use it in my project, while in the fiddle they look positioned more natural. May be it's because elements in the fiddle are pretty much smaller then elements I use in my page layout. That's why I wanted to exclude the elements's size from positive margin. – Kostsei Nov 29 '13 at 06:59
  • Changed the script a bit more, now the randomness seems fine, but sometimes elements positioned the way they shouldn't, like if the calculations go wrong — http://jsfiddle.net/7JGqZ/663/ And what's the difference between `Math.floor(Math.random() * 30);` and `Math.floor(Math.random() * (max - min + 1) + min);` – Kostsei Nov 29 '13 at 08:22
  • `(30 - 1 + 1) + 1) = 31`, you should be returning `Math.floor(Math.random() * (max - min) + min);` instead and be inputting it from 0 to 30 instead of 1 to 30 – Zach Saucier Nov 29 '13 at 15:16
  • [**Updated jsFiddle**](http://jsfiddle.net/Zeaklous/7JGqZ/664/) using the new math, input, and using `scrollHeight`/width which is a more inclusive dimension measurement – Zach Saucier Nov 29 '13 at 15:25
  • Thank you, but I've just figured out that the problem is because the elements which I want to place randomly are hidden by default — you can see them only when you click on a certain other element, and because of that their sizes cannot be calculated and I have the whole calculation wrong, #plane (html, body) were set fine from the start, but when I wanted to exclude image size to calculate the position, that size was always 0 and that made images to have too big top and left margins... – Kostsei Nov 29 '13 at 16:30
  • Here you can take a look at what I'm actually trying to do: http://thelocalgenius.com/patterns/brick-wall-classics/ I've made lots of changes there, some previous js and html code is stored as inactive. – Kostsei Nov 29 '13 at 16:34
  • 1
    I see. To calculate the dimensions of a hidden object a common practice is to position it off screen and calculate it then hide it again. Best of luck with your project! – Zach Saucier Nov 29 '13 at 18:07
  • I thought about that, but if I place something off screen with `margin-left:-1000px;` or something like that, won't it affect the calculated size of the page? And I also had an idea, but not sure it's possible — to calculate image width and height via a link to image file. Or is it out of Javascript abilities? Thanks a lot for your help! – Kostsei Nov 29 '13 at 19:07
  • You'd temporarily position it using `top:100%` or `left:100%`. This way you don't add margins or anything and it's not causing extra rendering space yet it's still off screen. And there is no use in calculating it with a link, it'd be more work and processing than it's worth – Zach Saucier Nov 29 '13 at 19:24
  • I have even more strange problem now — in Firefox the first two elements are calculated wrong (null) while other go okay although they are all the same both in html and js. And in Chrome/Safari first two get null, others 0... – Kostsei Nov 30 '13 at 10:58
  • Post a question about it on SO, I cannot help you further – Zach Saucier Nov 30 '13 at 13:57
  • Thank you so much! Wonderful idea! Helped me create stars that are randomly positioned on the page. – www139 Aug 04 '15 at 01:16