Friday, 8 January 2016

Web Tutorial: Star Wars Scroll Text


Use the Force! Star Wars returned to the silver screen last month with Episode VII: The Force Awakens, and with it legions of slavering fanboys (your Teochewness included!).



With that in mind, I think it's only appropriate to style this month's web tutorial on the Star Wars scroll text. You know that starry background with the introductory text emerging from the bottom of the screen to a point in the distance? Yep, that's the one.

We'll start with a black background here.
<!DOCTYPE html>
<html>
    <head>
        <title>Star Wars</title>

        <style type="text/css">
        body
        {
            background-color:#000000;
        }
        </style>

        <script>

        </script>
    </head>

    <body>

    </body>
</html>


So space is black, but we're missing the stars that give space its twinkly goodness. Add this to the body. It's the overlay that will hold all the stars we'll generate.
    <body>
        <div id="star_wrapper">

        </div>
    </body>


Add this to the CSS. This ensures that the star_wrapper div is positioned on top of everything and covers the entire screen.
        <style type="text/css">
        body
        {
            background-color:#000000;
        }

        #star_wrapper
        {
            position:absolute;
            z-index:500;
            left:0;
            top:0;
            width:100%;
            height:100%;
        }
        </style>


Now, we're going to make stars. Each star is a div with the CSS class star. It's circular, thus border-radius is set to 50%, and it'll be given a position of absolute so that it's position doesn't interfere with the rest of the stars inside the star_wrapper div.
        <style type="text/css">
        body
        {
            background-color:#000000;
        }

        #star_wrapper
        {
            position:absolute;
            z-index:500;
            left:0;
            top:0;
            width:100%;
            height:100%;
        }

        .star
        {
            border-radius:50%;
            position:absolute;
        }
        </style>


OK, what next? We could manually include divs into the star_wrapper div, but that's too much like work. How many would you type in - a hundred? A thousand? No, we're going to make JavaScript do the work for us, much the same way we implemented the snowflakes last Christmas. Make these changes to your HTML and add the stars() function. Here, we define a variable wrapper which will be used to represent the star_wrapper div. Another variable, node, will represent each star as it is created. nodesize, nodeopacity, nodex and nodey are variables to hold the randomly generated values for each node.
        <script>
        function stars()
        {
            var wrapper=document.getElementById("star_wrapper");
            var node;
            var nodesize,nodeopacity,nodex,nodey;
        }
        </script>
    </head>

    <body onload="stars();">


Now we'll add the standard function generaterandomno(), which will be used to create stars with random appearances and positions. Using a For loop, we'll create 500 stars. This is not set in stone; if you want a thousand or just ten, change the value.

Each star is small, so we'll set the range from 1 to 3 pixels for height and width. nodeopacity will be a number from 1 to 10, and it'll be used to determine how bright different stars are. And of course, nodex and nodey are given a number from 1 to 99. That's the percentage each star is offset from the top left hand corner.
        <script>
        function stars()
        {
            var wrapper=document.getElementById("star_wrapper");
            var node;
            var nodesize,nodeopacity,nodex,nodey;

            for (var i=0;i<500;i++)
            {
                nodesize=generaterandomno(1,3);
                nodeopacity=generaterandomno(1,10);
                nodex=generaterandomno(1,99);
                nodey=generaterandomno(1,99);

                node=document.createElement("div");
                node.className="star";
                node.style.width=nodesize+"px";
                node.style.height=nodesize+"px";
                node.style.backgroundColor="rgba(255,255,255,"+nodeopacity/10+")";
                node.style.left=nodex+"%";
                node.style.top=nodey+"%";

                wrapper.appendChild(node);
            }
        }

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


Run your code. We have a starry space background!


That's just the beginning. We'll be making the scroll text next. For that, we'll use a nested div. Add this to your HTML.
    <body onload="stars();">
        <div id="star_wrapper">

        </div>

        <div id="diagonal_wrapper">
            <div id="text_wrapper">
                <p>A long long time ago, in a galaxy far far away...</p>
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
                <p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
             </div>
        </div>
    </body>


Add the CSS for the diagonal_wrapper div and the text_wrapper div.
        .star
        {
            border-radius:50%;
            position:absolute;
        }

        #diagonal_wrapper
        {
            position:relative;
            z-index:50;
            width:70%;
            height:600px;
            margin: 0 auto 0 auto;
            border:1px solid #FFFFFF;
        }

        #text_wrapper
        {   
            z-index:50;       
            width:100%;
            height:200%;
            margin-top:100%;
            font-size:3em;
            font-weight:bold;
            font-family:arial;
            color:#FFFF00;
        }


The diagonal_wrapper div is so named because at some point, we'll be rotating it along its X-axis. It is 70% as wide as the full screen and set in the middle. An arbitrary height of 600px has been set. I've also given it a white border so you can see clearly what we're doing.

The text_wrapper div holds the scrolling text, and is set to be as wide as the diagonal_wrapper div, and twice as tall. margin-top has been set to 100% so that at the start of everything, it appears under the diagonal_wrapper div. The font size and color are cosmetic, but I've set the text color to yellow. Very Star Wars-y, yes?

This is what you should be seeing. You won't see the yellow text unless you scroll down.



