ng-animate when ng-view is updated through route - javascript

I try to animate the change of a ng-view div in AngularJS.
So my div inside my index.html file looks like:
<div ng-view></div>
I have another html-file (view1.html) with just divs inside.
My app.js with the routing looks like:
app.config(function($routeProvider) {
$routeProvider
.when('/sites/:templateID',
{
controller: 'simpleController',
templateUrl:'templates/question.html'
})
});
I am changing the path with a click on a button, and call this:
$location.path("/sites/" + nextID);
The URL changes of the site, and only the ng-view-div gets updated. But when i am applying a ng-animation to it:
<div class="content" data-ng-view ng-animate="{enter: 'animate-enter', leave: 'animate-leave'}"></div>
It doesn't work. I included AngularJS 1.2.5, the animate-js file inside my index.html and also my CSS:
.animate-enter, .animate-leave {
-webkit-transition:all 2s ease;
-moz-transition:all 2s ease;
-o-transition:all 2s ease;
transition:all 2s ease;
}
.animate-enter {
left: -100%;
}
.animate-enter.animate-enter-active {
left: 0;
}
.animate-leave {
left: 0;
}
.animate-leave.animate-leave-active {
left: 100%;
}
Is there a way to animate the ng-view change through route-(URL)-changing?

ng-view can work with animation. In fact there is official example of it. Check out this link.
Also remember that you also need to declare ngAnimate dependency for it to work:
var app = angular.module('App', [
'ngRoute',
'ngAnimate'
]);
HTML
<div class="content">
<div class="question" ng-view></div>
</div>
Class .question defines CSS animation:
.question.ng-enter,
.question.ng-leave {
-webkit-transition: all 1s ease;
-moz-transition: all 1s ease;
-o-transition: all 1s ease;
transition: all 1s ease;
}
Your modified demo Plunker.
Mini-project
I also created a little project demonstrating different ngView animations. Check it out this page.

There are a few changes to the CSS rules with Angular Animation 1.2+. ng-animate directive is no longer used so AngularJS now changes the class of the element based on events, such as hide, show, etc.
You can define these like so in your CSS:
.toggle {
-webkit-transition: all 0 cubic-bezier(0.25, 0.46, 0.45, 0.94);
-moz-transition: all 0 cubic-bezier(0.25, 0.46, 0.45, 0.94);
-ms-transition: all 0 cubic-bezier(0.25, 0.46, 0.45, 0.94);
-o-transition: all 0 cubic-bezier(0.25, 0.46, 0.45, 0.94);
transition: all 0 cubic-bezier(0.25, 0.46, 0.45, 0.94);
/* easeOutQuad */
-webkit-transition-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
-moz-transition-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
-ms-transition-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
-o-transition-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
transition-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
/* easeOutQuad */
}
.toggle.ng-enter {
opacity: 0;
transition-duration: 250ms;
-webkit-transition-duration: 250ms;
}
.toggle.ng-enter-active {
opacity: 1;
}
.toggle.ng-leave {
opacity: 1;
transition-duration: 250ms;
-webkit-transition-duration: 250ms;
}
.toggle.ng-leave-active {
opacity: 0;
}
.toggle.ng-hide-add {
transition-duration: 250ms;
-webkit-transition-duration: 250ms;
opacity: 1;
}
.toggle.ng-hide-add.ng-hide-add-active {
opacity: 0;
}
.toggle.ng-hide-remove {
transition-duration: 250ms;
-webkit-transition-duration: 250ms;
display: block !important;
opacity: 0;
}
.toggle.ng-hide-remove.ng-hide-remove-active {
opacity: 1;
}
That way when you have your HTML element you really only have to define the class="toggle" for example. When your app runs Angular will append the classes appropriately.
Here is a good resource for different animation techniques by Augus
And here is a break down of the changes in AngularJS Animations

In 1.2+ you no longer need the directive, the css notation has changed aswell.
The 1.2.5 way of doing it is as follows:
Give your View a class:
<div data-ng-view class="mainview-animation"></div>
Add the following dependency:
/**
* Main Application & Dependencies
* #type {*}
*/
var mainApp = angular.module('app', [
// Angular modules
'ngRoute',
'ngAnimate'
]);
Then add the following CSS:
/*
The animate class is apart of the element and the ng-enter class
is attached to the element once the enter animation event is triggered
*/
.mainview-animation.ng-enter {
-webkit-transition: .3s linear all; /* Safari/Chrome */
-moz-transition: .3s linear all; /* Firefox */
-o-transition: .3s linear all; /* Opera */
transition: .3s linear all; /* IE10+ and Future Browsers */
}
/**
* Pre animation -> enter
*/
.mainview-animation.ng-enter{
/* The animation preparation code */
opacity: 0;
}
/**
* Post animation -> enter
*/
.mainview-animation.ng-enter.ng-enter-active {
/* The animation code itself */
opacity: 1;
}

