I did it by choosing even rows for lg view and even columns for smaller screens. I choose 12 for the "even" value and then I played with md-cols for the different sizes. This gives me 1 column on phones, two equal width columns on tablets and multiple equal height rows on larger screens.
I calculate the ratio of the tile by finding the closest aspectratio from a predifinded set. Some cropping always appear but it is quite minimal. One could also just skip the whole ratios thing and just calculate the missing value by image.width/image.height*12.
css
md-grid-tile {
transition: all 500ms ease-out 100ms;
overflow: hidden;
img{
width: 100%;
height: auto;
}
}
template:
<md-grid-list
md-cols="12" md-cols-gt-sm="24" md-cols-gt-lg="72"
md-row-height="1:1"
md-gutter="2px" md-gutter-gt-sm="4px" >
<md-grid-tile ng-repeat="image in images"
md-rowspan="{{getRowspan(article)}}"
md-rowspan-gt-lg="{{getRowspan(image,'lg')}}"
md-colspan="{{getColspan(article)}}"
md-colspan-gt-lg="{{getColspan(image,'lg')}}"
class="md-whiteframe-z2" >
<img ng-src="{{image.src}}" />
<md-grid-tile-footer>
<h3 article-title="image.title"></h3>
</md-grid-tile-footer>
</md-grid-tile>
</md-grid-list>
controller:
$scope.ratios = [
3/12,
6/12,
9/12,
12/12,
15/12,
18/12,
21/12
]
$scope.getRowspan = function(image,size){
switch (size) {
case 'lg':
return 12;
default:
var ratio = image.meta.height / image.meta.width;
var i;
for (i = $scope.ratios.length; i > 0; i--) {
var cur = $scope.ratios[i - 1];
if (!angular.isDefined($scope.ratios[i - 2]) || ratio > cur) {
ratio = cur;
break;
}
}
return ratio * 12;
}
};
$scope.getColspan = function(image,size){
switch (size) {
case 'lg':
var ratio = image.meta.width / image.meta.height;
var i;
for (i = 0; i < $scope.ratios.length; i++) {
var cur = $scope.ratios[i];
if (!angular.isDefined($scope.ratios[i + 1]) || ratio < cur) {
ratio = cur;
break;
}
}
return ratio * 12;
default:
return 12;
}
};