Animating UI Router using #keyframes not working - angularjs

I am attemping to animate the ui-router using #keyframes property.
What I want to achieve is that when the user clicks on an item in the menu, the page to come flying in
Doesn't seem to be working as expected.
#keyframes page-slide {
0% {left:100%; top:0px;}
25% {left:75%; top:0px;}
50% {left:50%; top:0px;}
75% {left:25%; top:0px;}
100% {left:0%; top:0px;}
}
Any clue what I could be missing here ?
Link to Plnkr: http://plnkr.co/edit/CXNaNogXwn8Vzg8rugDT?p=info

If you just wanna use CSS you need to wrap the position:absolute with a position:relative container. Also set the height: 100% for all the containers.
http://embed.plnkr.co/xOEgPjvNtfpcQAxj6rWY/preview
.container {
position: relative;
height: 100%;
}
.page-transition {
width: 100%;
height: 100%;
position: absolute;
animation-name: page-slide;
animation-duration: 4s;
}
#keyframes page-slide {
0% {left:100%; top:0px;}
25% {left:75%; top:0px;}
50% {left:50%; top:0px;}
75% {left:25%; top:0px;}
100% {left:0%; top:0px;}
}

What exactly is not working as expected?
If you want the animation to run more "fluidly" just define start and end:
#keyframes page-slide {
from {left:100%; top:0px;}
to {left:0%; top:0px;}
}
Or using translate3d
#keyframes page-slide {
from {
transform: translate3d(100%, 0, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
Here a link to your example with the changes I made: http://embed.plnkr.co/7bTcKhLWJmm4hXkdcRvN/preview

Related

Reactjs: Wait for animation to finish

inside my react app, users are able to enter data that is saved on the server. The data is saved immediatly, users don't have to press any "save" button. I want to display a short animation (similar to https://codepen.io/Sixclones/pen/VBdeXL) whenever I'm sending data to the server. After doing some research, I figured out that I should use react-transition-group (http://reactcommunity.org/react-transition-group/css-transition).
I made a component savingIcon:
const SavingIcon: React.SFC<SavingIconProps> = ({
className,
saving,
}) => {
return (
<div className={ classNames(className, "saving-icon") }>
<CSSTransition
timeout={ 200 }
classNames="saving"
in={ saving }
>
<div className="saving-balls">
<div className="saving-balls__item" />
<div className="saving-balls__item" />
<div className="saving-balls__item" />
</div>
</CSSTransition>
</div>
);
}
Whenever something is being saved, saving is set to true and I'd like to display the animation.
Inside saving-icon.scss I put the following CSS (I tried out several approaches, therefore there might be some unnecessary css):
#keyframes bouncing {
0% {
transform: translate3d(0, 10px, 0) scale(1.2, 0.85);
}
100% {
transform: translate3d(0, -20px, 0) scale(0.9, 1.1);
}
}
div.saving-icon {
position: sticky;
top: 15vh;
display: flex;
flex-direction: column;
justify-content: end;
height: 84vh;
$anim-drt: 0.4s;
$anim-ease: cubic-bezier(.6, .05, .15, .95);
.saving-enter {
div.saving-balls{
&__item {
background-color: $success-color;
transition: background-color 20ms;
}
}
}
.saving-enter-active {
div.saving-balls{
&__item {
background-color: $active-color;
transition: background-color 20ms;
}
&:nth-child(1) {
animation: bouncing $anim-drt alternate infinite $anim-ease;
transition: animation 1000ms;
}
&:nth-child(2) {
animation: bouncing $anim-drt $anim-drt/4 alternate infinite
$anim-ease backwards;
transition: animation 1000ms;
}
&:nth-child(3) {
animation: bouncing $anim-drt $anim-drt/2 alternate infinite
$anim-ease backwards;
transition: animation 1000ms;
}
}
}
.saving-exit {
div.saving-balls{
&__item {
background-color: $active-color;
transition: background-color 20ms;
}
&:nth-child(1) {
animation: bouncing $anim-drt alternate infinite $anim-ease;
transition: animation 1000ms;
}
&:nth-child(2) {
animation: bouncing $anim-drt $anim-drt/4 alternate infinite
$anim-ease backwards;
transition: animation 1000ms;
}
&:nth-child(3) {
animation: bouncing $anim-drt $anim-drt/2 alternate infinite
$anim-ease backwards;
transition: animation 1000ms;
}
}
}
.saving-exit-active {
div.saving-balls{
&__item {
background-color: $success-color;
transition: background-color 20ms;
transition: animation 1000ms;
}
}
}
div.saving-balls {
width: 3em;
height: 10vh;
z-index: 5;
display: flex;
justify-content: space-between;
align-items: center;
&__item {
width: 0.7em;
height: 0.7em;
border-radius: 50%;
background: $success-color;
}
}
}
My issue is the following:
Usually saving something only takes very short time; not enough time to actually run the animation once. My balls just become red for a split second and return being green (active and success color are some type or red and green). I would like to have the animation running a longer period of time, something around 2 seconds. I tried some hacks using effects, states and timeouts, but they didn't work well and I'd rather use a correct solution instead of some dirty hack.
I'm not very familiar with css transitions and animations, neither with react-transition-group. I hope for some existing easy way to play an animation for a certain minimum amount of time (if the connection is weak, the animation should show until the data is saved).
As an alternative, I accept different suggestions on how to tell the user that his input has been saved instead of an animation at the corner of the page. Currently, everything the user enters is saved, but he might not notice that this happened and search for a "save" button.
For anybody with a similar issue: I solved the issue by using useState and only changing the state value for saving if it indeed changed. I didn't use a transition group.
The working saving component:
const SavingIcon: React.SFC<SavingIconProps> = ({
className,
saving,
}) => {
const [ isSaving, setIsSaving ] = useState(false);
useEffect(() => {
if (isSaving !== saving) setIsSaving(saving);
}, [ saving ]);
return (
<div className={ classNames(className, "saving-icon", {
"saving-active": isSaving
}) }>
<div className="saving-balls">
<div className="saving-balls__item" />
<div className="saving-balls__item" />
<div className="saving-balls__item" />
</div>
</div>
);
}
scss:
#keyframes bouncing {
0% {
transform: translate3d(0, 10px, 0) scale(1.2, 0.85);
}
100% {
transform: translate3d(0, -20px, 0) scale(0.9, 1.1);
}
}
div.saving-icon {
position: fixed;
top: 86px;
right: 1.3vw;
$anim-drt: 0.4s; /* duration */
$anim-ease: cubic-bezier(.6, .05, .15, .95);
&.saving-active {
div.saving-balls {
div.saving-balls__item {
background-color: $active-color;
transition: background-color 20ms;
&:nth-child(1) {
animation: bouncing $anim-drt alternate infinite $anim-ease;
}
&:nth-child(2) {
animation: bouncing $anim-drt $anim-drt/4 alternate infinite
$anim-ease backwards;
}
&:nth-child(3) {
animation: bouncing $anim-drt $anim-drt/2 alternate infinite
$anim-ease backwards;
}
}
}
}
div.saving-balls {
width: 3em;
height: 30px;
z-index: 5;
display: flex;
justify-content: space-between;
align-items: center;
&__item {
width: 0.7em;
height: 0.7em;
border-radius: 50%;
background: $success-color;
}
}
}

ng-Animate: How to also animate sibling div?

I just got into CSS animations with ngAnimate. Cool stuff! I'm now struggling to figure out how to control the animation of a sibling element affected by some animation.
Plunker: https://plnkr.co/edit/XqpMPklO2SDlZQ1GIJ5Z?p=preview
For example, in the above plunker, the top div animates away nicely, but the bottom div doesn't. Is there a way to also animate the bottom div when the top is animated?
div.top {
width: 100%;
background-color: red;
height: 200px;
position: relative;
transition: 1s linear all;
opacity: 1;
top: 0;
}
div.bottom {
widows: 100%;
background-color: blue;
height: 300px;
}
button {
width: 100%;
padding: 25px;
}
div.top.ng-hide {
opacity: 0;
top: -1000px;
}
The problem has to do with the top div dissapearing suddenly. Make it transition to height: 0 and the bottom div will follow it's motion.
div.top.ng-hide {
/* ... */
height: 0;
}
Plnkr Fork

AngularJS 1.2 ng-show height animation

I'm trying to get a height animation working using Angular JS 1.2. I've got a plunker here that has the animation working for closing the item:
http://plnkr.co/edit/YVtnXgjO3Evb6tz5DJOp?p=preview
With the key bit being this CSS here:
.accordion-body {
height: 100px;
-webkit-transition: 0.5s linear all;
transition: 0.5s linear all;
}
.accordion-body.ng-hide-add,
.animate-show.ng-hide-remove {
display: block !important;
}
.accordion-body.ng-hide-add{
}
.accordion-body.ng-hide-remove{
}
.accordion-body.ng-hide {
height:0;
}
But I can't figure out how to get it to work for opening the item. I'm obviously doing something braindead - what am I missing?
Got it working with the following CSS:
.accordion-body {
height: 100px;
-webkit-transition: 0.5s linear all;
transition: 0.5s linear all;
}
.accordion-body.ng-hide-add,
.accordion-body.ng-hide-remove {
display: block !important;
height: 0px;
}
.accordion-body.ng-hide-remove.ng-hide-remove-active {
height: 100px;
}
.accordion-body.ng-hide-add{
height: 100px;
}
.accordion-body.ng-hide-add.ng-hide-add-active {
height: 0;
}
You messed up a class name is all.

ng-Animate doesn't remove add classes angular 1.2.x

I am trying to have an icon animate while loading and stop the animation once loading is complete. I was attempting this by activating a class based on a refreshing property. This worked in AngularJS 1.2.0-rc.3, but now (have tried 1.2.3 and 1.2.4) the animation never stops, and I believe the reason is that the -add classes that are added are not removed when the bound variable changes to false.
Here is the plunker demonstrating.
http://plnkr.co/edit/fbcCPxwZtcIoS0ZqrHhf?p=preview
Interesting that more toggles of the variable eventually do stop the animation. Is what I am trying to do valid, I suppose I could always just show hide a loading gif, but I liked the idea of animating the existing image
Thanks!
Curt
The problem is in your css.
You don't need '.icon-refresh-animate-add'.
Use this css class:
.icon-refresh-animate {
animation-name: rotateThis;
animation-duration: .5s;
animation-iteration-count: infinite;
animation-timing-function: linear;
-webkit-animation-name: rotateThis;
-moz-animation-name: rotateThis;
-webkit-animation-duration: .5s;
-moz-animation-duration: .5s;
-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-moz-animation-timing-function: linear;
}
It's a carbon copy of your animate-add.
Explanation: The ngClass is turning the .icon-refresh-animate class on and off. So when the state is true the class is applied and the animation loops forever. When the state is false the css class is removed so there will be no animation at all. So this bit of code does all the work for you
ng-class="{'icon-refresh-animate':refreshing}"
And here's the full CSS:
#keyframes rotateThis {
from {
transform: scale(1) rotate(0deg);
}
to {
transform: scale(1) rotate(360deg);
}
}
#-webkit-keyframes rotateThis {
from {
-webkit-transform: scale(1) rotate(0deg);
}
to {
-webkit-transform: scale(1) rotate(360deg);
}
}
.icon-refresh-animate {
animation-name: rotateThis;
animation-duration: .5s;
animation-iteration-count: infinite;
animation-timing-function: linear;
-webkit-animation-name: rotateThis;
-moz-animation-name: rotateThis;
-webkit-animation-duration: .5s;
-moz-animation-duration: .5s;
-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-moz-animation-timing-function: linear;
}

