Question

I'm trying to make images that move randomly over the screen.

Images are positionned randomly over the screen, and then moves from -15px to 15px every 10ms.

But after a few seconds, images gets concentrated on the top-left corner of the screen instead of being scattered all over the screen (or at least being concentrated on another corner of the screen)...

You can see my code in action here: http://secretlabs.alwaysdata.net/bug.html

window.onload = function() {
    var imgUrl = 'http://image.jeuxvideo.com/smileys_img/18.gif';
    var imgs = [];
    var imgPos = [];

    for(var i = 0; i < 50; i++) {
        // Create 50 images.

        imgs.push(new Image());
        imgs[i].src = imgUrl;
        imgs[i].style.position = 'absolute';

        // Position them randomly on the screen.

        imgPos[i] = [Math.floor(Math.random() * window.innerWidth),
                    Math.floor(Math.random() * window.innerHeight)];

        imgs[i].style.left = imgPos[i][0] + 'px';
        imgs[i].style.top = imgPos[i][1] + 'px';
        document.body.appendChild(imgs[i]);
    }

    window.setInterval(function() {
        for(var i = 0; i < 50; i++) {
            // Move randomly each image from -15px to 15px, vertically and horizontally.

            imgPos[i][0] += Math.floor(Math.random() * 30) - 15;
            imgPos[i][1] += Math.floor(Math.random() * 30) - 15;

            // Avoid images to go out of the screen.

            if(imgPos[i][0] < 0)
                imgPos[i][0] = 0;
            if(imgPos[i][1] < 0)
                imgPos[i][1] = 0;
            if(imgPos[i][0] > window.innerWidth - 16)
                imgPos[i][0] = window.innerWidth - 16;
            if(imgPos[i][1] > window.innerHeight - 16)
                imgPos[i][1] = window.innerHeight - 16;

            imgs[i].style.left = imgPos[i][0] + 'px';
            imgs[i].style.top = imgPos[i][1] + 'px';
        }
    }, 10);
};
Was it helpful?

Solution

If you want something less biased, don't round towards negative values.

Replace

Math.floor(Math.random() * 30) - 15

with

Math.round(Math.random() * 30  - 15)

I just made a small test with this code :

var N = 1000000;
for (var j=0; j<20; j++) {
  var sum = 0;
  for (var i=N; i-->0;) sum += Math.round(Math.random() * 30  - 15);
  console.log(sum/N);
}

It seems OK (open the console)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top