0

I have a function which is almost working.

It finds an element with the class of .hex and then runs a random number between 5 and 13 and then appends those .hex items to the body of the document.

Then I have a delay and the hexagons are faded in and out slowly.

What I want to do is to create this on a loop so they constantly fade in and out.

I have commented out the code where this should work to my understanding, but currently doesn't.

All I did was to wrap all my code in a new function called initHex() and then after the code I use setInterval to run the function every 12 seconds (at the moment).

I can see in the console the function runs, and then starts looping very fast, the numbers incrementing dramatically, and quite quickly it stops the browser responding.

I am wondering if the function is wrapped around too much of the code.

The idea is that hopefully the current function is still running (fading out hexagons) as new ones are fading in.

I am assuming at the end of the function I will also require something to remove the existing hex elements so they don't keep getting added to the document. I did try this.

Here is the function:

 //function initHex() {

    $rndNum = Math.floor(Math.random() * 8) + 5;
    var e = $('.hex');
        for (var i = 0; i < $rndNum ; i++) {
        $docHeight = $(window).height();
        $docHeight = Math.random() * $docHeight * 2;
        $docWidth = $(window).width();
        $docWidth = Math.random() * $docWidth;
        $rndOpacity = Math.random();
        $rndSpeed = Math.floor(Math.random() * 2000) + 2000;
        e.each(function(){
            $(this).css({
                position:   'absolute',
                top:        $docHeight,
                left:       $docWidth - 195,
                opacity:    $rndOpacity
            });
            e.clone().prependTo('body').delay(e.length*800).fadeIn($rndSpeed).delay(1000).fadeOut($rndSpeed*2);
            console.log($rndNum, $rndOpacity, $rndSpeed);
        });
    }
//}

 //setInterval(initHex, 12000);

In terms of removing the hexagons once they have run I tried:

 e.clone().prependTo('body').delay(e.length*800).fadeIn($rndSpeed).delay(1000).fadeOut($rndSpeed*2.5, function(){
      e.remove();
 });

Here is the fiddle: http://jsfiddle.net/lharby/j5bSz/ Fork it to your hearts content.

TIA

lharby
  • 3,057
  • 5
  • 24
  • 56
  • Then what's the problem? – Bhojendra Rauniyar Oct 30 '13 at 09:55
  • I have some idea of what you want to achieve, that is, continuously fading in and out hexagons at random moments. I wonder if you append a whole lot to the body. You can also do tests, removing the interval after a certain amount of time (before it crashes) to check the heap, DOM, etc. – EricG Oct 30 '13 at 10:02
  • You're creating quite a few hexagons. If at a certain point you have 4 hexagons, you random 10, then you create 40 more hexagons. Run the function 5 times and you end up with roughly 400000 animated hexagons. That can kill any browser. – Tibos Oct 30 '13 at 10:07
  • The maximum number of hexagons the function will run once is 13. – lharby Oct 30 '13 at 10:11
  • Ahhh, do you mean that when the function runs the second time it will clone however many hexagons were created in the first function? So it is doubling each time? – lharby Oct 30 '13 at 10:12
  • Well setting var e = $('.hex:first'); seems to solve the issue of doubling, but it's a bit juddery at present. – lharby Oct 30 '13 at 10:49
  • 1
    Yup, Assuming that you need only 5-13 hexagons in your DOM at any given time. This fiddle solves the problem http://jsfiddle.net/j5bSz/4/ – nightf0x Oct 30 '13 at 11:30

1 Answers1

1

I have reworked your code. You made a few mistakes and yes you have tried to clone the whole bunch of elements with class hex each time, but the array have no method clone.

Try this:

function initHex() {

    var $rndNum = Math.floor(Math.random() * 8) + 5;
    for (var i = 0; i < $rndNum ; i++) {
        var $docHeight = $(window).height()
          , $top = Math.random() * $docHeight * 2
          , $docWidth = $(window).width()
          , $left = Math.random() * $docWidth - 195
          , $rndOpacity = Math.random()
          , $rndSpeed = Math.floor(Math.random() * 2000) + 2000;
        $('<div></div>').addClass('hex').css({
            position:   'absolute',
            top:        $top,
            left:       $left,
            opacity:    $rndOpacity
        }).prependTo('body').delay(1000).fadeIn($rndSpeed).delay(1000).fadeOut($rndSpeed*2, function(){
           this.remove();
        });
    }
}

setInterval(initHex, 12000);

One more thing, this code is still not optimized, but I have tried to save your code as much as possible to be more clear for you.

http://jsfiddle.net/andbas/DZSJT/1/

andbas
  • 591
  • 4
  • 8
  • Cool. I have a clunky version working where I only cloned $('.hex:first') but your method looks more economical. Do you know if there is a way for the function to fire as some of the hexagons are still fading out, I want to create an overlap if possible. – lharby Oct 30 '13 at 12:09
  • Could you please describe behavior of hex you are trying to reach? I don't think that I understood your question. – andbas Oct 30 '13 at 12:38
  • It's OK, I have done some research on SO, you cannot have the setInterval function firing before the function has run completely. http://stackoverflow.com/a/9219700/1238244 – lharby Oct 30 '13 at 12:49
  • Probably you're not fully understand javascript in it one thread concept. You have a lot of places in code where javascript thread could fire setInterval and function in it (each jQuery delay and fadeIn). Just try to set 1sec (1000) as a second parameter instead of 12sec (12000) and you'll see it. – andbas Oct 30 '13 at 13:48