I am using ui-router in my web application. Root div code is:
<div ui-view="content" class="fade-in-up"></div>
When I go from one state to another (/orders to /feedbacks in the screenshot below), the first state doesn't hide before the new state's fade animation has finished.
My css is:
#-webkit-keyframes fadeInUp {
0% {
opacity: 0;
-webkit-transform: translateY(15px);
}
100% {
opacity: 1;
-webkit-transform: translateY(0);
}
}
#-moz-keyframes fadeInUp {
0% {
opacity: 0;
-moz-transform: translateY(15px);
}
100% {
opacity: 1;
-moz-transform: translateY(0);
}
}
#-o-keyframes fadeInUp {
0% {
opacity: 0;
-o-transform: translateY(15px);
}
100% {
opacity: 1;
-o-transform: translateY(0);
}
}
#keyframes fadeInUp {
0% {
opacity: 0;
transform: translateY(15px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.fade-in-up {
-webkit-animation: fadeInUp .5s;
animation: fadeInUp .5s;
}
Where am I wrong?
I've just posted a tutorial with a working demo showing how to do this using ngAnimate with CSS transitions.
There's a couple of transitions in the demo, this is the CSS snippet for fading in new views on the main element:
/* start 'enter' transition on main view */
main.ng-enter {
/* transition on enter for .5s */
transition: .5s;
/* start with opacity 0 (invisible) */
opacity: 0;
}
/* end 'enter' transition on main view */
main.ng-enter-active {
/* end with opacity 1 (fade in) */
opacity: 1;
}
There's only a transition on .ng-enter and not on .ng-leave, which causes the new view (that is entering) to fade in while the old view (that is leaving) disappears instantly without a transition.
ui-router will fire your ui-view route change view out at the same time as the incoming view in. so what you get is the previous ui-view still visible while the next ui-view is rendered and if you're animating the view out then there will be that transition duration of overlap between the old view and the new. you should look into holding off on rendering the new ui-view until the old one is finished animating out (before animating the new one in)
i would look into the ui-router $rootScope state change events to tap into this (https://github.com/angular-ui/ui-router/wiki#state-change-events).
## Hold off on the state change, until current (previous) state has finished animating out
$rootScope.$on '$stateChangeStart', (event, toState, toParams, fromState, fromParams) ->
console.log "state change start", arguments
$rootScope.$on '$stateChangeSuccess', (event, toState, toParams, fromState, fromParams) ->
console.log "state change success", arguments
also have a look it this person's example http://homerjam.github.io/angular-ui-router-anim-in-out. they have created a module that hooks into the ui-view and breaks apart the change into an enter and leave where you can trigger the animate in (of new view) after the animate out (of old view) http://homerjam.github.io/angular-ui-router-anim-in-out/anim-in-out.js
this person explains what is happening with the ui-view change duplication https://youtu.be/W89DYSthCTQ?t=345
Try adding the class "main" to your DIV so it looks like this:
<div ui-view="content" class="main"></div>
Then use this CSS:
.main.ng-enter {
transition: 0.25s;
opacity: 0; }
.main.ng-enter-active {
opacity: 1; }
.main.ng-leave {
transition: 0.25s;
opacity: 1; }
.main.ng-leave-active {
opacity: 0; }
You could use the .ng-enter and .ng-leave classes (If you've included the 'ng-animate' module) to trigger the animations. Then you can do something like this in your CSS file:
[ui-view].ng-leave {
animation: fadeOut 0.5s;
}
[ui-view].ng-enter {
animation: fadeIn 0.5s;
}
or just set a transition property with a duration on the transform and opacity properties and just set them accordingly in the ng-enter and ng-leave classes.
Related
I have a CSS3 rotate transform with a cubic-bezier transition-timing-function, it is working fine on mouse over, but i want to disable the mouseleave animation. I prepared a simple jsFiddle to show you.
img {
transition : all 1s cubic-bezier(0.680,-0.550,0.265,1.550);
}
img:hover {
transform: rotate(360deg);
}
You mean you don't want it to transition back when you hover off? You can use an "infinite" (actually very large) transition-delay (that's the second time value in the shorthand) for that.
Like this:
demo
CSS:
img {
transition: 0s 99999s; /* transition when mouse leaves */
}
img:hover {
transform: rotate(360deg);
/* transition on mouseover */
transition: 1s cubic-bezier(0.680,-0.550,0.265,1.550);
}
Note that this will make the image rotate only on first hover.
If you want to make it rotate for each hover, then you'll have to use keyframe animations. Like this:
demo
CSS (no prefixes, you'll have to add them):
img:hover {
animation: rot 1s cubic-bezier(0.680,-0.550,0.265,1.550);
}
#keyframes rot {
to {
transform: rotate(360deg);
}
}
Also, I noticed that you were writing the unprefixed property first - you should always put it last. Especially now, when the coming versions of IE, Firefox and Opera are unprefixing transitions.
I'm trying to get this animation to work in Chrome:
#-webkit-keyframes flipAnimation {
0% {
-webkit-transform: perspective(400px) rotateY(90deg);
-webkit-transform-origin: right center;
}
100% {
-webkit-transform: perspective(400px) rotateY(0deg);
-webkit-transform-origin: right center;
}
}
#-webkit-keyframes appear {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#-webkit-keyframes disappear {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
.flipAnimation {
opacity: 0;
-webkit-backface-visibility: visible !important;
-webkit-animation: flipAnimation .5s, appear .2s, disappear .3s;
-webkit-animation-delay: 0s, .3s, 2s;
}
But it's always glitchy. For one, the div.flipAnimation doesn't appear with opacity 0. Second, the div flashes in and out and the last disappear animation doesn't seem to trigger properly. Is there a problem with have 2 opacity animations in the same animation even though they're spaced with delays?
I'm not quite sure if this is the desired effect are you aiming for, but you can look up at my solution:
JS Fiddle demo
I think the effect you are looking for cannot be achieved with keyframes. Please confirm if this is satisfactory!
Here the code working.
Demo Jsfiddle
the reson that it was not work is the delay time. you could not see the different.
so I change the delay time for 10 sec just for you see that it is work.
Your code work with other delay
I make some change in the code for to see that is work, just change the time and ather thing according your request:
first you see the appear ,flipAnimationu working togther after 20s you will see the disappear work and change color to azure,black,azure.
Looks like this can't be done with key frames alone. I'm going to use jquery to do the final fade out animation.
This question already has answers here:
Maintaining the final state at end of a CSS animation
(5 answers)
Closed 3 months ago.
I'm trying to animate a div so that when the page load it has scale(0,0) and animates to scale(1,1). The problem I have is that once the animation takes effect the div scales to 0 again. What I want is the div to animate to scale(1,1) and staying like that. Here's my CSS code
#-moz-keyframes bumpin {
0% { -moz-transform: scale(0,0); }
100% { -moz-transform: scale(1,1); }
}
.landing .board {
-moz-transform: scale(0,0);
-moz-transform-origin: 50% 50%;
}
.landing .board {
-moz-animation-name: bumpin;
-moz-animation-duration: 1s;
-moz-animation-timing-function: ease;
-moz-animation-delay: 0s;
-moz-animation-iteration-count: 1;
-moz-animation-direction: normal;
}
What am I doing wrong?
You're looking for animation-fill-mode:forwards which applies the last keyframe of the nimation to the element when the animation is done. https://developer.mozilla.org/en/CSS/animation-fill-mode
-moz-animation-fill-mode: forwards
Another way of doing this: If all you want to do is animate an element to scale, you don't need to use keyframes. transitions will suffice.
.landing-board {
-moz-transition: all 1s ease;
/* all other css properties */
}
.landing-board.animated {
-moz-transform: scale(1.1);
}
And very little javascript to add the related class to your element: (Here i'm using jquery but it could be done in any other framework or pure javascript)
$(window).load(function() {
$('.landing-board').addClass('animated');
});
When creating continuous animations in CSS3, such as an infinite rotation, is the keyframe at 100% inclusive? That is, are the properties given at 100% set at the last frame of the current iteration?
An example: would a glow animation using
#-webkit-keyframes glow {
0% { opacity: 1; }
50% { opacity: 0.7; }
100% { opacity: 1; }
}
cause a slight (and possibly imperceptible) lag due to two consecutive frames with an opacity of 1?
But mostly, your problem here is due to the easing which is by default ease-in-out, meaning it will focus more on the style of 0% and 100% of your animation. So it will be mainly very close to opacity:1.
For this kind of animation you can also use alternate, so you'll have only 2 keyframes.
#-webkit-keyframes glow {
from { opacity: 1; }
to { opacity: 0.5; }
}
.glow {
-webkit-animation-name: glow;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: alternate;
}
The current state of CSS3 animation is that many of them have a small but perceptible stutter particularly if they repeat too quickly. To mitigate this, make your animation longer with more keyframes aka
0% { opacity 1; }
5% { opacity .7; }
10% { opacity 1; }
15% { opacity .7; }
20% { opacity 1; }
etc.
How can I make a CSS3 Animation play to the end and then stop dead. I don't want it to return the elements being transformed back to their initial states.
Right now I'm using some javascript to add a class to the element after the animation's duration with the same properties as 100% in the animation.
This is possible with the "animation-fill-mode" defined as "forwards", at least in Webkit. I got this result with code like this:
#-webkit-keyframes test {
100% { background-color: #0000ff; }
}
a { background-color: #ff0000; }
a:hover { -webkit-animation: test 1s 1 ease forwards }
Note that specifying start color in 0% keyframe and end color in :hover was not necessary.
Of course, this code is Webkit specific. I haven't tried in other browsers with other vendor prefixes or with the general "animation" property.
put your end values in the main css class and the start values in the animation keyframes at 0%:
#keyframes test {
0% {
background-color: #ff0000; /* start value */
}
100% {
background-color: #0000ff;
}
}
a {
background-color: #ff0000; /* normal state */
}
a:hover {
animation-name: test;
animation-duration: 1s;
background-color: #ff0000; /* final state, after animation is finished */
}
In case this question is still open, I don't think this is possible using CSS3 animations as they're currently specified:
An animation does not affect the computed value before the application of the animation, before the animation delay has expired, and after the end of the animation.
However, you should be able to use CSS3 transitions for basic effects. There's a slide in the html5rocks.com presentation that shows how to do this. Here's the relevant [paraphrased] excerpt:
#box.left { margin-left: 0; }
#box.right { margin-left: 1000px; }
#box { -webkit-transition: margin-left 1s ease-in-out; }
// Run this to animate to the left
document.getElementById('box').className = 'left';
// Run this to animate to the right
document.getElementById('box').className = 'right';
animation-fill-mode: forwards
The animation-fill-mode CSS property specifies how a CSS animation should apply styles to its target before and after it is executing