Friday 25 March 2016

Web Tutorial: The Easter Egg Generator (Part 4/4)

In this final part, we're going to add some gloss over your egg, and a bit of functionality.

Now for the egg itself. It's looking decidedly flat, and we'll be fixing this. Add this to the HTML.
        <div id="egg_wrapper">
            <div id="egg">
                <div id="egg_overlay"></div>

                <div id="band1" class="band"></div>
                <div id="band2" class="band"></div>
                <div id="band3" class="band"></div>


And this to the CSS. This was generated by the CSS Gradient Generator. The opacity has been set to 50%. This gives your egg a fake 3D effect.
            #egg_overlay
            {
                 opacity: 0.5;
                 filter: alpha(opacity=50); /* For IE8 and earlier */
                 -webkit-border-radius: 63px 63px 63px 63px / 108px 108px 72px 72px;
                 border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
                 width:250px;
                 height:350px;
                 position:absolute;
                 z-index:900;
                 background: #feffff; /* Old browsers */
                 background: -moz-radial-gradient(100px 100px, ellipse cover,  #feffff 0%, #444444 58%); /* FF3.6+ */
                 background: -webkit-gradient(radial, 100px 100px, 0px, center center, 100%, color-stop(0%,#feffff), color-stop(58%,#444444)); /* Chrome,Safari4+ */
                 background: -webkit-radial-gradient(100px 100px, ellipse cover,  #feffff 0%,#444444 58%); /* Chrome10+,Safari5.1+ */
                 background: -o-radial-gradient(100px 100px, ellipse cover,  #feffff 0%,#444444 58%); /* Opera 12+ */
                 background: -ms-radial-gradient(100px 100px, ellipse cover,  #feffff 0%,#444444 58%); /* IE10+ */
                 background: radial-gradient(ellipse at 100px 100px,  #feffff 0%,#444444 58%); /* W3C */
                 filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#feffff', endColorstr='#444444',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
            }


So far so good?



Now add this to your HTML. This is meant to add a shadow under your egg.
                <div id="star_wrapper5" class="star_wrapper">
                    <div id="star5_part1" class="star_part1"></div>
                    <div id="star5_part2" class="star_part2"></div>
                    <div id="star5_part3" class="star_part3"></div>
                </div>

                <div id="rainbow_wrapper">
                    <div id="rainbowband1" class="rainbowband"></div>
                    <div id="rainbowband2" class="rainbowband"></div>
                    <div id="rainbowband3" class="rainbowband"></div>
                    <div id="rainbowband4" class="rainbowband"></div>
                    <div id="rainbowband5" class="rainbowband"></div>
                    <div id="rainbowband6" class="rainbowband"></div>
                    <div id="rainbowband7" class="rainbowband"></div>   
                </div>
            </div>

            <div id="egg_shadow"></div>
        </div>
    </body>
</html>


This is the CSS for it.
            #egg_shadow
            {
                border-radius: 50%;
                width:150px;
                height:10px;
                box-shadow: 0px 20px 5px 5px #999999;
                background:none;
                position:absolute;
                z-index:0;
            }


Take another look! But there's a problem - the shadow isn't correctly placed. Also, when you resize the egg, a bit of weirdness appears. You need to resize the egg_overlay div and the egg_shadow div as well.


So modify the setwidth() function to cater to the egg. Note that what we're doing for the egg div and egg_shadow div is basically what we did for rainbow_wrapper div, except that this time the adjustments are made in relation to the egg_wrapper div. Also, note that since the width of the egg is altered and the rainbow is drawn in relation to the egg, you need to fire off the setwidth() function for the rainbow_wrapper.
            function setwidth(varid)
            {
                $("#"+varid).width($("#rng_width_"+varid).val());

                if (varid=="egg")
                {
                    $("#egg_overlay").width($("#rng_width_"+varid).val());
                    $("#egg_shadow").width($("#rng_width_"+varid).val()/1.5);
                    $("#egg").css("margin-left", marginleft+"px");
                    $("#egg_shadow").css("margin-left", (($("#egg_wrapper").width()-$("#egg_shadow").width())/2)+"px");
                    setwidth("rainbow_wrapper");
                }

                if (varid=="rainbow_wrapper")
                {
                    $("#rainbow_wrapper").css("margin-left","-"+(($("#rainbow_wrapper").width()-$("#egg").width())/2)+"px");
                    $(".rainbowband").width($("#rng_width_"+varid).val()-($("#hid_thickness_rainbow").val()*2));
                }
            }


Now modify the setheight() function.
            function setheight(varid)
            {
                $("#"+varid).height($("#rng_height_"+varid).val());

                if (varid=="egg")
                {
                    var margintop=($("#egg_wrapper").height()-$("#egg").height())/2;

                    $("#egg_overlay").height($("#rng_height_"+varid).val());
                    $("#egg").css("margin-top", margintop+"px");
                    $("#egg_shadow").css("margin-top",(parseInt($("#rng_height_"+varid).val())+margintop-($("#egg_shadow").height()*2))+"px");
                }

                if (varid=="rainbow_wrapper")
                {
                    $(".rainbowband").height($("#rainbow_wrapper").height()*2);
                    $("#hid_thickness_rainbow").val($("#rainbow_wrapper").height()/20);
                   
                    $(".rainbowband").each(function()
                    {
                        $(this).css("border-width", $("#hid_thickness_rainbow").val()+"px");
                    });

                    $("#rainbowband1").css("margin-top", "0px");
                    $("#rainbowband2").css("margin-top", $("#hid_thickness_rainbow").val()+"px");
                    $("#rainbowband3").css("margin-top", ($("#hid_thickness_rainbow").val()*2)+"px");
                    $("#rainbowband4").css("margin-top", ($("#hid_thickness_rainbow").val()*3)+"px");
                    $("#rainbowband5").css("margin-top", ($("#hid_thickness_rainbow").val()*4)+"px");
                    $("#rainbowband6").css("margin-top", ($("#hid_thickness_rainbow").val()*5)+"px");
                    $("#rainbowband7").css("margin-top", ($("#hid_thickness_rainbow").val()*6)+"px");
                    setwidth("rainbow_wrapper");
                }
            }


Run your code again. Your overlay and shadow should move when you resize your egg now!


The Safari Fix

If you've been running your code so far, you'll realize it works on most other browsers but Safari. The overflow doesn't work and your rainbow, polka dots and whatnot are running out of the egg.


So yes, due to Safari's monkey crap different way of handling round corners and overflow rules in divs, here's a fix.

Add the following to your egg_wrapper div.
        <div id="egg_wrapper">
            <div id="egg">
                <div id="safari_fix"></div>
                <div id="egg_overlay"></div>

                <div id="band1" class="band"></div>
                <div id="band2" class="band"></div>
                <div id="band3" class="band"></div>


And style the safari_fix div. It's almost identical to the egg_overlay div, except that it has no background, its z-index property is set to higher than the egg_overlay's z-index property, and the box-shadow property is set to give the outline a red glow.
            #safari_fix
            {
                 -webkit-border-radius: 63px 63px 63px 63px / 108px 108px 72px 72px;
                 border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
                 width:250px;
                 height:350px;
                 position:absolute;
                 z-index:950;
                 box-shadow: 0px 0px 0px 500px #FF0000;
            }


Why red? Well, so it allows you to see what's going on, of course! See how the red part masks out the parts that are supposed to be hidden?


Change the color to white. Then when you run your code again, the effect should be there. This isn't a great solution (I mean, what if your the background color of your screen isn't white?), but web technology is often about improvisation.
            #safari_fix
            {
                 -webkit-border-radius: 63px 63px 63px 63px / 108px 108px 72px 72px;
                 border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
                 width:250px;
                 height:350px;
                 position:absolute;
                 z-index:950;
                 box-shadow: 0px 0px 0px 500px #FFFFFF;
            }


Of course, you'll have to alter your setheight() and setwidth() functions to reflect this.
            function setwidth(varid)
            {
                $("#"+varid).width($("#rng_width_"+varid).val());

                if (varid=="egg")
                {
                    $("#egg_overlay").width($("#rng_width_"+varid).val());
                    $("#safari_fix").width($("#rng_width_"+varid).val());
                    $("#egg_shadow").width($("#rng_width_"+varid).val()/1.5);
                    $("#egg").css("margin-left", marginleft+"px");
                    $("#egg_shadow").css("margin-left", (($("#egg_wrapper").width()-$("#egg_shadow").width())/2)+"px");
                    setwidth("rainbow_wrapper");
                }

                if (varid=="rainbow_wrapper")
                {
                    $("#rainbow_wrapper").get(0).style.marginLeft="-"+(($("#rainbow_wrapper").width()-$("#egg").width())/2)+"px";
                    $(".rainbowband").width($("#rng_width_"+varid).val()-($("#hid_thickness_rainbow").val()*2));
                }
            }

            function setheight(varid)
            {
                $("#"+varid).height($("#rng_height_"+varid).val());

                if (varid=="egg")
                {
                    var margintop=($("#egg_wrapper").height()-$("#egg").height())/2;

                    $("#egg_overlay").height($("#rng_height_"+varid).val());
                    $("#safari_fix").height($("#rng_height_"+varid).val());
                    $("#egg").css("margin-top", margintop+"px");
                    $("#egg_shadow").css("margin-top",(parseInt($("#rng_height_"+varid).val())+margintop-($("#egg_shadow").height()*2))+"px");
                }

                if (varid=="rainbow_wrapper")
                {
                    $(".rainbowband").height($("#rainbow_wrapper").height()*2);
                    $("#hid_thickness_rainbow").val($("#rainbow_wrapper").height()/20);
                   
                    $(".rainbowband").each(function()
                    {
                        $(this).css("border-width", $("#hid_thickness_rainbow").val()+"px");
                    });

                    $("#rainbowband1").css("margin-top", "0px");
                    $("#rainbowband2").css("margin-top", $("#hid_thickness_rainbow").val()+"px");
                    $("#rainbowband3").css("margin-top", ($("#hid_thickness_rainbow").val()*2)+"px");
                    $("#rainbowband4").css("margin-top", ($("#hid_thickness_rainbow").val()*3)+"px");
                    $("#rainbowband5").css("margin-top", ($("#hid_thickness_rainbow").val()*4)+"px");
                    $("#rainbowband6").css("margin-top", ($("#hid_thickness_rainbow").val()*5)+"px");
                    $("#rainbowband7").css("margin-top", ($("#hid_thickness_rainbow").val()*6)+"px");
                    setwidth("rainbow_wrapper");
                }
            }


Print functionality

Now that your egg's looking good, what else could you want? To output your awesome design, of course!

Add this to your CSS. This basically ensures that in a print view, the dashboard_wrapper div turns invisible and the egg_wrapper div takes center stage.
            @media print
            {
                #dashboard_wrapper {display: none;}
                #egg_wrapper
                {
                    display:block;
                    border-width:0px;
                    width:90%;
                    position:relative;
                    margin-left:auto;
                    margin-right:auto;
                }
            }


That's it for your Easter egg generator. And I hoped this helped illustrate how jQuery has its uses. I'm still not overly fond of it, but y'know, it's Easter, keep an open mind.

Have a good Easter Sunday, because He shell rise again!
T___T

No comments:

Post a Comment