AngularJS 1.2 fade animation from 0 to 0.5 not working

So I have this simple fade animation using AngularJS 1.2 and the ngAnimate module but I'm having a small issue.
I want to show/hide an element with a fade animation but I want the element to fade from opacity: 0 to opacity: 0.5. The thing is, the element fades from 0 to 0.5 within the duration period I set, but after the animation ends, it sets the opacity to 1. I don't want that.
This is my CSS code:
.overlay {
background-color: #ff0000;
position: absolute;
width: 150px;
height: 150px;
}
.fade-animation.ng-hide-add, .fade-animation.ng-hide-remove {
transition: 2s linear all;
display: block !important;
}
.fade-animation.ng-hide-remove {
opacity: 0;
}
.fade-animation.ng-hide-remove.ng-hide-remove-active {
opacity: .5;
}
.fade-animation.ng-hide-add {
opacity: .5;
}
.fade-animation.ng-hide-add.ng-hide-add-active {
opacity: 0;
}
Here's a sample of the problem: http://jsfiddle.net/Kn3th/8/
I'm testing this on Firefox.
That's because as soon as the animation completes, the animation-related classes are removed, so only the .overlay definition applies. Just add this to your CSS:
.overlay {
...
opacity: .5; // <-- add this line to apply an opacity of 0.5
} when the animation is over
See, also, this short demo.

Resources