0

I'm trying to create a zoom effect, by adding a class and a width or height style to a span.

<span ng-class="fat_or_tall(this)"><figure><img ng-style="set_ratio(this)" draggable="true" class="thumb" id="{{tablet.created}}" title="{{ tablet.title }}" data-ng-src="{{ tablet.src }}" /></figure></span>

It works on the first page i'm on after the refresh, but when I click on the other tabs it just hops between sizes as if the css transition doesn't exist. If I inspect I see that sometime the styles have rendered, but sometimes they have not. After I click around the tabs and visit each one, then the zoom works properly. Why doesn't it work on the first try, and how can I fix that?

when it doesn't work. notice there's no style after i click the tab a second time it works well.  Notice there is a style now. First image above notice there is no style, and the transition does not work, but after I click the tab a second time (second pic) the style does show and the transition works well.

HERE: http://jsfiddle.net/U3pVM/23506/ (If you click refresh it won't wont, but if you click run it will. The style won't render. WHY?)

function TodoCtrl($scope) {
  $scope.tablet = {} 

    $scope.tablet.title = 'help'
    $scope.tablet.created = Date.now()
    $scope.tablet.src = 'http://tallclub.co.uk/wp-content/uploads/2011/04/Tall-Person-1.png'
    
  $scope.set_ratio = function (it) { //Find ratio and return style so that it can be used for zoom effect. 
    
        console.log(it)
        var img = new Image();  
        img.src = it.tablet.src;
        console.log(it.tablet)

        if(img.height>img.width){
            var h = 300*(img.height/img.width)+'px'     
            return {
                "height": h
            }   
        }else{
            var w = 300*(img.width/img.height)+'px'     
            return {
                "width":w 
            }       
        }
    }  
}

function TodoCtrlTwo($scope) {
  $scope.tablet = {} 

    $scope.tablet.title = 'help'
    $scope.tablet.created = Date.now()
    $scope.tablet.src = 'http://tallclub.co.uk/wp-content/uploads/2011/04/Tall-Person-1.png'
    
  $scope.set_ratio = function (it) { //Find ratio and return style so that it can be used for zoom effect. 
    
        console.log(it)
        var img = new Image();  
        img.src = it.tablet.src;
        console.log(it.tablet)

        if(img.height>img.width){
            var h = 300*(img.height/img.width)+'px'     
            return {
                "height": h
            }   
        }else{
            var w = 300*(img.width/img.height)+'px'     
            return {
                "width":w 
            }       
        }
    }  
}
.taller img  {
    -webkit-transition: .3s ease-in-out;
    transition: .3s ease-in-out;

}
.taller img:hover  {
    -webkit-transition: .3s ease-in-out;
    transition: .3s ease-in-out;

    height: 300px !important;
}  

