Tuesday 13 September 2016

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

Nature sometimes inspires. And at the risk of sounding like some tree-hugger wannabe, the sight of a butterfly flitting around my neighbor's potted flowers spurred me to create my own version - a browser-based version, that is.

Imagine a butterfly moving around your web page, in random directions and speeds...

Done imagining? Ponder no more; we're going to make this a reality.

This web tutorial leverages heavily on CSS3 animations, 3D transformations in particular, and JavaScript Timer functions. But in the first part of this tutorial, we're just going to concentrate on building the butterfly.

This is the initial HTML. We start off with a div tag and assign it an id of butterfly_wrapper. This is the div that will be moved around the screen, rotated and resized at random later on. It will contain the wings of the butterfly.
<html>
    <head>
        <title>Butterfly</title>

        <style type="text/css">

        </style>

        <script>

        </script>
    </head>

    <body>
        <div id="butterfly_wrapper">

        </div>
    </body>
</html>


Here's the CSS code for butterfly_wrapper. We're giving it a position of absolute because it needs to move around the page and avoid displacing other DOM objects while it does so. Width and height are set to an initial value of 150 pixels. The final product is not going to be that big, but let's set it at this size to make things clearer.
    <style type="text/css">
        #butterfly_wrapper
        {
            width:150px;
            height:150px;
            position:absolute;
        }
    </style>


To make things visually easier for us, let's add this to the code. This ensures that all divs will have a nice red border so you can see what's happening as we change the code.
        div {border:1px solid #FF0000;}

        #butterfly_wrapper
        {
            width:150px;
            height:150px;
            position:absolute;
        }


See?


Now, let's put in some placeholders for the wings. These are divs that are assigned the CSS class leftwings and rightwings, respectively.
    <div id="butterfly_wrapper">
        <div class="leftwings">

        </div>
        <div class="rightwings">

        </div>
    </div>


The CSS classes are like so. Both leftwings and rightwings take up 50% of butterfly_wrapper's width, and 100% of its height. They will adhere to the top of butterfly_wrapper. leftwings will stick to the left side of butterfly_wrapper, while rightwings will stick to the right side.
        div {border:1px solid #FF0000;}

        #butterfly_wrapper
        {
            width:150px;
            height:150px;
            position:absolute;
        }

        .leftwings,.rightwings
        {
            position:absolute;
            width:50%;
            height:100%;
            top:0;
        }

        .leftwings
        {
            left:0;
        }

        .rightwings
        {
            right:0;
        }


So far, this is what you should see.


OK now, for leftwings and rightwings, we include two divs in each of them, with a CSS class of perspective. This will be necessary for 3D transformations later on.
    <div id="butterfly_wrapper">
        <div class="leftwings">
            <div class="perspective">

            </div>
            <div class="perspective">

            </div>
        </div>
        <div class="rightwings">
            <div class="perspective">

            </div>
            <div class="perspective">

            </div>
        </div>
    </div>


The CSS class for perspective is like so. They'll take up the full width of their parent divs (which in turn are 50% of butterfly_wrapper's width) and only 50% of the height. That's because  the butterfly's wings are segmented into upper and lower wings.
        .leftwings
        {
            left:0;
        }

        .rightwings
        {
            right:0;
        }

        .perspective
        {
            position:relative;
            width:100%;
            height:50%;
        }


So far so good?


Now add a div inside each of these divs. These divs will have two classes each. This is deliberate as the classes have overlapping style elements. We could simply style each wing individually, but that would entail a fair bit of unnecessary repetition.
    <div id="butterfly_wrapper">
        <div class="leftwings">
            <div class="perspective">
                <div class="upperwing upperwing_left">

                </div>
            </div>
            <div class="perspective">
                <div class="lowerwing lowerwing_left">

                </div>
            </div>
        </div>
        <div class="rightwings">
            <div class="perspective">
                <div class="upperwing upperwing_right">

                </div>
            </div>
            <div class="perspective">
                <div class="lowerwing lowerwing_right">

                </div>
            </div>
        </div>
    </div>


Pay close attention - this next part could be tricky. The CSS classes upperwing and lowerwing determine the sizes of the upper and lower wings. This is true for both left and right wings. Upper wings are larger, and lower wings smaller. This is reflected in the width and height values. lowerwing has top set to 0 in order to keep the upper and lower wings from looking disjointed. This may not be strictly necessary, but good to have.
        .perspective
        {
            position:relative;
            width:100%;
            height:50%;
        }

        .upperwing
        {
            position:absolute;
            width:100%;
            height:100%;
        }

        .lowerwing
        {
            position:absolute;
            top:0;
            width:80%;
            height:80%;
        }


Starting to look a mite complicated, isn't it?


Now, we shape the wings based on their positions. You may want to refer to this documentation on the border-radius property.
        .upperwing
        {
            position:absolute;
            width:100%;
            height:100%;
        }

        .upperwing_left
        {
            border-top-left-radius: 10%;
            border-top-right-radius: 80%;
            border-bottom-right-radius: 0%;
            border-bottom-left-radius: 30%;
        }

        .upperwing_right
        {
            border-top-left-radius: 80%;
            border-top-right-radius: 10%;
            border-bottom-right-radius: 30%;
            border-bottom-left-radius: 0%;
        }

        .lowerwing
        {
            position:absolute;
            top:0;
            width:80%;
            height:80%;
        }

        .lowerwing_left
        {
            right:0;
            border-top-left-radius: 30%;
            border-top-right-radius: 0%;
            border-bottom-right-radius: 80%;
            border-bottom-left-radius: 10%;
        }

        .lowerwing_right
        {
            left:0;
            border-top-left-radius: 0%;
            border-top-right-radius: 30%;
            border-bottom-right-radius: 10%;
            border-bottom-left-radius: 80%;
        }


Ah yes, starting to take shape!


Now add this code. This styles both upperwing and lowerwing classes with a nice radial pattern I shamelessly generated from colorzilla. Feel free to apply your own colors!
        .perspective
        {
            position:relative;
            width:100%;
            height:50%;
        }

        .upperwing,.lowerwing
        {
            background: #FF4400; /* Old browsers */
            background: -moz-radial-gradient(center, ellipse cover, #FF4400 0%, #FFEE00 50%, #FF4400 100%); /* FF3.6-15 */
            background: -webkit-radial-gradient(center, ellipse cover, #FF4400 0%,#FFEE00 50%,#FF4400 100%); /* Chrome10-25,Safari5.1-6 */
            background: radial-gradient(ellipse at center, #FF4400 0%,#FFEE00 50%,#FF4400 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
            filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FF4400', endColorstr='#FF4400',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
        }

        .upperwing
        {
            position:absolute;
            width:100%;
            height:100%;
        }


Getting warmer...


Do this to your code. This will remove the red border.
    div {border:0px solid #FF0000;}


Damn, that's pretty.


We've created the basic shape of the butterfly. But it's cold and lifeless as a fossil. Soon, we'll be emulating Mary Shelley's Frankenstein and injecting some life into it!

Next

Animating the wings!

No comments:

Post a Comment