2

How can I set a ng-class (inside ng-repeat) depending on image aspect ratio?

something like...

<div ng-repeat="img in images" style="width: 100px; height: 100px;">
   <img ng-src="{{img}}" ng-class="{'wide': img.width/img.height > 1, 'tall': img.width/img.height <= 1}" />
</div>

EDIT: CSS object-fit doesn't work for me because of IE... :(

cb4
  • 6,689
  • 7
  • 45
  • 57
  • That looks like it should work. Is it not working for you? – Lex Mar 25 '16 at 00:48
  • Nop... "img.width" is not a property of img array.... I'd like to get the image width and height but I don't know how – Mauricio Betancur Molina Mar 25 '16 at 00:55
  • Oh, ha...gotcha. Does [this answer](http://stackoverflow.com/a/14508318/548997) help? Sounds like you will need to write a directive (which is pretty standard any time you start wanting to mess with the DOM). – Lex Mar 25 '16 at 01:00
  • Hey Lex, thanks for your fast answer... Maybe yes, but I get lost here... `//check width and height and apply styling to parent here`. I'm new on this, I appreciate your help! – Mauricio Betancur Molina Mar 25 '16 at 01:07
  • I also found [this](http://stackoverflow.com/a/1892815/5904036) but ... doesn't work with my images... maybe because of ng-repeat? – Mauricio Betancur Molina Mar 25 '16 at 01:18

2 Answers2

1

The main problem here is waiting for the image to load before setting the width / height properties on the img json object. So something like this will work.

Important: Scope.apply - Because you are altering the scope in a non-angular context, i.e. in jQuery you need to call scope.apply so the digest-watch cycle occurs and the variables get set up correctly.

Plunker

HTML:

<img ng-src="{{img}}" image-set-aspect ng-class="{'wide':    img.width/img.height > 1, 'tall': img.width/img.height <= 1}" />

Directive:

app.directive('imageSetAspect', function() {
    return {
        scope: false,
        restrict: 'A',
        link: function(scope, element, attrs) {
        element.bind('load', function() {
            // Use jquery on 'element' to grab image and get dimensions.
            scope.$apply(function() {
              scope.imageMeta.width = $(element).width(); 
              scope.imageMeta.height = $(element).height(); 
              console.log(scope.$parent.imageMeta);
            });
        });
        }
    };
});
Gene
  • 616
  • 4
  • 8
  • THANK YOU Dr Jones. Really I don't need the properties, it was just a "sketch". The important thing here is apply 'wide' or 'tall' classes correctly. [This](https://plnkr.co/edit/nXzDbM5GldH8jezLXZA5?p=preview) is the plunker. You'll see an example of expected result. Thanks again for your help and your time! – Mauricio Betancur Molina Mar 25 '16 at 04:15
  • Updated solution above. – Gene Mar 25 '16 at 06:49
  • Dr Jones, thank you, the plunker is already! But in my application is not working... something wrong with this two lines `scope.$parent.imagen.width = $(element).width();` and `scope.$parent.imagen.height = $(element).height();` In debug mode, I'm not seeing pass the values `$(element).width();` to `scope.$parent.imageMeta.width`... after this line, `scope.$parent.imageMeta.width`is undefined. – Mauricio Betancur Molina Mar 25 '16 at 12:41
  • ...And what would be a solution in the angular context? – Mauricio Betancur Molina Mar 25 '16 at 12:50
  • I updated the code to remove $parent. Not really needed. Since this works in Plunker I think the question is answered. I think it's up to you to take it from here. – Gene Mar 25 '16 at 15:10
0

After many times serching for it, I found a simple and sexy answer... It is a CSS img element property called object-fit. It could have these values: fill, contain, cover, scale, none.

img {
  object-fit: cover;
}