Just to add to the accepted answer it is necessary to either define position: absolute or display: block to .ng-enter and .ng-leave. I struggled with this for a while when trying to fade in ng-view on route change and didn't want to use absolute positioning. Example without browser prefixes for transition:
//add animate class to ng-view
//css
.animate.ng-leave, .animate.ng-enter {
transition: 1s cubic-bezier(0.5, 0.1, 0.25, 1) all;
}
.animate.ng-enter, .animate.ng-leave.ng-leave-active {
opacity: 0;
display: block;
}
.animate.ng-leave, .animate.ng-enter.ng-enter-active {
opacity: 1;
display: block;
}
For my specific situation I removed the transition from ng-leave so there wouldn't be overlap of elements which would cause one to be pushed down due to block display.

Related

CSS hover with mouse in translateXY

Thank you for reading my question
.ab {
position:absolute;left:50%;top:50%
}
.logo_img {
width:100px;
}
.logo_img:hover {
-webkit-animation: hvr 0.5s ease-out 1 0s;
-ms-animation: hvr 0.5s ease-out 1 0s;
animation: hvr 0.5s ease-out 1 0s;
}
#keyframes hvr {
0% { -webkit-transform: translateX(0px);transform: translateX(0px); }
50% { -webkit-transform: translateX(900px);transform: translateX(900px);}
51% { -webkit-transform: translateX(-900px);transform: translateX(-900px);}
100% {-webkit-transform: translateX(0px);transform: translateX(0px);}
}
<div class="ab"><img src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" class="logo_img" /></div>
Problem is when mouse goes on it, and image moves, then mouse is not on image and sometimes hover does not work!
Is there any way to do animation like this hover but if mouse is not on image... it keeps going?
Is it possible to user jQuery hover and add class on hover? And delete that class after animation ends?
You can create a container div for the image, wich always stays in the same place, and put the image inside this div. Then instead of checking, if the mouse is over the image, you can check if it is over the div.
#container {
border: 1px solid black;
}
.logo_img {
width:100px;
margin-left: calc(50% - 50px);
}
#container:hover .logo_img {
-webkit-animation: hvr 0.5s ease-out 1 0s;
-ms-animation: hvr 0.5s ease-out 1 0s;
animation: hvr 0.5s ease-out 1 0s;
}
#keyframes hvr {
0% { -webkit-transform: translateX(0px);transform: translateX(0px); }
50% { -webkit-transform: translateX(900px);transform: translateX(900px);}
51% { -webkit-transform: translateX(-900px);transform: translateX(-900px);}
100% {-webkit-transform: translateX(0px);transform: translateX(0px);}
}
<div id="container">
<img src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" class="logo_img">
</div>
var duration = 500;
$('img').mouseenter(function() {
$(this).addClass('hvr').delay(duration).queue(function() {
$(this).removeClass('hvr');
$(this).dequeue();
});
});
CODEPEN
If you mean to make animation work without hover then add this animation-iteration-count to infinite.
.logo_img {
-webkit-animation: hvr 5s ease-out;
-ms-animation: hvr 5s ease-out;
animation: hvr 5s ease-out infinite;
}
Updated another answer using jQuery,
<img src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"/>
$(document).ready(function(){
$("img").on("mouseenter",function(){
$(this).addClass("logo_img");
});
$("img").on("mouseleave",function(){
$(this).removeClass("logo_img");
});
});

Jquery CSS animation bug on mobile

