<!DOCTYPE html>
<html>

  <head>
    <link data-require="animate.css@3.2.0" data-semver="3.2.0" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/animate.css/3.2.0/animate.min.css" />
    <script data-require="angular.js@1.3.0" data-semver="1.3.0" src="//code.angularjs.org/1.3.0/angular.js"></script>
    <script data-require="angular-animate@1.3.4" data-semver="1.3.4" src="https://code.angularjs.org/1.3.4/angular-animate.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="scroll-animate-directive.js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-app="demo">
      <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box green" ani-scroll="1">
      <div class="box circle" ng-class="{roundit: $parent.show}"></div>
    </div>
    <div class="box"></div>
    <div class="box green" ani-scroll="110"></div>
    <div class="box"></div>
    <div class="box green" ani-scroll="220"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box green" ani-view></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box green" ani-view></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box green" ani-view></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
  </body>

</html>
'use strict';

angular
  .module('demo', [
    'ngAnimate',
    'scroll-animate-directive'
    ]);
.box {
    height:100px;
    width: 100px;
    margin: 10px auto;
    background-color:#000;
}

.green{
    background-color:#7ED321;
}

.box.ng-hide{
  display: block!important;
  visibility: hidden;
}

.box.ng-hide-add {
    -webkit-animation: bounceOutLeft 0.4s;
    -moz-animation: bounceOutLeft 0.4s;
    animation: bounceOutLeft 0.4s;
    visibility: visible;
}

.box.ng-hide-remove {
    animation: bounceInLeft 0.4s;
    -moz-animation: bounceInLeft 0.4s;
    -webkit-animation: bounceInLeft 0.4s;
}

.roundit{
  transition:all 1s;
  border-radius:50%;
}

.box.ng-hide-add .circle{
    transition:all 0.25s;
    border-radius:0%;
    background-color: #fff;
}
'use strict';

angular.module('scroll-animate-directive', [])
    .controller('aniDistances', ['$scope',
        function($scope) {
            $scope.getScrollOffsets = function(w) {

                // Use the specified window or the current window if no argument 
                w = w || window;

                // This works for all browsers except IE versions 8 and before
                if (w.pageXOffset !== null) {
                    return {
                        x: w.pageXOffset,
                        y: w.pageYOffset
                    };
                }

                // For IE (or any browser) in Standards mode
                var d = w.document;
                if (document.compatMode === 'CSS1Compat') {
                    return {
                        x: d.documentElement.scrollLeft,
                        y: d.documentElement.scrollTop
                    };
                }

                // For browsers in Quirks mode
                return {
                    x: d.body.scrollLeft,
                    y: d.body.scrollTop
                };
            };
            $scope.getPosition = function(e) {
                return {
                    x: e[0].offsetLeft,
                    y: e[0].offsetTop
                };
            }
            $scope.getViewPortSize = function(w) {

                return {
                    x: Math.max(document.documentElement.clientWidth, w.innerWidth || 0),
                    y: Math.max(document.documentElement.clientHeight, w.innerHeight || 0)
                }


            }
        }
    ])
    .directive('aniScroll', function($window) {
        return {
            restrict: 'A',
            controller: 'aniDistances',
            transclude: true,
            replace: true,
            template: '<div ng-transclude ng-show=\'show\'></div>',
            scope: {
                show: '@',
            },
            link: function(scope, element, attrs) {

                angular.element($window).bind('scroll', function() {
                    var targetOffset = attrs.aniScroll;
                    var offset = scope.getScrollOffsets($window);
                    if (offset.y >= targetOffset) {
                        scope.show = true;
                    } else {
                        scope.show = false;
                    }
                    scope.$apply();
                });
            }
        };
    })
    .directive('aniView', function($window) {
        return {
            restrict: 'A',
            controller: 'aniDistances',
            transclude: true,
            replace: true,
            template: '<div ng-transclude ng-show=\'show\'></div>',
            scope: {
                show: '@',
            },
            link: function(scope, element, attrs) {

                angular.element($window).bind('scroll', function() {
                    var position = scope.getPosition(element);
                    var offset = scope.getScrollOffsets($window);
                    var viewport = scope.getViewPortSize($window);
                    var coverage = {
                        x: parseInt(viewport.x + offset.x),
                        y: parseInt(viewport.y + offset.y)
                    }
                    if (coverage.y >= position.y && coverage.x >= position.x) {
                        scope.show = true;
                    } else {
                        scope.show = false;
                    }
                    scope.$apply();
                });
            }
        };
    });