Angular Gallery - with Animation

by ksoncan34

HTML

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular-animate.min.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<div id="imageGalleryPage" ng-app="galleryApp" ng-controller="GalleryCtrl">    
    <div id="imageGallery">
        <div class="photoHolder" ng-repeat="photo in photos | filter:{caption:query} | orderBy:orderProp" style="width: 75px; height: 75px;" ng-class="{photoSelected : photo.selected}">
            <div class="photoClass" data-id="{{photo.id}}" ng-attr-style="background-image:url({{photo.thumb_url}})"></div>
            <div class="caption">{{photo.caption}}</div>
            <div class="caption">{{photo.date}}</div>
        </div>
    </div>
</div>

CSS

.photoHolder {
    display: inline-block;
    border: 4px solid #fff;
    text-align: center;
    box-sizing: border-box;    
}

.photoHolder .photoClass {
    transition: transform .2s ease, opacity .3s ease;
    -webkit-transition: -webkit-transform .2s ease, opacity .3s ease;
}

.photoHolder.ng-enter-stagger .photoClass {
  /* 200ms will be applied between each sucessive enter operation */
  -webkit-transition-delay:0.2s;
  transition-delay:0.s;

  /* this is here to avoid accidental CSS inheritance */
  -webkit-transition-duration:0;
  transition-duration:0;
}

.photoHolder.ng-enter .photoClass {
    transform: scale(.8,1);
    -webkit-transform: scale(.8,1);
    opacity: 0;
}

.photoHolder.ng-enter-active .photoClass {
    transform: scale(1,1);
    -webkit-transform: scale(1,1);
    opacity: 1;
}

.photoClass {
    display: inline-block;
    background: #eee;
    box-sizing: border-box;    
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
    width: 100%;
    height: 100%;
    border: 4px solid #dfe2e2;
}

.caption {
    overflow: hidden;
    font-size: 9px;
    white-space: nowrap;
    text-overflow: ellipsis;
}

JavaScript

function rand(min, max) {
  return Math.round(Math.random() * (max - min) + min);
}

var myApp = angular.module('galleryApp', ['ngAnimate']);

myApp.controller('GalleryCtrl', function ($scope, $http) {
    var caption = '';
    var photos = [];
    var loaded = 0;
    
    var image = new Image();
    image.onload = function() { 
        
         var canvas = document.createElement("canvas");
        canvas.width = image.width;
        canvas.height = image.height;

        // Copy the image contents to the canvas
        var ctx = canvas.getContext("2d");
        ctx.drawImage(image, 0, 0);

        var dataUrl = canvas.toDataURL("image/png");
        
        for (var i = 0; i < 50; i++) {
            
            var tmp = new Date(1310000000000 + (rand(0,2317410007)));
            var dateString = tmp.toDateString();
            switch (rand(0,2)) {
                case 0 : caption = 'IMG' + rand(1000,9999);
                    break;
                case 1 : caption = 'Image ' + rand(30,999);
                    break;
                case 2 : caption = 'DSC' + rand(1000,9999);
                    break;
            }
            
            photos.push({id: i, date: dateString, caption: caption, selected: i > 40, thumb_url : dataUrl});            
        }
        $scope.$apply();    
    }
    var width = rand(150,250);
    var height = rand(150,250);
    image.crossOrigin = "Anonymous";
    image.src =  'http://placekitten.com/200/231';
    
    $scope.photos = photos;        
    $scope.orderProp = 'caption'
    
});