Angular JS and Animate.css: fade animation is janky - javascript

I have a dialog in which I'd like to display one of two things depending on the state of a variable. So, I hooked up 2 versions of a form with ng-if.
When you click "delete" button on first state, it toggles to the second state.
I wanted to make it less abrupt, so I tried adding some css:
[ng-if].ng-enter {
animation: fadeIn .5s;
}
[ng-if].ng-leave {
animation: fadeOut .5s;
}
These animations come from the bower package "animate css":
#keyframes fadeIn {
0% {opacity: 0;}
100% {opacity: 1;}
}
.fadeIn {
animation-name: fadeIn;
}
However, as you can see in my animated GIF below, what happens is that for a second BOTH forms appear, making the dialog taller, then one fades out.
Is there no way to do a simple fadein/fadeout as in jQuery? I used to do this all the time with it, but trying to get nice UI animation in Angular is eluding me.

I had a similar problem with an Angular app and animations. I ended up having to use jquery - I wish I had a better answer - but it turned out beautifully. One note, though, I had to wrap any jquery I used in a noConflict() and use body on click plus the element because it doesn't exist yet in the DOM:
$.noConflict();jQuery( document ).ready(function( $ ) {
$('body').on('click', "#toggler", function(){
$('#div_to_show').slideDown();
});
});
I realize this a tangential answer and not an elegant solution but it worked for me to get it out the door under a tight deadline.

A clean solution is to change the state you use to check which form is to display when the animation ng-leave ends.
You can use a second variable to set the ng-leave class in the form that will be hidden.
I can't post you some code because i don't know your js and html.

Related

Tapping into fade events for Bootstrap 4

