JSFiddle - React, Tailwind, and code Playground

by Hassen Charef

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
The animation will run when you firt open the page,<br> 

and when you hover it,<br> 

and when you scroll out then in. <br>

<div class="my-image-container">
  <img class="my-image" 
  src="http://www.lifeofpix.com/wp-content/uploads/2017/05/img-5831.jpg">
</div>
<br> Scroll down then back up
<br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br>
scroll up

CSS

.my-image-container {
  top: 50px;
  max-width: 22%;
}

.my-image-container:hover {
  animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
  perspective: 1000px;
}

.my-image-container .my-image {
  animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
  -moz-animation-delay: 1s;
  -webkit-animation-delay: 1s;
  -o-animation-delay: 1s;
  animation-delay: 1s;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
  perspective: 1000px;
  width: 100%;
}

.animate {
  animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
  -moz-animation-delay: 0.5s;
  -webkit-animation-delay: 0.5s;
  -o-animation-delay: 0.5s;
  animation-delay: 0.5s;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
  perspective: 1000px;
}

@keyframes shake {
  10%,
  90% {
    transform: translate3d(-1px, 0, 0);
  }
  20%,
  80% {
    transform: translate3d(2px, 0, 0);
  }
  30%,
  50%,
  70% {
    transform: translate3d(-4px, 0, 0);
  }
  40%,
  60% {
    transform: translate3d(4px, 0, 0);
  }
}

JavaScript

var $window = $(window);
var $elem = $(".my-image-container");
var $gotOutOfFrame = false;

function isScrolledIntoView($elem, $window) {
  var docViewTop = $window.scrollTop();
  var docViewBottom = docViewTop + $window.height();

  var elemTop = $elem.offset().top;
  var elemBottom = elemTop + $elem.height();

  return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop) && $gotOutOfFrame);
}

function isScrolledOutView($elem, $window) {
  var docViewTop = $window.scrollTop();
  var docViewBottom = docViewTop + $window.height();

  var elemTop = $elem.offset().top;
  var elemBottom = elemTop + $elem.height();

  return ((elemBottom < docViewBottom) && (elemTop < docViewTop));
}
$(document).on("scroll", function() {
  if (isScrolledIntoView($elem, $window)) {
    $gotOutOfFrame = false;
    $elem.addClass("animate");
    $(function() {
      setTimeout(function() {
        $elem.removeClass("animate");

      }, 1500);
    });
  }
  if (isScrolledOutView($elem, $window)) {
     $gotOutOfFrame = true;
    $elem.removeClass("animate");
  }
});