Monday 19 September 2016

Web Tutorial: The Browser Butterfly (Part 3/3)

Your butterfly has begun to move, and now it needs to go places. Specifically, around your browser.

We'll start with some JavaScript. The global variables x, y, size, rotation and wingtimer point to the CSS properties that will be randomized. The variable nexttimer is is also randomized - it is the number of milliseconds to the next transition. The variable transitiontimer is just to set animation durations for everything else.
        <script>
        var x=0;
        var y=0;
        var size=0;
        var rotation=0;
        var transitiontimer;
        var wingtimer;
        var nexttimer;
        </script>


Of course, we'll need a random number generator function.
        <script>
        var x=0;
        var y=0;
        var size=0;
        var rotation=0;
        var transitiontimer;
        var wingtimer;
        var nexttimer;

        function generaterandomno(varmin,varmax)
        {
            return Math.floor((Math.random() * (varmax-varmin+1)) + varmin);
        }
        </script>


Next, we define the function flutter(). It accepts a variable vartimer, which is the number of milliseconds it will take to execute the next transition. First of all, we set the variable wrapper as the object pointing to the butterfly_wrapper div.
        var x=0;
        var y=0;
        var size=0;
        var rotation=0;
        var transitiontimer;
        var wingtimer;
        var nexttimer;

        function flutter(vartimer)
        {
            var wrapper=document.getElementById("butterfly_wrapper");
        }

        function generaterandomno(varmin,varmax)
        {
            return Math.floor((Math.random() * (varmax-varmin+1)) + varmin);
        }


Next, we set a random value to nexttimer. If the result is not between 1500 and 3000, it uses the default of 1500. You can change this if you like. Finally, we use the nexttimer variable to call the flutter() function again in the setTimeout() method. So the flutter() method will call itself repeatedly after a randomized number of milliseconds (between 1500 and 300).
        function flutter(vartimer)
        {
            var wrapper=document.getElementById("butterfly_wrapper");

            nexttimer=vartimer+(generaterandomno(-200,200));
            nexttimer=(nexttimer<1500||nexttimer>3000?1500:nexttimer);

            setTimeout(function(){flutter(nexttimer);},vartimer);
        }


Now, we generate the values for x, y, size, rotation and timer. Each of them has a minimum and maximum value. For example, size is the size of the butterfly. If it gets too small, it'll disappear. If it gets too large, it'll eat up your entire screen. So we need to provide a happy medium, say, between 10 to 50 pixels. Feel free to alter the defaults. It's all up to you!
        function flutter(vartimer)
        {
            var wrapper=document.getElementById("butterfly_wrapper");

            nexttimer=vartimer+(generaterandomno(-200,200));
            nexttimer=(nexttimer<1500||nexttimer>3000?1500:nexttimer);

            x+=generaterandomno(-80,80);
            y+=generaterandomno(-80,80);

            x=(x<20?30:x);
            y=(y<20?30:y);
            x=(x>250?240:x);
            y=(y>250?240:y);

            size+=generaterandomno(-10,10);
            size=(size<10?20:size);
            size=(size>50?40:size);

            rotation+=generaterandomno(-10,10);
            rotation=(rotation<-20?0:rotation);
            rotation=(rotation>20?0:rotation);

            transitiontimer=generaterandomno(20,50)/10;

            setTimeout(function(){flutter(nexttimer);},vartimer);
        }


