Jquery animate - callback executing before animation is complete - javascript

What I'd like to accomplish is for the element to expand in height, and then apply a background image once the height change is complete. I've noticed that the background image in the callback applies before the height animation is complete resulting in laggy performance. Can anyone tell me why this is?
$(document).ready(function() {
$('#hero').animate({
height: ($(window).height() - $("#hero").offset().top - 50)
}, 100, function() {
$('#hero').css('background-image', 'url(./img/hero.jpg)');
});
});

You have a transition: all 1s ease on #hero, which will cause the animation to play erratically since you are trying to use css3 animations to animate the jQuery animation (and throw all kinds of timing problems).
What I suspect is happening is that you are getting notified that the jQuery animation completed, but the css3 animation doesn't complete for an additional 1s, which is why you are seeing what you are.

Related

CSS transition speed change based on mouse position

I have a div element whose width is determined by the users mouse position inside a defined area. Upon entering this area the transition should be smooth, until the width has catched up to the current mouse position and smooth again when leaving the area and the width goes back to normal. In the time between the transition should be fast, so the width is responsive to the mouse position.
Html
<div class="widthChanging"></div>
<div class="HoverA"></div>
CSS
.widthChanging {
transition: width 300ms cubic-bezier(.45,.1,.14,.61);
}
.HoverA:hover + .widthChanging {
width: calc(0.001 / var(--mouse-x, 0) * 100vw);
transition: width 0s;
}
I get the mouse position using Javascript.
When leaving the "HoverA" area the width returns smoothly, because the transition speed defined in "widthChanging" takes over. Sadly I cant (I think) do the same for entering the "HoverA" area. My only idea would be waiting the transition time before assigning a class with the slower transition time, but this seems like a bad solution to me and would also require more Javascript.
I hope you have some more elegant ideas than me :)
I solved the problem by waiting and then assigning a class with the new transition speed using javascript. I dont think that this is the best way to do it.
Here the codepen https://codepen.io/Teiem/pen/EReJPx
html
<div class="HoverA" onmouseover="SpeedEnter2()" onclick="SpeedEnter2()"onmouseout="SpeedLeave2()"></div>
Javascript
function SpeedEnter2() {
goVar = setTimeout(function(){
document.getElementById("SpeedId2").classList.add('Fast');
}, 300);
Css
.Fast {
transition: width 0s !important;
}

Change Height of Navbar on Scroll Jquery with Bootstrap3

Hello i have a problem with my navbar.
I want to animate it on scroll and change his height. When i scroll a bit down it should animate smaller and when im at the top of the page it should aniamte bigger. The standard height is 100px. The problem is when im at the top of the page it takes a delay, which i need to wait, until it animates. They delays gets longer if i scroll first to the bottom of the page and then back to the top. The has a height of 11000px. This is my code for it:
$(document).on("scroll",function(){
if($(document).scrollTop()>500)
{
$( ".navbar" ).animate({height: 50} ,{duration:100});
}
else if($(document).scrollTop()==0)
{
alert("dhsihsp");
$( ".navbar" ).animate({height: 100} ,{duration:100});
}
});
Maybe u can help me. I use Google Chrome and Bootstrap 3.
The problem you are having is that the "scroll" fires every single time the scrollbar moves. So every single time the scrollbar moves a pixel, it will do the IF checks. That's why you delay your animation for so long. The queue of things to run stacks up immensely if you move the scrollbar too much.
DEMO
The scroll event seems to fire a lot when you scroll so all the events get queued. So the event that actually changes you header seems to take a long time to appear.
I added a css transition on the height of a .navbar. for making this happen almost instantly. Are the events not still there? True, but changing css is a lot less demanding then adding animations (with a duration of 100ms). The transition does have a duration but it does not have to finish so an other event can come in at any time.
CSS
.navbar {
transition: height 0.1s;
}
Jquery
$(window).scroll(function () {
var scrollh = $(this).scrollTop();
if (scrollh == 0) {
$(".navbar").css({
'height':'100px',
});
} else {
$(".navbar").css({
'height':'50px',
});
}
});

Apple-like website section-by-section scrolling behavior

I'm trying to figure out how to make the main visible content area expand to the height of the browser-- it's responsive in a sense. If you extend the browser, more of the content shows. If you scroll down, it scrolls to the next div and repeats the behavior.
I have no idea what this behavior is called or referred to as, so I'm not sure I can give an accurate title.
My guess is that this is done with Javascript, but I'm not well-versed in the language by any means. Can someone help me out here?
Examples:
http://theartofraw.g-star.com &
http://www.apple.com/iphone-5s/
I've done this with Jquery. Basically you get the height of the window and then set the height of each slide to that value.
var origheight = $(".slide").height();
var height = $(window).height();
if (height > origheight) {
$(".slide").height(height);
}
http://jsfiddle.net/uYXvF/
They have sections, that are CSS "height: 100%";
Then they detect scrolling and, do a CSS3 Transform with CSS3 Transition:
Transform: Y: 0%
Scrolling Detected
Transform: Y: 100%
So they are basically preventing actual scrolling and instead move the whole content by 100%.
Edit (2):
In this post they show how to disable scrolling:
How to disable scrolling temporarily?
function wheel(e) {
preventDefault(e);
document.getElementById("mainContainer").style.webkitTransition = "-webkit-transform 1s";
document.getElementById("mainContainer").style.webkitTransform = "translateY(-100%)";
}
This is a simplified version from what i use on my own page.
If you want to accomplish the same as in the example sites you posted, then you could make use of a jQuery plugin called fullPage.js.

Smoothly change CSS animation mid-animation

I'm trying to transition smoothly from one half-completed CSS animation to the next one and I can't find a way to do it without a slight stutter. I have an infinite animation at very high speed that should gently slow down to a stop on click. Right now, I'm always getting a slight hickup while switching animations, likely partially because I need to wait for the next requestAnimationFrame before starting the next animation. Are there other options? Here's approximately what I'm doing:
function onClick(){
// get current location of element
var content = $(".content");
var currentOffset = $(content[0]).css("top");
// set property to stop jumping back to the beginning of current animation
content.css({ top: currentOffset });
// stop the current animation
content.removeClass("anim-infinite");
// update content based on current location
// updateContent(currentOffset);
// setup ease-out animation
window.requestAnimationFrame(function() {
content.addClass("anim-ease-out");
content.css({ top: parseFloat(currentOffset) + 50 });
});
}
And here's the relevant CSS.
#keyframes "spin" {
from { top: 0 };
to { top: -200%; }
}
.anim-infinite{
animation: spin 1s linear infinite;
}
.anim-ease-out{
transition: all 0.25s ease-out;
}
The distances and timespans are reasonable to maintain constant speed between the two animations and I'm using the relevant browser prefixes.
I get the same stutter when I use a "linear" timing function for the second animation. I tried setting an animation-fill-mode:both, without success. It appears to only affect animations that complete.
The stutter gets worse when I try to update the content based on the location of the content - which is dependent on when the animation gets stopped.
While trying to work out a jsFiddle that demos the problem, I found the source of most of the stutter. Anything that happens between removing the anim-infinite class and in the requestAnimationFrame can have a big perf impact, especially if it modifies the DOM in the content and causes the content to reflow. That's obvious in retrospect but the minor DOM updates had a bigger impact than expected.
I still have a slight occasional stutter but it's "good enough" for now.
For reference, here's the fiddle.

