I have found this script and would be great but if I scroll to the top all browsers wait around 10 secs to animate back.
This script animate if you scroll down or up. Down way works fine bet the up way does not.
I do not know what can be the problem. I tried to leave only one animation but the same result.
Thanks
$(function () {
var iScrollPos = 0;
var header = $('header');
var li = $('.headerRight nav ul li');
var logo = $('h2');
$(window).scroll(function () {
var iCurScrollPos = $(this).scrollTop();
if (iCurScrollPos > iScrollPos) {
header.animate({
top: '-3.5em'
}, 250);
li.animate({
padding: '0'
}, 250);
logo.animate({
fontSize: '1.5em'
}, 250);
}
else {
header.animate({
top: '0em'
}, 250);
li.animate({
padding: '1em'
}, 250);
logo.animate({
fontSize: '2em'
}, 250);
}
});
});
You are probably experiencing an effect caused by the animation queue filling up with animate requests. Each animation has to complete on the elements before the next can fire. What you want to do is stop any animations in play when you need to fire off the next.
Without your UI I can't fully tell what you are seeing but I am imagining something like this to resolve. Note the shorthand to stop all at once
all = header.add(li).add(logo);
and in the conditions:
all.stop(true, false); // stops where it is
Also, I added a class to the items so it only animates if they have not already been animated to the position.
$(function () {
var iScrollPos = 10;
var header = $('header');
var li = $('.headerRight nav ul li');
var logo = $('h2');
$(window).scroll(function () {
var iCurScrollPos = $(this).scrollTop();
var all = header.add(li).add(logo);
if (iCurScrollPos > iScrollPos && !all.hasClass('up')) {
all.stop(true, false);
header.animate({
top: '-3.5em'
}, 250);
li.animate({
padding: '0'
}, 250);
logo.animate({
fontSize: '.5em'
}, 250);
all.addClass('up');
}
else if (iCurScrollPos <= iScrollPos && all.hasClass('up')) {
all.stop(true, false);
header.animate({
top: '0em'
}, 250);
li.animate({
padding: '1em'
}, 250);
logo.animate({
fontSize: '2em'
}, 250);
all.removeClass('up');
}
});
});
A fiddle of something at least to see it: http://jsfiddle.net/3d4pmvky/
Related
Is there a way to have the div called #middlecta stop scrolling when it reaches #footer?
FIDDLE:
http://jsfiddle.net/BP6rq/1522/
var pointOne = $("#form").offset().top;
$(window).on("scroll", function () {
$.fx.speeds.xslow = 750;
if ($(this).scrollTop() > pointOne) {
$("#middlecta").fadeIn('xslow').addClass('fixed');
} else {
$("#middlecta").fadeOut('xslow').removeClass('fixed').hide();
}
$("#middlecta-t").addClass("mob");
});
You definitely want to play around with the CSS. Setting a 100px margin may or may not be a good idea. But, this should get you thinking on the right track at least.
var pointOne = $("#form").offset().top;
var pointTwo = $('#footer').position().top;
var $midCta = $("#middlecta");
$(window).on("scroll", function () {
$.fx.speeds.xslow = 750;
if ($(this).scrollTop() > pointOne) {
$midCta.fadeIn('xslow').addClass('fixed');
} else {
$midCta.fadeOut('xslow').removeClass('fixed').hide();
}
if ($midCta.offset().top > pointTwo) {
$midCta.css('bottom', 150);
$midCta.fadeOut('xslow').removeClass('fixed');
}
$midCta.addClass("mob");
});
http://jsfiddle.net/BP6rq/1523/
I am having a view problems with animating a background to give the impression that a window is opening, I have the animation actually animating but it just animates like the images are in sequence. What I am wanting is to give the impression of a movie or animated gif.
You can see my current attempt here,
http://jsfiddle.net/8nj4934w/
I have so far done the following javascript,
$('a').bind('mouseenter', function() {
var self = $(this);
this.iid = setInterval(function() {
self.animate({ 'background-position-y': '-=500px' });
}, 300);
}).bind('mouseleave', function(){
this.iid && clearInterval(this.iid);
});
and the kind of effect I am going for here,
http://www.jeld-wen.com/catalog/exterior-doors
just hover of a door image.
Update (for jQuery solution handling two way sliding)
function slide(that, increment, limit){
var self = $(that);
that.iid && clearInterval( that.iid );
that.pos = that.pos || 0;
return setInterval(function () {
that.pos = that.pos += increment;
if (that.pos === limit){
clearInterval(that.iid);
} else {
self.css({
'background-position': '0 '+ that.pos + 'px'
});
}
}, 50);
}
$('a').bind('mouseenter', function () {
this.iid = slide( this, -500, -11500 );
}).bind('mouseleave', function () {
this.iid = slide(this, 500, 0);
});
Demo at http://jsfiddle.net/g8cypadx/
Original answer
I would suggest that you use CSS transitions with steps.
a {
background-image: url('https://dl.dropboxusercontent.com/u/58586640/9100_FRONT_STRIP.png');
background-repeat: no-repeat;
height: 500px;
width: 500px;
display: block;
background-position: 0 0;
transition: background-position 1s steps(23);
}
a:hover {
background-position: 0 -11500px; /* number of steps times the height */
}
If you have to do it through jQuery then you should animate both properties but with 0 duration for the animation, and small delay for the interval
$('a').bind('mouseenter', function () {
var self = $(this);
this.iid = setInterval(function () {
self.animate({
'background-position': '-=0 -=500px'
}, 0);
}, 50);
}).bind('mouseleave', function () {
this.iid && clearInterval(this.iid);
});
Demo at http://jsfiddle.net/8nj4934w/2/
(the problem with this solution is that it will not stop at the end)
I want to set up a menu bar like you see her in JSfiddle:
http://jsfiddle.net/gvjeyywa/21/
There it works exactly the way I want it to … But on the webpage it has a bug, I think it's because of the elastic scrolling in OSX … On scrolling down the menu bar should slide in from the top to set up on top:0px, being fixed there… But if you scroll back to top and the elastic scrolling scrolls higher than the body is… the menu jumps too high…
Here see the live example:
http://www.cyrill-kuhlmann.de/index.php/projects
on iOS it's a complete mess too…
Here is the JS Code:
var bitFlag = false;
var isActive = true;
var lastScrollTop = 0;
var timeoutId;
$navigation = $("#navigation");
$(window).scroll(function (event) {
var intWindowTop = $(window).scrollTop();
var intElementBottom = $navigation.offset().top + $navigation.height();
if (intWindowTop > lastScrollTop) {
isActive = true;
if (!bitFlag) {
$navigation.css("position", "absolute").css("top", intWindowTop + "px");
bitFlag = true;
}
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(function () {
if (intWindowTop > intElementBottom) {
intDelayTime = setTimeout(function () {
if (isActive) {
$navigation.animate({ top: intWindowTop + "px" }, {
duration: 800,
step: function () {
if ($(window).scrollTop() < $navigation.offset().top) {
$(this).stop(true,true);
}
},
complete: function () {
intDelayTime2 = setTimeout(function () {
$("#navigation").css("position", "fixed").css("top", "0px");
bitFlag = false;
isActive = false;
}, 1);
}
});
}
}, 500);
}
}, 100);
} else {
$navigation.css("position", "fixed").css("top", "0px");
bitFlag = false;
isActive = false;
}
lastScrollTop = intWindowTop;
});
And this is the CSS:
#navigation {
position:absolute;
top: 0px;
left: 0px;
right: 0px;
height: 80px;
background-color: #FFF;
z-index:999;
padding-top: 25px;
padding-left: 45px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
Does someone have an idea? Unfortunately I'am a bloody starter in JS… I am thankful for any help…
problem is this: intWindowTop > lastScrollTop.
this value is true, when you scroll into the negative area, that comes with webkit.
so you have to check, if the value is positive via intWindowTop > 0
$(window).scroll(function () {
var intWindowTop = $(window).scrollTop();
var intElementBottom = $navigation.offset().top + $navigation.height();
if ( intWindowTop > lastScrollTop && intWindowTop > 0 ) {
//...
} else {
//...
}
note that i removed the variable "event" as well. you dont use it, so why declare it..?
Hey so i was trying to get my navigation to animate down after a certain div has passed but its not working properly. not sure why. it works when sliding down although a bit buggy(sometimes there seems to be a delay before it slides down and other times it slides down properly immediately). It also does not slide up it justs removes it self.
what am i doing wrong?
here is my code:
$(window).scroll(function () {
targetScroll = $('#scroll_verder').position().top,
currentScroll = $('html').scrollTop() || $('body').scrollTop();
if(currentScroll>=targetScroll){
$('.navbar').addClass('show-menu').animate({ top: '0px' });
}
else {
$('.navbar').stop();
$('.navbar').removeClass('show-menu');
$('.navbar').animate({ top: '-50px' });
}
});
Had a look at your code on the link you posted. This should do the trick:
var reachedTarget = false; // Prevent animation collisions with this
var targetScroll = $('#scroll_verder').position().top;
$(window).scroll(function () {
var currentScroll = $('html').scrollTop() || $('body').scrollTop();
if ( currentScroll >= targetScroll ) {
if ( !reachedTarget ) {
$('.navbar').stop();
$('.navbar').addClass('show-menu').animate({ top: '0px' });
}
reachedTarget = true;
} else{
if ( reachedTarget ) {
$('.navbar').stop();
$('.navbar').removeClass('show-menu').animate({ top: '-50px' });
}
reachedTarget = false;
}
});
EDIT: In CSS (to make sure initial position is correct):
.navbar.show-menu {
z-index: 999;
display: block;
top : -50px;
}
In my game I have a grid populated with words. To spell the words the user has to click on the letters on the side called "drag". When a letter is clicked it animates into position on the grid.
The problem I am having is that the user can click letters rapidly, which crashes the program. To solve this I want to disable the click events until the animation completes.
In the past I have used a setTimeOut function before but it is not a reliable method as the timing all depends on browser speeds.
Here is the click event:
$('.drag').on('click', function (e) {
e.preventDefault();
var target = $('.highlight-problem .drop-box:not(.occupied):first');
var targetPos = target.parents('td').position();
console.log(targetPos);
var currentPos = $(this).offset();
var b = $(this);
if (target.length) {
target.addClass("occupied");
$(".occupied").parent(".flip-wrapper").addClass("flipped");
var clonedObject = b.clone()
if (b.data("letter") == target.parents('td').data("letter")) {
clonedObject.addClass("right-letter");
target.addClass('right-letter');
setTimeout(function () {
hitSound.play();
}, 550);
} else {
clonedObject.addClass("wrong-letter");
target.addClass('wrong-letter');
setTimeout(function () {
missSound.play();
}, 550);
}
clonedObject.appendTo("table").css({
position: "absolute",
top: currentPos.top,
left: currentPos.left
}).stop().animate({
top: targetPos.top,
left: targetPos.left
}, "slow", function () {
$(this).prop('disabled', false).css({
top: 0,
left: 0
}).appendTo(target);
var spellWord = $('.highlight-problem .drop-box');
if (!spellWord.filter(':not(.occupied)').length) {
var wordIsCorrect = 0;
spellWord.each(function () {
if ($(this).parents('td').data("letter") == $(this).find("div").data("letter")) {
console.log('letter is: ' + $(this).find("div").data("letter"))
wordIsCorrect++;
}
});
You can do it in simple 3 steps.
Declare a global variable called animationComplete and set it to false.
var animationComplete = false;
In your .animate({...}); function, toggle the value after the animation is complete.
.animate({
top: targetPos.top,
left: targetPos.left
}, "slow", function () {
...
animationComplete = true;
});
Check for the completeness using the global variable.
if (animationComplete)
{
// Do something!
}
Full Code
JavaScript
animationComplete = true;
$(document).ready(function(){
animationComplete = false;
$(".background").animate({
height: 50,
width: 50
}, 10000, function(){
animationComplete = true;
});
$("button").click(function(){
if (animationComplete)
$(".background").animate({
height: 200,
width: 200
}, 10000, function(){
animationComplete = false;
});
else
alert("Please wait till the animation is complete!");
});
});
HTML
<div class="background"></div>
<button>Click me!</button>
CSS
.background {background: red;}
Fiddle: http://jsfiddle.net/KAryP/
Fiddle for your code here: http://jsfiddle.net/smilburn/Dxxmh/94/
Can't test code atm, but checking if the element is not animated within click function should do
if(!$('selector:animated')){
}