JSFiddle - React, Tailwind, and code Playground

by meo

HTML

<div class="text">
    <p><span>Lorem </span><span>ipsum </span><span>dolor </span><span>sit </span><span>amet, </span><span>consectetur </span><span>adipiscing </span><span>elit. </span><span>Morbi </span><span>cursus </span><span>consequat </span><span>eros </span><span>at </span><span>pretium. </span><span>Mauris </span><span>sollicitudin </span><span>molestie </span><span>pharetra. </span><span>Cum </span><span>sociis </span><span>natoque </span><span>penatibus </span><span>et </span><span>magnis </span><span>dis </span><span>parturient </span><span>montes, </span><span>nascetur </span><span>ridiculus </span><span>mus. </span><span>Suspendisse </span><span>pulvinar </span><span>venenatis </span><span>quam </span><span>vitae </span><span>vehicula. </span><span>Praesent </span><span>lacinia </span><span>mattis </span><span>mi </span><span>eget </span><span>venenatis. </span><span>Vivamus </span><span>dapibus, </span><span>ante </span><span>id </span><span>vestibulum </span><span>blandit, </span><span>purus </span><span>augue </span><span>condimentum </span><span>tortor, </span><span>nec </span><span>pellentesque </span><span>risus </span><span>sapien </span><span>non </span><span>dui. </span><span>Aliquam </span><span>egestas </span><span>quam </span><span>et </span><span>sapien </span><span>aliquet </span><span>viverra.</span></p><p><span>Vestibulum </span><span>ante </span><span>ipsum </span><span>primis </span><span>in </span><span>faucibus </span><span>orci </span><span>luctus </span><span>et </span><span>ultrices </span><span>posuere </span><span>cubilia </span><span>Curae; </span><span>Mauris </span><span>pretium </span><span>luctus </span><span>congue. </span><span>Donec </span><span>eu </span><span>arcu </span><span>nisl. </span><span>Pellentesque </span><span>sed </span><span>risus </span><span>tempor </span><span>sem </span><span>gravida </span><span>interdum. </span><span>Phasellus </span><span>ultrices </span><span>commodo </span><span>urna,...

SCSS

@import url(http://fonts.googleapis.com/css?family=Droid+Serif:400,700);


.text {
    font-family: 'Droid Serif', serif;
   
    font-size: 1em;
    line-height: 1.8;
    
    max-width: 80%;
    margin: 40px auto;
    
    
    
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    
   
    &, p {
         perspective: 600px;
        -webkit-perspective: 600px;
        -moz-perspective: 600px;
        
        transform-style: preserve-3d;
        -webkit-transform-style: preserve-3d;
        -moz-transform-style: preserve-3d;
    }
    span {
        display: inline-block;
        margin-right: 4px;
        
        transform-origin: center center;
        -webkit-transform-origin: center center;
        -moz-transform-origin: center center;
        
        transition: color 200ms ease-in;
        -webkit-transition: color 200ms ease-in;
        -moz-transition: color 200ms ease-in;
        
        color: rgba(0,0,0,.1);
        
        &.done {
            color: rgba(0,0,0,.5);
        }
        
        &.active {
            color: rgba(0,0,0,1);
        }
    }
}

JavaScript

window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

var Readler = function(){
    this.$textBlock = null;
    this.$resultTextBlock = null;
    
    this.$activePart = null;
    this.$activeResultPart = null;
    
    this.activePartIndex = null;
    this.totalParts = null;
    
    this.$parts = null;
    this.$resultsParts = null;
};

Readler.prototype.setTextBlock = function( $textBlock ){
    this.$textBlock = $textBlock;
    return $textBlock;
};

Readler.prototype.setParts = function( $parts ){
    this.$parts = $parts
    this.totalParts = $parts.length;
    
    return $parts;
};

Readler.prototype.setActive = function( index ){
    if(this.$activePart) {
        this.$activePart.removeClass("active").addClass("done");
    }
    if( this.$parts.eq( index ).length ){
        this.$activePart = this.$parts.eq( index );
        this.$activePart.addClass("active");
        this.activePartIndex = index;
        
        return index;
    }else{
        return this.activePartIndex || "no part is active";
    }
};

Readler.prototype.getActiveIndex = function(){
    return this.activePartIndex;
};

Readler.prototype.returnActive = function(){
    return this.$activePart;
};

$(function(){
    var $doc, $textBlock, animate, redner, i, R = new Readler();
    
    $textBlock = $("div.text:eq(0)");
    $doc = $(document);
    
    R.setTextBlock( $textBlock );
    R.setParts( $("span", $textBlock) );
    R.setActive(0);
    
    i = 0;
    
    render = function(){
        i++;
        console.log( R.$activePart.css("transform", "scale(" + 150 / i + ")") );
    };

    animate = function(){
        requestAnimFrame( animate );
        render()
    };
    
    animate();
    
    $doc.on("keypress.readler click.readler...