How to stop or delay flexslider animation using the before() callback?

I'm adding a class .animate-out on all the elements of the slides before flexslider animates to the next slide, the issue is that the css animation applied won't show because flexslider moves to the next slide immediately.
I'm adding the class using flexslider's before() callback function which is called inside the function that animates the slider, so it's too late to use slider.pause() to pause the slider (using it will pause the next slide).
I already tested the animations using alert() inside the before() callback function which pauses the javascript execution and I can see the css animations added by .animate-out.
is there a way to stop the slider from animating (I will use slide.flexAnimate() later to animate manually) ? and if not is there a way to delay the slide ? Here's the code on Github.
Currently the only way to delay the animation to show the css animations is using .delay() on the current slide and the one we're animating to:
before: function(slider) {
// TODO: check if the browser supports css animations before delaying the slides
// delay slide fadeOut to show the css animations
slider.slides.eq(slider.currentSlide).delay(1000);
// delay slide fadeIn until the animations on the prev slide are over
slider.slides.eq(slider.animatingTo).delay(1000);
}
To know why I used this code you can check the slider code for fade animation which is:
if (!touch) {
slider.slides.eq(slider.currentSlide).fadeOut(vars.animationSpeed, vars.easing);
slider.slides.eq(target).fadeIn(vars.animationSpeed, vars.easing, slider.wrapup);
}
I'm using as my slider options:
animation: 'fade',
animationSpeed: 0;
I hope this helps someone.
There is another way to get the desired effect without the need to pause the slider. This also works with animation set to "slide".
For this example we assume the duration of each of the transitions is 500ms. Adept the paramters to your transition speed accordingly.
First we set a transition delay on the slides container (which is animated by flexslider via CSS3 as well):
.flexslider .slides {
transition-delay: 0.5s;
-webkit-transition-delay: 0.5s
}
The trick is not to use the '.flex-active-slide' class provided by flexslider to build the transitions upon, but to use our own transition class by simply applying that class to the slide elements via flexsliders' callbacks:
start: function(slider) {
slider.slides.eq(slider.currentSlide).addClass('flex-active-transition');
},
before: function(slider) {
slider.slides.eq(slider.currentSlide).removeClass('flex-active-transition');
},
after: function(slider) {
setTimeout(function() {
slider.slides.eq(slider.currentSlide).addClass('flex-active-transition');
}, 700);
}
This will add the transition class '.flex-active-transition' with a delay after the sliding has taken place AND the fade-out transitions have been animated and remove the class before the beginning of every slide. We can use this class for all our CSS3 transitions now.
Since sliding itself is already delayed by our CSS declaration, the slide-out transitions will now perform before the slider slides. We can set the timeout in the "after" callback to the duration of our fade-out + our slide speed, and the fade-in transitions triggered by the custom transition class will be performed just after the sliding has completed.
To get smoother animations, try shorten the setTimeout delay. This will blend sliding and slide transition animations, which may result in some nice slide effects.

Categories