I have an animation using JQuery and CSS for sliding divs into view.
This is my javascript code:
(function($) {
$.fn.visible = function(partial) {
var $t = $(this),
$w = $(window),
viewTop = $w.scrollTop(),
viewBottom = viewTop + $w.height(),
_top = $t.offset().top,
_bottom = _top + $t.height(),
compareTop = partial === true ? _bottom : _top,
compareBottom = partial === true ? _top : _bottom;
return ((compareBottom <= viewBottom) && (compareTop >= viewTop));
};
})(jQuery);
$(window).scroll(function(event) {
$(".slide-up").each(function(i, el) {
var el = $(el);
if (el.visible(true)) {
el.addClass("come-up");
}
});
});
$(document).ready(function() {
$(".heading-slide-down").each(function(i, el) {
var el = $(el);
if (el.visible(true)) {
el.addClass("come-down");
}
});
});
$(window).scroll(function(event) {
$(".slide-left").each(function(i, el) {
var el = $(el);
if (el.visible(true)) {
el.addClass("come-left");
}
});
});
$(window).scroll(function(event) {
$(".slide-right").each(function(i, el) {
var el = $(el);
if (el.visible(true)) {
el.addClass("come-right");
}
});
});
And this is my CSS
/** FADE IN SLIDING FROM BOTTOM TO TOP **/
.come-up {
transform: translateY(150px);
animation: comeup 0.8s ease forwards;
}
.come-up:nth-child(odd) {
animation-duration: 0.6s;
}
#keyframes comeup {
to { transform: translateY(0); }
}
/** FADE IN SLIDING FROM TOP TO BOTTOM **/
.come-down {
transform: translateY(-100px);
animation: comedown 0.8s ease forwards;
}
.come-down:nth-child(odd) {
animation-duration: 0.6s;
}
#keyframes comedown {
to { transform: translateY(0); }
}
/** FADE IN SLIDING FROM RIGHT TO LEFT **/
.come-left {
transform: translateX(100px);
animation: comeleft 0.8s ease forwards;
}
.come-left:nth-child(odd) {
animation-duration: 0.6s;
}
#keyframes comeleft {
to { transform: translateX(0); }
}
/** FADE IN SLIDING FROM LEFT TO RIGHT **/
.come-right {
transform: translateX(-100px);
animation: comeright 0.8s ease forwards;
}
.come-right:nth-child(odd) {
animation-duration: 0.6s;
}
#keyframes comeright {
to { transform: translateX(0); }
}
With my divs that need sliding I just apply the classes slide-up or slide-left etc.
Live demo: http://www.shivampaw.com
On my laptop it works fine, however on my phone (iPhone) the divs are already in the correct position and as I scroll towards them I see them transform away and then animate to where they should be.
I'm not sure how else I can explain this, if possible try and take a look for yourself and just scroll down the site slowly and you will see it.
How come this is happening and is there a fix?
Thanks!
Update:
The problem is that on mobile safari on an iPhone SE latest iOS the divs that should be starting positioned downwards so they can slide up into place are starting in the right place and then moving down and sliding backup when they are in view.
I'm experiencing the exact same issue.
The problem seems to be that on mobile devices, .visible() only becomes true some time AFTER the element has entered the screen (rather than EXACTLY when it enters the screen), making the element visible to you already before the animation is played.
I quick-fixed this by giving the elements an opacity of 0 and changing this only when the animation plays.
You would have to add this to your CSS:
.slide-up, .heading-slide-down, .slide-left, .slide-right {
opacity:0;
}
.come-up, .come-down, .come-left, .come-right {
opacity:1;
-webkit-transition: opacity 0.8s ease-in;
-moz-transition: opacity 0.8s ease-in;
-o-transition: opacity 0.8s ease-in;
-ms-transition: opacity 0.8s ease-in;
transition: opacity 0.8s ease-in;
}
.come-up:nth-child(odd), .come-down:nth-child(odd), .come-left:nth-child(odd), .come-right:nth-child(odd) {
opacity:1;
-webkit-transition: opacity 0.6s ease-in;
-moz-transition: opacity 0.6s ease-in;
-o-transition: opacity 0.6s ease-in;
-ms-transition: opacity 0.6s ease-in;
transition: opacity 0.6s ease-in;
}
To make sure these animations aren't played on items that are already in view when the page loads, you could add this to your jQuery:
$(".slide-up, .slide-left, .slide-right").each(function() {
if ($(this).visible(true)) {
$(this).addClass("already-visible");
}
});
And at the bottom of your CSS:
.already-visible {
opacity:1;
transform: translateY(0);
transform: translateX(0);
animation: none;
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
-ms-transition: none;
transition: none;
}

Slider animation with ngAnimate in a ngSrc directive