Now add this to your text_wrapper CSS specification. We're going to animate it. The movetext keyframe specification moves the text_wrapper div from the bottom of the diagonal_wrapper div to the top. Since the text_wrapper div's height has been set to 200%, in order for it to appear at the top, margin-top has to be set to -200%. And that's what we've done in the movetext keyframe specification.
        #text_wrapper
        {   
            z-index:50;       
            width:100%;
            height:200%;
            margin-top:100%;
            font-size:3em;
            font-weight:bold;
            font-family:arial;
            color:#FFFF00;
            -webkit-animation-name: movetext;
            -webkit-animation-duration: 20s;
            -webkit-animation-delay: 0s;
            -webkit-animation-iteration-count: infinite;
            -webkit-animation-timing-function: linear;
            animation-name: movetext;
            animation-duration: 20s;
            animation-delay: 0s;
            animation-iteration-count: infinite;
            animation-timing-function: linear;
        }
           
        @-webkit-keyframes movetext{
            from {margin-top:100%;}
            to {margin-top:-200%;}
        }
           
        @keyframes movetext{
            from {margin-top:100%;}
            to {margin-top:-200%;}
        }


Refresh your browser. Does the text move?


Modify the CSS. This will ensure that you won't see the text_wrapper div once it moves beyond the diagonal_wrapper div's boundaries.
        #diagonal_wrapper
        {
            position:relative;
            z-index:50;
            width:70%;
            height:600px;
            margin: 0 auto 0 auto;
            border:1px solid #FFFFFF;
            overflow:hidden;
        }


Refresh your browser. The text should now appear from the bottom of the diagonal_wrapper div and disappear at the top.

Now the appearance and disappearance of the text is a little abrupt, don't you think? We'll rectify this by adding a gradient layer on top of the diagonal_wrapper div. Add this to your HTML.
        <div id="diagonal_wrapper">
            <div id="overlay"></div>
            <div id="text_wrapper">
                <p>A long long time ago, in a galaxy far far away...</p>
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
                <p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
            </div>
    </div>


Now style your overlay div with this. Its position property is set to absolute and its z-index property is set to 100, which is higher than the text_wrapper div's z-index property. So it will cover the entire diagonal_wrapper div and appear over the text_wrapper div. The gradient background was generated at ColorZilla. It goes from an opaque black to full transparency, then back to an opaque black again.
        #overlay
        {
            position:absolute;
            z-index:100;
            top:0;
            left:0;
            width:100%;
            height:100%;
            background: -moz-linear-gradient(top,  rgba(0,0,0,1) 0%,rgba(0,0,0,0) 40%, rgba(0,0,0,0) 60%, rgba(0,0,0,1) 80%,

rgba(0,0,0,1) 100%); /* FF3.6-15 */
            background: -webkit-linear-gradient(top,  rgba(0,0,0,1) 0%,rgba(0,0,0,0) 40%,rgba(0,0,0,0) 60%, rgba(0,0,0,1)

80%,rgba(0,0,0,1) 100%); /* Chrome10-25,Safari5.1-6 */
            background: linear-gradient(to bottom,  rgba(0,0,0,1) 0%,rgba(0,0,0,0) 40%,rgba(0,0,0,0) 60%, rgba(0,0,0,1)

80%,rgba(0,0,0,1) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
            filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#000000',GradientType=0

); /* IE6-9 */

        }


Run your code. Watch as the scrolling text fades in from the bottom and fades out at the top. Isn't this like magic?


Now, we're going to rotate the diagonal_wrapper div. Encase it inside another div, and set the id to perspective_wrapper. Because when you're doing a 3D transformation with perspective, this is required.
    <div id="perspective_wrapper">
            <div id="diagonal_wrapper">
                <div id="overlay"></div>
                <div id="text_wrapper">
                    <p>A long long time ago, in a galaxy far far away...</p>
                    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
                    <p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
                </div>
        </div>
    </div>


Style the perspective_wrapper div, like so. This ensures that the perspective_wrapper div fills the while screen. The perspective property has been given a low number, at 150px, to exaggerate the skewing of the diagonal_wrapper div.
        #perspective_wrapper
        {
            width:100%;
            height:100%;
            overflow:hidden;
            -webkit-perspective:150px;
            -webkit-perspective-origin:50% 50%;
            perspective:150px;
            perspective-origin:50% 50%;
        }


Next, we rotate the diagonal_wrapper div along its X-axis. Just 10 degrees should do it.
        #diagonal_wrapper
        {
            position:relative;
            z-index:50;
            width:70%;
            height:600px;
            margin: 0 auto 0 auto;
            border:1px solid #FFFFFF;
            overflow:hidden;
            -webkit-transform-origin:50% 50%;
            -webkit-transform:rotateX(10deg);
            transform-origin:50% 50%;
            transform:rotateX(10deg);
        }


We're getting warm. Very warm.


Now all we have left to do is remove the white border.
        #diagonal_wrapper
        {
            position:relative;
            z-index:50;
            width:70%;
            height:600px;
            margin: 0 auto 0 auto;
            border:0px solid #FFFFFF;
            overflow:hidden;
        }


And there you go. This is a live demo, and it works.

A long long time ago, in a galaxy far far away...
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.


Sure brings back memories, doesn't it? Well, until the sequel arrives, this should keep the Jedi (or Sith) in you alive.

Yes, this is the web tutorial you're looking for.
T___T

No comments:

Post a Comment