figure  {
 width: 300px;
 height: 300px;
 
 //height: 200px;
 margin: 1em;
 padding: 0;
 background: #fff;
 overflow: hidden;
 border: 1px solid #222;
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>

<div ng-app>
  <h2>ARGH</h2>
  <div ng-controller="TodoCtrl">
<span class="taller"><figure><img ng-style="set_ratio(this)" draggable="true" class="thumb" id="{{tablet.created}}" title="{{ tablet.title }}" data-ng-src={{tablet.src}} /></figure></span>

  </div>
   <div ng-controller="TodoCtrlTwo">
<span class="taller"><figure><img ng-style="set_ratio(this)" draggable="true" class="thumb" id="{{tablet.created}}" title="{{ tablet.title }}" data-ng-src={{tablet.src}} /></figure></span>

  </div> 
</div>
Refresh page and click run code snippet, and mouse over. The images will jump. Then click run code snippet again and mouse over. There will be a smooth transition. Why is that?
Nrzonline
  • 1,600
  • 2
  • 18
  • 37
Squirrl
  • 4,909
  • 9
  • 47
  • 85

3 Answers3

1

Solution 1:

Working Demo

On first load of image, both width and height of the image are 0. So code of else block get executed which returns NaNpx.

In detail:

var w = 300*(img.width/img.height)+'px' 
var w = 300*(0/0)+'px'  // As img.width = 0, img.height = 0 
var w = 300*(NaN)+'px'
var w = NaNpx

To resolve this, set initial height of the image:

.taller img  {
    -webkit-transition: .3s ease-in-out;
    transition: .3s ease-in-out;
    height: 500px;
}

Solution 2:

You can add following if block in both controller.

if(img.height===0 && img.width ===0){
            var h = '500px';     
            return {
                "height": h
            }
    }

Working Demo

Hope that solve your problem.

Khalid Hussain
  • 1,675
  • 17
  • 25
0

try this. create $scope.tablet ={}; object first.and change ng-class to class for span tag.

var app = angular.module("app",[])
app.controller('ctrl',['$scope', function($scope){
   $scope.tablet ={};
  $scope.tablet.title = 'help';
    $scope.tablet.created = Date.now();;
    $scope.tablet.src = 'http://tallclub.co.uk/wp-content/uploads/2011/04/Tall-Person-1.png'
    
  $scope.set_ratio = function (it) { //Find ratio and return style so that it can be used for zoom effect. 
    
        console.log(it);
        var img = new Image();  
        img.src = it.tablet.src;
        console.log(it.tablet)

        if(img.height>img.width){
            var h = 300*(img.height/img.width)+'px'     
            return {'height':h};
        }else{
            var w = 300*(img.width/img.height)+'px'     
            return {
                'width':w 
            }       
        }
    }

}]);
.taller img  {
    -webkit-transition: .3s ease-in-out;
    transition: .3s ease-in-out;

}
.taller img:hover  {
    -webkit-transition: .3s ease-in-out;
    transition: .3s ease-in-out;

    height: 300px !important;
}  

figure  {
 width: 300px;
 height: 300px;
 
 //height: 200px;
 margin: 1em;
 padding: 0;
 background: #fff;
 overflow: hidden;
 border: 1px solid #222;
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div >
   <h2>ARGH</h2>
     <div>
      <span class="taller">
         <figure>
           <img ng-mouseenter="set_ratio(this)" draggable="true" class="thumb" id="{{tablet.created}}" title="{{ tablet.title }}" data-ng-  src={{tablet.src}} />
         </figure>
      </span>
   </div>
  </div>
</div>
Hadi J
  • 16,989
  • 4
  • 36
  • 62
  • I don't think so. Refresh your page, then click run code snippet and mouse over the image. Then click run code snippet a second time and mouse over. See the difference, because I do? Refresh the page and click it again. It keeps happening to me. One jumps and the other is smooth. That is my exact issue. Thanks for illustrating. – Squirrl Mar 29 '16 at 09:38
  • No, do u notice the difference between the jump and the smooth transition? – Squirrl Mar 29 '16 at 10:07
  • http://jsfiddle.net/U3pVM/23506/ If you click refresh it won't wont, but if you click run it will. The style won't render. – Squirrl Mar 29 '16 at 10:09
  • http://jsfiddle.net/U3pVM/23518/ The mouseenter is working better. If you can make it a little smoother, I'll give u the green. Thank you :) – Squirrl Mar 29 '16 at 10:38
0

The answer can be found here.

is there a post render callback for Angular JS directive?

I simply wrapped it in a $timeout

$timeout(function(){

    $scope.set_ratio = function (it) { //Find ratio and return style so that it can be used for zoom effect. 
        var img = new Image();  
        img.src = it.tablet.src;
        console.log(it.tablet)

        if(img.height>img.width){
            var h = 300*(img.height/img.width)+'px'     
            return {
                "height": h
            }   
        }else{
            var w = 300*(img.width/img.height)+'px'     
            return {
                "width":w 
            }       
        }
    }

}, 50)
Community
  • 1
  • 1
Squirrl
  • 4,909
  • 9
  • 47
  • 85