Reputation: 263
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?
Upvotes: 0
Views: 615
Reputation: 14417
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.
Upvotes: 2
Reputation: 5217
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);
Upvotes: 3