Now use those variables to set the CSS properties of the variable wrapper. x determines the number of pixels from the left, and y determines the number of pixels from the top. size determines the width and height of wrapper. rotation determines the, well, rotation of wrapper. And transitiontimer determines how slowly or quickly the wrapper moves.
        function flutter(vartimer)
        {
            var wrapper=document.getElementById("butterfly_wrapper");

            nexttimer=vartimer+(generaterandomno(-200,200));
            nexttimer=(nexttimer<1500||nexttimer>3000?1500:nexttimer);

            x+=generaterandomno(-80,80);
            y+=generaterandomno(-80,80);

            x=(x<20?30:x);
            y=(y<20?30:y);
            x=(x>250?240:x);
            y=(y>250?240:y);

            size+=generaterandomno(-10,10);
            size=(size<10?20:size);
            size=(size>50?40:size);

            rotation+=generaterandomno(-10,10);
            rotation=(rotation<-20?0:rotation);
            rotation=(rotation>20?0:rotation);

            transitiontimer=generaterandomno(20,50)/10;

            wrapper.style.marginLeft=x+"px";
            wrapper.style.marginTop=y+"px";
            wrapper.style.width=size+"px";
            wrapper.style.height=size+"px";
            wrapper.style.transform="rotate("+rotation+"deg)";
            wrapper.style.webkitTransform="rotate("+rotation+"deg)";       
            wrapper.style.transition="all "+transitiontimer+"s";   
            wrapper.style.webkitTransition="all "+transitiontimer+"s";

            setTimeout(function(){flutter(nexttimer);},vartimer);
        }


Now we randomize the variable wingtimer, and declare the variables upperwings and lowerwings. Then we assign to them the array returned by the method getElementsByClassName(). So now upperwings points to the divs styled by the upperwing CSS class, while lowerwings points to the divs styled by the lowerwing CSS class. Then we use a For loop and iterate through each of these arrays, modifying the animation-duration property. This causes the wings to flap at random speeds. Here, I've taken the lazy way out and setting the variable k to a range between 0 and 1, because I know there are only two upper wings and lower wings.
        function flutter(vartimer)
        {
            var wrapper=document.getElementById("butterfly_wrapper");

            nexttimer=vartimer+(generaterandomno(-200,200));
            nexttimer=(nexttimer<1500||nexttimer>3000?1500:nexttimer);

            x+=generaterandomno(-80,80);
            y+=generaterandomno(-80,80);

            x=(x<20?30:x);
            y=(y<20?30:y);
            x=(x>250?240:x);
            y=(y>250?240:y);

            size+=generaterandomno(-10,10);
            size=(size<10?20:size);
            size=(size>50?40:size);

            rotation+=generaterandomno(-10,10);
            rotation=(rotation<-20?0:rotation);
            rotation=(rotation>20?0:rotation);

            timer=generaterandomno(20,50)/10;

            wrapper.style.marginLeft=x+"px";
            wrapper.style.marginTop=y+"px";
            wrapper.style.width=size+"px";
            wrapper.style.height=size+"px";
            wrapper.style.transform="rotate("+rotation+"deg)";
            wrapper.style.webkitTransform="rotate("+rotation+"deg)";       
            wrapper.style.transition="all "+timer+"s";   
            wrapper.style.webkitTransition="all "+timer+"s";

            wingtimer=generaterandomno(1,5);
            var upperwings=document.getElementsByClassName("upperwing");
            var lowerwings=document.getElementsByClassName("lowerwing");

            for (var k=0;k<=1;k++)
            {
                upperwings[k].style.animationDuration="0."+wingtimer+"s";
                upperwings[k].style.webkitAnimationDuration="0."+wingtimer+"s";
                lowerwings[k].style.animationDuration="0."+wingtimer+"s";
                lowerwings[k].style.webkitAnimationDuration="0."+wingtimer+"s";       
            }

            setTimeout(function(){flutter(nexttimer);},vartimer);
        }


Modify your HTML to run the flutter() function upon loading the page, with an arbitrary value of 1500. Again, change this value if you wish.
<body onload="flutter(1500);">


Run your code. You should now have a beautiful butterfly roaming around your page.


Other changes possible

The code sample restricts your butterfly to a small section of the page. You can actually make it go  all around the entire page by setting x and y to values between 0 and 100, and using percentages instead of pixels.

You can also make multiple butterflies with different colors. Just replicate the divs and name the ids differently, then modify the flutter() function to animate each one. I won't spoonfeed you here, figure this out yourself! The possibilities are endless.

Now that was pretty fly.
T___T

No comments:

Post a Comment