<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link data-require="bootstrap-css@3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<script data-require="angular.js@1.3.0" data-semver="1.3.0" src="https://code.angularjs.org/1.3.0/angular.js"></script>
<script data-require="angular.js@1.3.0" data-semver="1.3.0" src="https://code.angularjs.org/1.3.0/angular-animate.js"></script>
<script data-require="moment.js@2.8.3" data-semver="2.8.3" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment.min.js"></script>
<script data-require="jquery@*" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script data-require="bootstrap@3.1.1" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="animations.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainCtrl as main">
<select class="form-control" ng-model="main.dateAfter" ng-options="range.name for range in main.dateRanges"></select>
<hr />
<div class="thumb-wrapper">
<div class="thumb my-repeat-animation" ng-repeat="item in main.items | isAfter:main.dateAfter.date track by item.id">
<img ng-src="{{item.img}}">
<p>{{item.date}}</p>
</div>
</div>
</body>
</html>
// Inspired by the incredible article by Todd Motto on custom filters
// http://toddmotto.com/everything-about-custom-filters-in-angular-js/
angular.module('myApp', [
'ngAnimate'
])
.controller('MainCtrl', function(ItemsModel,DateRanges){
var main = this;
main.dateRanges = DateRanges;
main.dateAfter = main.dateRanges[0];
main.items = ItemsModel.getItems();
})
.filter('isAfter', function() {
return function(items, dateAfter) {
// Using ES6 filter method
return items.filter(function(item){
return moment(item.date).isAfter(dateAfter);
})
}
})
.value('DateRanges', [
{name:'All items', date:moment().subtract(10, 'year')},
{name:'Newer than 3 months', date:moment().subtract(3, 'month')},
{name:'Newer than 6 months', date:moment().subtract(6, 'month')},
{name:'Newer than 12 months', date:moment().subtract(1, 'year')}
])
.factory('ItemsModel', function(){
var items = [
{id: 1, date:'08/01/2013', img:'http://onehungrymind.com/images/image00.jpg'},
{id: 2, date:'09/01/2013', img:'http://onehungrymind.com/images/image01.jpg'},
{id: 3, date:'10/01/2013', img:'http://onehungrymind.com/images/image02.jpg'},
{id: 4, date:'11/01/2013', img:'http://onehungrymind.com/images/image03.jpg'},
{id: 5, date:'12/01/2013', img:'http://onehungrymind.com/images/image04.jpg'},
{id: 6, date:'01/01/2014', img:'http://onehungrymind.com/images/image00.jpg'},
{id: 7, date:'02/01/2014', img:'http://onehungrymind.com/images/image01.jpg'},
{id: 8, date:'03/01/2014', img:'http://onehungrymind.com/images/image02.jpg'},
{id: 9, date:'04/01/2014', img:'http://onehungrymind.com/images/image03.jpg'},
{id: 10, date:'05/01/2014', img:'http://onehungrymind.com/images/image04.jpg'},
{id: 11, date:'06/01/2014', img:'http://onehungrymind.com/images/image00.jpg'},
{id: 12, date:'07/01/2014', img:'http://onehungrymind.com/images/image01.jpg'},
{id: 13, date:'08/01/2014', img:'http://onehungrymind.com/images/image02.jpg'},
{id: 14, date:'09/01/2014', img:'http://onehungrymind.com/images/image03.jpg'},
{id: 15, date:'10/01/2014', img:'http://onehungrymind.com/images/image04.jpg'}
];
var getItems = function() {
return items;
}
return {
getItems: getItems,
}
})
;
@import url(http://fonts.googleapis.com/css?family=Permanent+Marker);
body {
padding: 10px;
}
.thumb-wrapper {
postion: relative;
}
.thumb {
background: white;
display: inline;
float: left;
margin: 0 15px 30px;
padding: 10px 10px 15px;
text-align: center;
text-decoration: none;
-webkit-box-shadow: 0 4px 6px rgba(0, 0, 0, .3);
-moz-box-shadow: 0 4px 6px rgba(0,0,0,.3);
box-shadow: 0 4px 6px rgba(0,0,0,.3);
transition: all .15s linear;
z-index:0;
}
.thumb img {
width: 100px;
height: 100px;
}
.thumb p {
font-family: 'Permanent Marker', cursive;
margin-top: 5px;
margin-bottom: 0px;
}
.my-repeat-animation.ng-enter,
.my-repeat-animation.ng-leave {
-webkit-transition: 0.5s linear all;
transition: 0.5s linear all;
position:relative;
}
.my-repeat-animation.ng-enter-stagger {
/* 100ms will be applied between each sucessive enter operation */
-webkit-transition-delay:0.1s;
transition-delay:0.1s;
/* this is here to avoid accidental CSS inheritance */
-webkit-transition-duration:0;
transition-duration:0;
}
.my-repeat-animation.ng-enter {
opacity:0;
}
.my-repeat-animation.ng-enter.ng-enter-active {
opacity:1;
}
.my-repeat-animation.ng-leave {
opacity:1;
}
.my-repeat-animation.ng-leave.ng-leave-active {
opacity:0;
}