JSFiddle - React, Tailwind, and code Playground

by BurpmanJunior

HTML

<div class="text-fx expand-fx">EXPAND</div>
<div class="text-fx rotate-fx">ROTATE</div>

SCSS

@import url(http://fonts.googleapis.com/css?family=Raleway:900);
html,
body{
    background-color: #533f68;
    color: #ddd;
    padding: 5vh 1vw;
}
.text-fx {
    font-family:'Raleway', sans-serif;
    font-weight: 900;
    font-size: 15vw;
    text-align: center;
    cursor: default;
    perspective: 100vw;
    span {
        position: relative;
        display: inline-block;
        cursor: default;
        z-index: 1;
        &.text-fx-focus {
            z-index: 3;
        }
        &.text-fx-subfocus {
            z-index: 2;
        }
    }
    
    &.expand-fx{
        span {
            transform: scale(1);
            transition: transform 300ms, color 300ms, text-shadow 300ms;
            text-shadow: 0 0 0 rgba(0, 0, 0, 0);
            color: #9c8faa;
            &.text-fx-focus {
                transform: scale(1.4);
                color: #fff;
                text-shadow: 0 0.5vw 1vw rgba(0, 0, 0, 0.4);
            }
            &.text-fx-subfocus {
                transform: scale(1.15);
                color: #cdc3d8;
                text-shadow: 0 0.5vw 0.5vw rgba(0, 0, 0, 0.2);
            }
        }
    }
    
    &.rotate-fx{
        span {
            transform: rotateX(40deg);
            transform-origin: bottom center;
            transition: transform 300ms, color 300ms, text-shadow 300ms;
            text-shadow: 0 0 0 rgba(0, 0, 0, 0);
            color: #9c8faa;
            &.text-fx-focus {
                transform: rotateX(0deg);
                color: #fff;
                text-shadow: 0 0.5vw 1vw rgba(0, 0, 0, 0.4);
            }
            &.text-fx-subfocus {
                transform: rotateX(25deg);
                color: #cdc3d8;
                text-shadow: 0 0.5vw 0.5vw rgba(0, 0, 0, 0.2);
            }
        }
    }
}

JavaScript

/**
 * TEXT EFFECTS
 * (needs splitting up a little)
 */

var textFx = {
    init: function () {
        // Find all elements with .text-fx
        var elems = document.getElementsByClassName('text-fx');
        for (var i = 0; i < elems.length; i++) {
            // Wrap inner HTML characters with <span>
            var elemText = elems[i].innerHTML;
            elems[i].innerHTML = '';
            for (var n = 0; n < elemText.length; n++) {
                elems[i].innerHTML = elems[i].innerHTML + '<span>' + elemText[n].replace(' ', '&nbsp;') + '</span>';
            }
            // Loop through spans and apply mouse events
            var nodes = elems[i].childNodes;
            for (var n = 0; n < nodes.length; n++) {
                // Mouseover - add focus classes
                nodes[n].addEventListener('mouseover', function () {
                    // Main focus class
                    this.className = 'text-fx-focus';
                    // Left subfocus
                    if (this.previousSibling !== null) {
                        this.previousSibling.className = 'text-fx-subfocus';
                    }
                    // Right subfocus
                    if (this.nextSibling !== null) {
                        this.nextSibling.className = 'text-fx-subfocus';
                    }
                });
                // Mouseout - remove focus classes
                nodes[n].addEventListener('mouseout', function () {
                    // Loop all spans from parent element
                    var spans = this.parentElement.childNodes;
                    for (var c = 0; c < spans.length; c++) {
                        spans[c].removeAttribute('class');
                    }
                });
            }
        }
    }
}

textFx.init();