JSFiddle - React, Tailwind, and code Playground

by gunderson

HTML

<p data-triggerPositionY="0.5">Brunch tofu disrupt, American Apparel chambray swag narwhal sartorial lomo. Ugh roof party +1, wolf slow-carb swag hashtag post-ironic leggings banh mi Wes Anderson bicycle rights Shoreditch. Neutra Pinterest gastropub heirloom food truck YOLO. Authentic Schlitz Brooklyn keffiyeh. Thundercats flexitarian chia put a bird on it, before they sold out keffiyeh pug single-origin coffee authentic small batch yr 90's street art. Pug vinyl banh mi, Helvetica Wes Anderson hella pickled squid iPhone mlkshk Blue Bottle. Letterpress cred locavore squid, PBR&amp;B Thundercats polaroid meggings vegan mlkshk iPhone mustache.</p>
<p>Flannel cornhole roof party keytar fingerstache. Ethical actually yr, Tumblr VHS freegan Neutra cred kogi plaid irony twee hashtag YOLO readymade. Slow-carb salvia Odd Future umami, leggings wolf cardigan High Life Tumblr pug four loko drinking vinegar jean shorts forage. Church-key twee irony gastropub banjo, drinking vinegar butcher. Skateboard ethical chia deep v, vegan keytar synth pickled asymmetrical Shoreditch PBR&amp;B banh mi McSweeney's Kickstarter Blue Bottle. Hella umami lomo, master cleanse Helvetica literally banh mi. Street art McSweeney's beard quinoa readymade.</p>
<p>Pickled Cosby sweater cray fashion axe, Neutra mustache umami blog narwhal tousled vegan Bushwick disrupt. Hoodie photo booth gentrify crucifix, Helvetica ethical slow-carb viral normcore banjo keffiyeh. Letterpress VHS Intelligentsia, ennui fanny pack photo booth art party flannel messenger bag gastropub skateboard +1 normcore Brooklyn. Next level seitan meh, raw denim food truck wolf ugh. Photo booth retro pug 90's. Selvage Wes Anderson mustache fashion axe keffiyeh. Pitchfork Marfa vegan dreamcatcher, pop-up hashtag Odd Future swag scenester fashion axe Bushwick keffiyeh selvage slow-carb pork belly.</p>
<p>Craft beer pickled meggings mlkshk. Fashion axe craft beer mumblecore hella disrupt wolf, YOLO Kickstarter Thundercats typewriter...

CSS

body{
    background: #f00;
    color: #fff;
    cursor: default;
}



.line{
    transform: translate3d(0,0,0);
    transition: transform 1s, opacity 1s;
    opacity: 0;
    margin-bottom: 15px;
    display: block;
}

.line.show{
    transform: translate3d(0, 0, 0);
    opacity: 1;
}
.line.hide{
    transform: translate3d(0, 100px, 0);
    opacity: 0;
}

.word{
    padding-right: 5px;
}

JavaScript

$(document).ready(onReady);

function onReady(){
    $("p").each(makeSpans);
    $(window)
        .on("scroll", onScroll)
        .on("resize", onResize);
    onScroll();
}

function onResize(){
    $("p").each(makeSpans);
    onScroll();
}

function makeSpans(){
    var $p = $(this);
    $p.find("span").contents().unwrap();
    var text = $p.text();
    var words = text.split(" ");
    var html = "<span class='word'>" + words.join("</span> <span class='word'>") + "</span>";
    $p.html(html);
    var _$lines = [];
    var lines = [];
    var lineNo = -1;
    $p.find("span").each(function(i, o){
        var $word = $(this);
        if (i > 0 && _$lines[lineNo] && $word.position().top === _$lines[lineNo][0].position().top){
            // it's the same line
            _$lines[lineNo].push($word);
            lines[lineNo].push(this);
        } else {
            _$lines[++lineNo] = [];
            lines[lineNo] = [];
            _$lines[lineNo].push($word);
            lines[lineNo].push(this);
        }
    });
    lines.forEach(function(line){
        $(line).wrapAll("<span class='line'>"); 
    });
    resetLines($p);
}

function resetLines($p){
    $p.find(".line")
        .addClass("hide")
        .removeClass("show")
        .data("triggerPositionY", 0.5);
}

function onScroll(){
    console.log("scroll");
    var pageTop = $(window).scrollTop();
    $("p").each(function(){
        var $p = $(this);
        var offset = $p.offset();
        var height = $p.height();
        var bottomOffset = offset.top + height;
        var triggerPositionY = parseFloat($p.data("triggerPositionY")) || 0.5;
        if (offset.top - pageTop <  window.innerHeight * triggerPositionY && bottomOffset > pageTop ){
            //evaluateLines($p);
            $p.find(".line").each(function(i){
                var $line = $(this);
                setTimeout(function(){
                    $line
                        .addClass("show")
                       ...