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&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&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")
...