Pseudo Live Tile Effect

The actual Live Tile effect involves either replacing the current tile with another tile, or the simpler “showing the backside” of the tile effect. But the reason I am writing this article is because while this effect may be desirable for many reasons, sometimes it may be just as useful to just mimic this effect to bring some subtle dynamic elements to your page. Lets see how we can implement this feature with ease to our web application.

This is what we will be building

See the Pen Pseudo Live Tile by Ashwin P Chandran (@Werty7098) on CodePen.dark

Lets dig deeper into how we will build this now.

1. Create the HTML

Lets create a container for our images and insert 9 images into it

<div id="tile-container">
    <div class="tile">1</div>
    <div class="tile">2</div>
    <div class="tile">3</div>
    <div class="tile">4</div>
    <div class="tile">5</div>
    <div class="tile">6</div>
    <div class="tile">7</div>
    <div class="tile">8</div>
    <div class="tile">9</div>
</div>

2. Style the containers

Lets give these images some shape. Now the styles used here are just to show the effect to keep this example simple. The additional styles used to make it useful will also be shown.

#tile-container {
    margin-top: 50px !important;
    margin: auto;
    width: 308px;
}
.tile {
    width: 100px;
    height: 100px;
    background: #F44336;
    display: inline-block;
}

This will give the images a width and height of 100px. Now you may have noticed that the container element has a width of 308px, an odd value. This is due to the padding that the browser adds to the div elements, and since we want 3 cells per row, this measurement adds up correctly.

Alternatively we can also make the tiles flush with each other with a little additional styles as follows:

.tile {
    width: 100px;
    height: 100px;
    background: #F44336;
    display: inline-block;
    line-height: 100px;
    float: left;
    text-align: center;
    color: white;
    font-family: sans-serif;
    font-size: 30px;
}

The additional float property’s removes these spaces and the width can now be made 300px and add some style to the cells so that they don’t look plain and boring.

3. Begin the scripts

Now as we have already setup the images, lets give them the iconic live-tile effect. We first need to trigger the tile update at random intervals.

(function loop() {
    // We need a random time interval between 100 and 1000 milliseconds
    var min = 100, max = 1000; 
    var rand = Math.round(Math.random() * (max - min)) + min;  
    
    setTimeout(function() {
        updateTile();
        loop();
    }, rand);
}());

This is a self executing recursive function which calls itself after a random interval between 100 and 1000 milliseconds. Every time the timeout interval is reached, the function calls the update tile method asynchronously and then calls itself.

Before we move onto the tile update function, We will store the tiles as an array so that the updateTile() function can easily update it.

var tiles = document.getElementsByClassName('tile');

Now for the update tile function:

function updateTile() {
    // We need a random tile between 0 and 8 (array indexes start from 0)
    var min = 0, max = 8; 
    var rand = Math.round(Math.random() * (max - min)) + min;  

    tiles[rand].classList.add('start');
    setTimeout(function() {
        tiles[rand].classList.remove('start');
    }, 500);
}

We will now perform this tile animation using css, and we will use the start class to start the animation. Therefore the update function will only pick a random tile from the list of tiles and adds a start class to it. It will remove this class after 500ms as the animation would have completed by then and we can proceed to animate the tile again.

4. Animating Styles

Since we are using the .start class to trigger the animation, lets add those styles to our existing css.

.tile.start {
    animation: tile 0.5s ease-in-out;
}

@keyframes tile {
    0% {
        transform: rotateY(0deg);
    }

    49% {
        transform: rotateY(90deg);
    }
    50% {
        transform: rotateY(270deg);
    }
    100% {
        transform: rotateY(360deg);
    }
}

Lets look at this animation. We have added an animation style named tile which will run for 500ms.  The @keyframes defines how the animation will execute. This is where we make the pseudo live tile effect seem real. People do not observe too carefully that the tiles have not changed, but they will notice an odd rotation of 360°. They will also notice if the animated tile is rotated 180º. So we must flip the tile a full 360° while making it appear to have flipped only half that.

Thats where the keyframes are important. We keep half the flip duration to represent 0° to 90° of the Tile, and at this point when the tile is no longer visible to the viewer, we rotate it by an additional 180°. It is important that this must be immediate that the view does not see anything. The remaining duration the tile will rotate from 270° to 360°.

This creates the illusion that the tile has flipped, while in reality it has actually rotated 360°.

5. Finally to sum it all up

Now lets look at the whole code:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Live Tiles</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <style>
            #tile-container {
                margin-top: 50px !important;
                margin: auto;
                width: 300px;
            }
            .tile {
                width: 100px;
                height: 100px;
                background: #F44336;
                display: inline-block;
                line-height: 100px;
                float: left;
                text-align: center;
                color: white;
                font-family: sans-serif;
                font-size: 30px;
            }

            .tile.start {
                animation: tile 0.5s ease-in-out;
            }

            @keyframes tile {
                0% {
                    transform: rotateY(0deg);
                }

                49% {
                    transform: rotateY(90deg);
                }
                50% {
                    transform: rotateY(270deg);
                }
                100% {
                    transform: rotateY(360deg);
                }
            }
        </style>
    </head>
    <body>
        <div id="tile-container">
            <div class="tile">1</div>
            <div class="tile">2</div>
            <div class="tile">3</div>
            <div class="tile">4</div>
            <div class="tile">5</div>
            <div class="tile">6</div>
            <div class="tile">7</div>
            <div class="tile">8</div>
            <div class="tile">9</div>
        </div>
        <script>
            (function loop() {
                // We need a random time interval between 100 and 1000 milliseconds
                var min = 100, max = 1000; 
                var rand = Math.round(Math.random() * (max - min)) + min;  
                
                setTimeout(function() {
                    updateTile();
                    loop();
                }, rand);
            }());

            var tiles = document.getElementsByClassName('tile');

            function updateTile() {
                // We need a random tile between 0 and 8 (array indexes start from 0)
                var min = 0, max = 8; 
                var rand = Math.round(Math.random() * (max - min)) + min;  

                tiles[rand].classList.add('start');
                setTimeout(function() {
                    tiles[rand].classList.remove('start');
                }, 500);
            }
        </script>
    </body>
</html>

Conclusion

Now this may not be the desired effect for many, but for certain scenarios where we do need to add a lil dynamic element to an otherwise plain page, such simple pseudo elements play an important role.

Leave a Reply

Your email address will not be published. Required fields are marked *