Typing

by hlmurray91

HTML

<div class="ctn">
  <div class="scroll">
    <div class="top">
      <p class="JS-track js-typing" data-type="hello top"></p>
    </div>

    <div class="bottom">
      <p class="JS-track js-typing" data-type="hello bottom"></p>
    </div>
  </div>
</div>

SCSS

.ctn {
  width: 500px;
  height: 500px;
  overflow: scroll;
  border: 1px solid black;
  margin: 20px;
}

.scroll {
  position: relative;
  height: 1000px;
  padding: 40px;
}

.bottom {
  position: absolute;
  top: 50%;
}

JavaScript

//Determine if in viewport
$.fn.isOnScreen = function(){
    
    var win = $(window);
    
    var viewport = {
        top : win.scrollTop(),
        left : win.scrollLeft()
    };
    viewport.right = viewport.left + win.width();
    viewport.bottom = viewport.top + win.height();
    
    var bounds = this.offset();
    bounds.right = bounds.left + this.outerWidth();
    bounds.bottom = bounds.top + this.outerHeight();
    
    return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
    
};

// Add class if in viewport
function isVisible() {
	$('.JS-track').each(function() {
  	if($(this).isOnScreen()) {
    	$(this).addClass('visible');
    }
  });
}

isVisible();
$('.js-typing').each(function() {
  var elObj = {
    el: $(this),
    isPlaying: false
  }
  playTypingAnimation.call(elObj);
  
  $('.ctn').scroll(function() {
    playTypingAnimation.call(elObj);
  });
});

// Play animation on scroll
$('.ctn').scroll(function() {
	isVisible();
});

function playTypingAnimation () {
	if(!this.el.hasClass('visible')) {
    return false;
  }

  if(this.isPlaying) {
    return false
  }
  this.isPlaying = true;

  var typingElement = this
  typing(this.el, this.el.attr('data-type'), function() {
    typingElement.isRunning = false;
  });
}

// Typing animation
function typing(container, string, callback) {
    var count = 0;
    var length = string.length;
    var newString = "";
    var timer;

    timer = setInterval(function(){
        if(count < length){
            addLetter();
        } else{
            clearInterval(timer);
            callback();
        }
    }, 100);

    // addLetters
    function addLetter(){
      var newLetter = "<span>"+string.charAt(count)+"</span>";
        newString = newString + newLetter;
        container.html(newString);
        count++;
        return undefined;
    }
}

/* 

    if(elObj.el.isOnScreen()) {
    	elObj.el.addClass('visible');
   ...