I have some code like this https://stackoverflow.com/a/18235271/3018275
So I wanted to do an animation like this http://www.nganimate.org/angularjs/ng-switch/slider-css3-transition-animation
But I've seen that ng-animate doesn't work with ng-src so i thought to use something with ng-show and a watch event to set a boolean variable, but i can't do this.
Anyone can suggest me something?
The best practice is to make a directive for the slider but you could do something like this. Its missing some code but this is the approach you should have.
In your html:
<div id="image-slider" ng-style="sliderStyle">
<div class="image" ng-repeat="(key, source) in imagesServingUrl track by $index" ng-style="imgStyle">
<img class="productImage" ng-src="{{source.serving_url}}" ng-class="{'hideImg':(current!=key), 'showImg':(current==key)}" />
<span class="arrow-right" ng-click="next(current+1)"/>
<span class="arrow-left" ng-click="prev(current-1)"/>
</div>
</div>
`
And in your css:
img.showImg {
opacity: 1;
-webkit-transition: 0.5s cubic-bezier(0.49, 0, 0.5, 1) all;
-moz-transition: 0.5s cubic-bezier(0.49, 0, 0.5, 1) all;
-ms-transition: 0.5s cubic-bezier(0.49, 0, 0.5, 1) all;
-o-transition: 0.5s cubic-bezier(0.49, 0, 0.5, 1) all;
transition: 0.5s cubic-bezier(0.49, 0, 0.5, 1) all;
}
img.hideImg {
opacity: 0;
-webkit-transition: 0.5s cubic-bezier(0, 0.5, 1, 0.47) all;
-moz-transition: 0.5s cubic-bezier(0, 0.5, 1, 0.47) all;
-ms-transition: 0.5s cubic-bezier(0, 0.5, 1, 0.47) all;
-o-transition: 0.5s cubic-bezier(0, 0.5, 1, 0.47) all;
transition: 0.5s cubic-bezier(0, 0.5, 1, 0.47) all;
}
And in your controller
$scope.next = function(next) {
$scope.current = next;
$scope.percent -= 100;
return $scope.imgStyle = {
transform: 'translateX(' + $scope.percent + '%)',
width: $scope.sliderWidth,
height: $scope.sliderHeight
};
};

How do I change the opacity of an image?

<script type="text/javascript">
$(document).ready(function(){
$('#logo').mouseenter(function() {
$('#logo').fadeTo("fast",0.3);
});
$('#logo').mouseleave(function() {
$('#logo').fadeTo("fast",1)
});
});
</script>
I made this to change the opacity of an image while hovering over it with the cursor, but this doesn't happen. :(
You don't need jQuery for that, you can use CSS:
Example HTML - you need it to have the ID logo.
<img id="logo" src="http://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Example.svg/200px-Example.svg.png" />
CSS
#logo {
opacity: 1;
filter:alpha(opacity=100);
transition: opacity 0.2s linear 0s;
-webkit-transition: opacity 0.2s linear 0s;
}
#logo:hover {
opacity: 0.3;
filter:alpha(opacity=30);
transition: opacity 0.2s linear 0s;
-webkit-transition: opacity 0.2s linear 0s;
}
http://jsfiddle.net/pFEdL/2/
What does you HTML look like for your image? Is it embedded in other divs?
SO: Jquery mouseenter() vs mouseover()
As gilly3 states in the question above, "Each time your mouse enters or leaves a child element, mouseover is triggered, but not mouseenter".

jQuery toggleClass - can't animate or give it a transition

I'm having a small issue with my code. I have an element that when the page scrolls it will appear. However, I cannot get it to "appear" in a smoother way. I have tried CSS transitions and attempted fadeIn but neither work. It always just "jumps" in, I cannot get it to ease in.
Here is the code:
$(window).on("scroll", function () {
$('.navbar').toggleClass('visible', $(document).scrollTop() > 40);
});
So it appears just fine, but I can't figure out how to animate adding the class name.
This is the CSS btw:
.navbar {
visibility: hidden;
}
.navbar.visible {
visibility: visible;
}
visibility can't be animated with CSS transitions.
But you can do :
.navbar {
opacity: 0;
transition: opacity .5s ease; // Feel free to use prefixes.
}
.navbar.visible {
opacity: 1;
}
CSS transition / animations is surely the best way to animate something in 2014. You should avoid fadeToggle() and others jQuery animation methods.
instead of using toggleClass, use fadeToggle. it will do everything for u as far as CSS..
give it a try, just fadeToggle();
Here is the example of your code with correct css transition. You cannot animate visibility, but you can play with position and opacity.
http://jsfiddle.net/xZ6fm/
.navbar {
position: fixed;
top: -100px;
left: 0; right: 0;
padding: 12px;
opacity: 0;
background: #ccc;
}
.navbar.visible {
top: 0;
opacity: 1;
-webkit-transition: top 0.3s linear, opacity 0.7s linear;
-moz-transition: top 0.3s linear, opacity 0.7s linear;
transition: top 0.3s linear, opacity 0.7s linear;
}
As indicated in the other answer, fadeToggle() will get the work done for you. And frankly, it's probably the easiest way to accomplish such an effect.
CSS transitions require the transition property. Place this block of code in each of your CSS declarations:
transition: visibility .25s linear;
-webkit-transition: visibility .25s linear;
-moz-transition: visibility .25s linear;
-o-transition: visibility .25s linear;
If you have difficulties with visibility, try using opacity instead.

Categories

Resources