Many transitions in Bootstrap 4 provide a set of events to listen for. For example, you could do something like:
$('.certainDropdowns').on('hidden.bs.dropdown', function() {
// do the things
});
A light inspection of some of the components shows that somehow they are able to respond to fading. For example, the Bootstrap modal fires a "hidden" event once it has faded out. But this is at the modal level, not the transition level (hidden.bs.modal)
Unlike dropdowns and modals, there is not a "fade" JavaScript component. But the light scan of the source code seems to be indicating that Bootstrap provides emulation for CSS transitionEvent, and I'm trying to figure out how I can tap into it.
In brief:
Is there a Bootstrap 4-provided method for tapping into the fade transition's events, or am I limited to native transitionend (possibly with help from a 3rd-party polyfill)?
[edit to add content below]
I possibly should have tried transitionend before posting the question, but I just gave it a try and it seems to be no go like this:
<div id="something" class="fade show">Fadeable</div>
Then JS:
$('#something').on('transitionend', function() {
console.log('transition ended!');
});
//later
$('#something').removeClass('show');
This was tested only with the latest Firefox, which is one of my target browsers.
I couldn't find a way to do it in my intended way with the provided components. Instead, I ended up writing it as a single new class, "collapseFade" which could still use the Bootstrap pattern of adding/removing the class "show".
The tricky thing was that transitions would trample over each other if I just tried to add or remove the "show" class, so I had to add a second helper class, "out". This requires intimate understanding of the new classes, which was potentially hazardous to maintenance developers. Consequently, I wrote a jQuery plugin to go with it. Without using this answer as code repository, here's the lightweight breakdown:
SASS:
.collapseFade {
max-height: 400px;
transition:
max-height 0.5s,
opacity 0.5s 0.5s;
&:not(.show) {
opacity: 0;
max-height: 0;
}
}
.collapseFade.out {
transition:
max-height 0.5s 0.5s,
opacity 0.5s;
&:not(.show) {
opacity: 0;
max-height: 0;
}
}
(You could theoretically use Bootstrap's SASS fade variables instead of hard-coding time intervals).
Then the plug-in (code not included, for brevity) simply allows you to call collapseFade on an element. Eg. $('.something').collapseFade(). It optionally accepts "show" or "hide" as string parameters, but will just toggle by default. For whatever reason, transitionend is working here, so I also listen and fire an appropriate custom event for future maintenance or feature devs who might find it useful.
It functions thus: when showing, it removes the out class and adds the show class. When hiding, it adds the out class and then removes the show class.
The so-called "magic" is just in the timing. The second transition start is delayed by a value equal to the first transition time, which visually chains them together even though technically they are fired at the same time.
The other tricky bit is that the collapse animates max-height rather than height. This is the way Bootstrap themselves do it, and it makes sense... you can't animate "auto" height; it needs an actual target number. But straight-up "height" (no "max") means you're committed to occupying a certain amount of space. Max-height will allow height to be dynamic, but the trade-off is that it will operate smoothly only by restricting it as closely as possible. If I had put max-height of ten-thousand, for example, the collapsing animation wouldn't be smooth. You might notice that in Bootstrap's own collapse functionality, which is less than smooth for elements that are not tall. I don't anticipate my targets to be any taller than 400px so that's what I've provided.

Angular Ng-Animate - Smoother Transitions

Using ng-animate to provide some transitions when a user clicks into a tab.
Simply using
.ng-enter{
transition:0.50s;
opacity: 0;
}
.ng-enter-active{
opacity: 1;
}
which works a treat. However, the first time you click in it's somewhat sticky.
The view which is being transitioned into displays for a brief second before being transitioned into, so you see it twice almost. This only occurs on the first time round, on subsequent visits the transition works perfectly.
Is there a way then to make the animation smoother the first time round? The tabs are being displayed using a div with ng-include.
You have to target the animation on the tab elements, like this :
.tab.ng-enter {
transition:0.5s linear all;
opacity:1;
}
.tab.ng-enter.ng-enter-active {
opacity:0;
}
ngAnimate (like ngLeave, ngEnter, etc...) classes will be added to each element appearing/disappearing in the view, so in your case, it is needed to restrain your animation to only one element.
You can see the documentation too.

Assigning classes to a slide within a basic css slider

Basically I have a really simple (makes a change) slider that is done with css only. There are labels for the nav buttons and they are unique for each slide. Question is , How can I add/remove classes to certain items within the slide ONLY WHEN the slide is navigated to.
As with sliders they tend to load everything when the slider loads and I want to add cool animations to the bits on the slides so makes it pointless if everything loads at slide one.
jsfiddle http://jsfiddle.net/greggy_coding/013481b9/3/
I have provided some jsfiddle mock up of the slider and the classes animated and fade which are the ones in this instance i want to add and remove on the specific slide loading .. I will then assign them to different bits on the slide...
.animated {
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
.fadeInUpBig {
-webkit-animation-name: fadeInUpBig;
animation-name: fadeInUpBig;
opacity: 0.3;
background-color: rgba(0,0,0,0.3);
}
CSS allows you to create animations with transitions and keyframes that once were only possible with JavaScript or Flash. Unfortunately, with CSS there’s no way to perform a callback when an animation is complete. With JavaScript, it’s possible to detect the end of a CSS transition or animation and then trigger a function.
Using JavaScript, we can detect the transitionend event; however for cross-browser, support we need to include the other browsers’ prefixes.
$(function() {
//Store a ref to slides
var $slides = $(".slides");
//Bind event to the contianed that gets animated
$(".slide-container")
.on("transitionend webkitTransitionEnd oTransitionEnd msTransitionEnd", function(e){
// Remove classes from all the elements within the active container that starts with the class 'add-anim'
$slides.find(".slide-container [class^='add-anim']").removeClass("animated bounceInLeft bounceInUp");
//Add appropriate classes to the matched elements within the active container
var $radio = $slides.find(":radio[name='radio-btn']:checked");
$radio.next(".slide-container").find(".add-anim-up").addClass("animated bounceInUp");
$radio.next(".slide-container").find(".add-anim-left").addClass("animated bounceInLeft");
});
});
Here is your entire code with HTML+JS+CSS.
Note: The above solution works, but the problem is, depending on the browser, it can fire twice (i.e. Chrome supports both webkitTransitionEnd and transitionend). There are ways to overcome this though, by detecting the supported event property. Take a look at this demo for more details.
Hope that helps.

jquery-ui switchClass() not working as expected

I'm having trouble getting the switchClass function to fade nicely like it does in the example on the jquery site. Basically the timing doesn't seem to have any effect, I've tried from 40000-4 but makes no difference.
I've posted a fiddle below (which explains better) but here's the code I'm using. There's two divs which are meant to switch class so the background image is different. I'm using different methods for each div but they both give exactly the same result even though one uses switchClass the other uses addClass.
$(document).ready(function() {
$('.iamatrainer').hover(function(){
$(this).switchClass('iamatrainer', 'iamatrainerhover', 400, 'easeInOutQuad');
}, function(){
$(this).switchClass('iamatrainerhover', 'iamatrainer', 400, 'easeInOutQuad');
});
$('.iusetrainer').hover(function(){
$(this).addClass('iusetrainerhover', 400);
}, function(){
$(this).removeClass('iusetrainerhover', 400);
});
});
http://jsfiddle.net/KJbA8/
Can anyone help me out?
Are you sure you have jQueryUI loaded? The switchClass method isn't a part of jQuery. Your fiddle is throwing JS Console errors about it.
You don't really need JS for this. Just setting the :hover on the .iamatrainer and .iusetrainer elements works fine. http://jsfiddle.net/y3ALr/3/
Also, if you must use a background image...
Make sure you're using some reasonably accessible image replacement technique
Consider using sprites and :hover offsets so you don't get that nasty delay.
You can use :hover pseudo-selector and css transitions
CSS:
.iamatrainer{
background:url(http://renegadeox.com/iamatrainer.png);
height:70px;
width:512px;
transition: background 0.3s linear;
}
.iamatrainer:hover{
background:url(http://renegadeox.com/iamatrainerhover.png);
height:70px;
width:512px;
transition: background 0.3s linear;
}
Here is your updated Demo.
Also, you'd better merge images in one and use background-position for :hover state

Page to page fading effect

i need to implement load/unload page animations fade-in on load, and fade-out on unload.
1) I have read some articles about implementation it based on links clicks. That's does not work for me. I don't want to go that way, because some links should not open new page actually, and have href.
So imagine: link has properly href, but sometimes it open new page, sometimes not, based on it handler behavior. We add another handler that fire redirect all the time as timeout callback.
2) I can't implement animation using page unload event. I think it's right way.
Please help or advice something. Thank You!
Give your links you want to animate a class. Then you can use the .click() method to check when a link is clicked. Then do a preventDefault to stop the default behavior.
The next thing to do is check if there is "http" in the href attribute. You can get the value with $(this).attr('href');. If the link contains this, you need to go to a new page. For this, use window.location.href. Call this method as the callback of your fadeOut().
The only thing that is left is do a fade in when the page loads ;)
Actually i was finding the way without using links event, but using any UNLOAD event. Links events can be used only on a small website. In my case it created additional errors. For example some links, shouldn't do fade-out, and i don't know which of them actually.
So i don't recommend to do this. Need to find any UNLOAD page redirections animation way.
I'm not sure if I understand your question correctly..
Put this code in the pages' <head>s.
<style>
#keyframes page_transition
{
from {opacity: 0;}
to {opacity: 1;}
}
#-webkit-keyframes page_transition
{
from {opacity: 0;}
to {opacity: 1;}
}
html
{
animation: page_transition 1s ease-in-out;
-webkit-animation: page_transition 1s ease-in-out;
}
html.unloading
{
transition: opacity 500ms linear !important;
opacity: 0 !important;
}
</style>
<script>
window.addEventListener("beforeunload", function() {
document.documentElement.classList.add("unloading");
});
</script>

Categories