0

I have a picture with an icon in the middle that indicates the ability to scroll for the user. When the user scrolls, I would like to fade the icon out. Right now I can hide the picture but would like the fade effect.

Here is my view:

<div style="overflow: scroll;">
    <img id="fullImage" ng-src="{{imageUrl}}" imageonload>
    <img id="drag-arrows" class="drag-arrows" ng-src="images/icon-drag.png"/>
    <h3 id="optionName" class="optionName">{{ optionName }}</h3>
    <a class="close-reveal-modal" ng-click="cancel()"><img class="cancel-icon" ng-src="images/icon-close-fullscreen.png"></a>
</div>

Here is my directive that listens on the touchmove event to hide the drag arrows icon:

modalController.directive('imageonload', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('load', function() {

                var img = document.getElementById("fullImage");

                var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
                var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

                var imageWidth = img.width;
                var imageHeight = img.height;

                var aspectRatio = imageWidth / imageHeight;

                if (w < imageWidth && h < imageHeight){
                  // scale image down
                  var widthDiff = imageWidth - w;
                  var heightDiff = imageHeight - h;

                  if(widthDiff <= heightDiff){
                    imageWidth = w;
                    imageHeight = w / aspectRatio;
                  }
                  else{
                    imageHeight = h;
                    imageWidth = h * aspectRatio;
                  }
                }
                else if (w < imageWidth && h > imageHeight) {
                  // fill image vertically
                  imageHeight = h;
                  imageWidth = h * aspectRatio;
                }
                else if (w > imageWidth && h < imageHeight) {
                  // fill image horizontally
                  imageWidth = w;
                  imageHeight = w / aspectRatio;
                }
                else {
                  // fill image in both directions
                  var widthDiff = w - imageWidth;
                  var heightDiff = h - imageHeight;

                  if(widthDiff >= heightDiff){
                    imageWidth = w;
                    imageHeight = w / aspectRatio;
                  }
                  else{
                    imageHeight = h;
                    imageWidth = h * aspectRatio;
                  }
                }

                img.style.width = imageWidth + "px";
                img.style.height = imageHeight + "px";
                img.style.maxWidth = "none";

                // add scroll left to parent container
                var container = img.parentNode;
                var scrollLeft = (imageWidth - w) / 2;
                container.scrollLeft = scrollLeft;

            });

            element.bind('touchmove', function(){

              var arrows = document.getElementById("drag-arrows");
              arrows.style.display = "none";

            });
        }
    };
});

Any suggestions on how to create this fade effect especially the correct angularjs way if possible?

0

2 Answers 2

3

If you are using jQuery, try .fadeOut() instead of arrows.style.display = "none";

arrows.fadeOut();

If you are not using jQuery, then you can do this with CSS classes:

arrows.className = "drag-arrows hidden";

And in CSS:

.drag-arrows {
    opacity: 1;
    -webkit-transition: opacity 0.5s; /* For Safari 3.1 to 6.0 */
    transition: opacity 0.5s;
}

.hidden {
    opacity: 0;
}

Do note that the CSS solution will simply change the opacity of the arrows, and not the actual display property, since display cannot be animated. If you still want to put your arrows' display property to none, you will need to add an eventListener as following:

arrows.className = "drag-arrows hidden";
arrows.addEventListener("transitionend", function(){
    arrows.style.display = "none";
    arrows.removeEventListener("transitionend");
}, false);

If you then want to show your arrows again later, you can use:

arrows.className = "drag-arrows";
arrows.addEventListener("transitionend", function(){
    arrows.style.display = "block"; // Or whichever display you had before
    arrows.removeEventListener("transitionend");
}, false);
Sign up to request clarification or add additional context in comments.

Comments

2

So I have created this plnkr extracted most of it from Angular Docs. It also shows how to put it all together, rather than just a excerpt, even though Angular does give this as well.

http://docs.angularjs.org/api/ngAnimate

http://docs.angularjs.org/api/ng/directive/ngShow#animations

So its the css3 that does all the work:

.animate-show {
  line-height: 20px;
  opacity: 1;
  padding: 10px;
  border: 1px solid black;
  background: white;
}

.animate-show.ng-hide-add.ng-hide-add-active,
.animate-show.ng-hide-remove.ng-hide-remove-active {
  -webkit-transition: all linear 0.5s;
  transition: all linear 0.5s;
}

.animate-show.ng-hide {
  line-height: 0;
  opacity: 0;
  padding: 0 10px;
}

Then it is merely using the directive:

 <p ng-show="vm.showText" class="animate-show">Sometext</p>

and the js:

vm.showText = false;

$timeout(function () {
  vm.showText = true;
}, 2000);

The $timeout just represents some async function. like a $http call.

Obviously it doesn't matter whether you do this from a controller or a directive, they both achieve the same result.

A cool tip, if you extend the time of the animation, and view the elements in the chrome or firebug console, you can watch the css classes as they change. This will give you a close look at what is exactly happening and how to modify your css to give the proper result.

3 Comments

Thanks for the response. This cleared up a lot for me. But just to clarify, how would I access the vm.showText scope variable from the directive?
it's on the directive scope, or you can put another attribute on the element and read that. Would you like an updated example
Sure thing, I will get on it later this afternoon. @user3562751

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.