Last Div Flickering During jQuery Hover Animation - javascript

Here's my code: http://jsfiddle.net/ZspZT/
As you can see from the example, the fourth div block is flickering pretty badly, particularly on the hover-over effect, but also occasionally with the other divs as well.
Thanks in advance!

It appears that the easing function built into .animate is causing your percentage widths to add up to greater than 100%, causing the last sub-DIV to disappear. There are a few ways to solve this.
When I replace your percentage widths with fixed numerical widths, the problem vanishes. I used this in the code below (and your code had a LOT of redundancy to reduce):
$('document').ready(function() {
var speed = 450;
$('.four-ways-slide').hover(function() {
$(this).stop().animate({
width: 425
}, speed).siblings().stop().animate({
width: 25
}, speed);
}, function() {
$(this).siblings().andSelf().stop().animate({
width: 125
}, speed);
});
});
http://jsfiddle.net/mblase75/ZspZT/10/
Another possibility is to use percent widths that add up to 99% instead of 100%, and set a background color on the container DIV to hide the gap. Adding linear easing to the .animate method helps keep the total width from exceeding 100%:
$('document').ready(function() {
var speed = 450;
$('.four-ways-slide').hover(function() {
$(this).stop().animate({
width: '75%'
}, speed, 'linear').siblings().stop().animate({
width: '8%'
}, speed, 'linear');
}, function() {
$(this).siblings().andSelf().stop().animate({
width: '24.5%'
}, speed, 'linear');
});
});
#four-ways-slide-4,#four-ways-slider{background:#999999;}
http://jsfiddle.net/mblase75/ZspZT/9/

try using 'mouseenter' and 'mouseleave' rather than 'hover'. also you should assign variables rather than repeating divs
var one = $('#four-ways-slide-1');
var two = $('#four-ways-slide-2');
var three = $('#four-ways-slide-3');
var four = $('#four-ways-slide-4');
var all = $('.four-ways-slide');
thisIn = function(){
all.animate({width:'8%'},{duration: 450,queue:false});
};
thisOut = function(){
all.animate({width:'25%'},{duration: 450,queue:false});
};
one.mouseenter(function(){
thisIn();
$(this).animate({width:'76%'},{duration: 450,queue:false});
one.mouseleave(function(){
thisOut();
$(this).animate({width:'25%'},{duration: 450,queue:false});
});
});

Related

Scale an absolutely positioned div from center

I have a number of divs positioned absolutely on a background image.
On the page will also be some buttons. When those are clicked different variables will trigger, shrinking and growing these divs.
Here is the javascript I'm currently using...
$(document).ready(function() {
var title = 1;
$(".button1").click(function() {
title = 1;
});
$(".button2").click(function() {
title = 2;
});
$(document).click(function(e) {
console.log(title);
if (title==1){
$('.london').animate({ backgroundColor:'green', width:'50', height:'50' }, 300);
} else if (title==2){
$('.london').animate({ backgroundColor:'red', width:'40', height:'40' }, 300);
}
});
});
As they are absolutely positioned they are scaled from the corner they are positioned with.
see an example here.
What I need to do is shrink and grow these divs from their center point. The only solutions I've seen seem overly complicated.
I guess I could add a negative margin of half the divs width in the jQuery to counteract this? I'll try that if there are no better solutions
Thanks for any help.
bboybeatle, your "negative margin of half the divs width" idea is spot on, and not at all difficult to implement. Just include the required marginTop and marginLeft settings in the two animations.
$(function() {
var cssMap1a = {
backgroundColor: 'green'
};
var cssMap1b = {
width: 50,
height: 50,
marginTop: -10,
marginLeft: -10
};
var cssMap2a = {
backgroundColor: 'red'
};
var cssMap2b = {
width: 30,
height: 30,
marginTop: 0,
marginLeft: 0
};
$(".button1").click(function () {
$('.london').css(cssMap1a).animate(cssMap1b, 300);
});
$(".button2").click(function () {
$('.london').css(cssMap2a).animate(cssMap2b, 300);
});
});
And here's a fiddle. Fiddles are not difficult to set up. Hopefully this will help you next time you need to ask a question here.
As you will see :
"London" and the buttons are moved to a better position for demo purposes
The colour changes are separated out as separate css maps. They didn't work in the fiddle when included in the animation maps. jQuery needs a plugin to animate colours.
Thanks very much for that #Roamer-1888, I actually used some variables to make it slightly easier to apply the margin. I will remember that technique of putting multiple css properties in a variable..
Heres a snippet of my code I ended up using...
londonMargin = london/2 - london;
$('.london').animate({ width:london, height:london, marginLeft:londonMargin, marginBottom:londonMargin }, 300);
Just for fun I put together a little FIDDLE that has a function to which you pass an element name, the x and y coordinates of the center, and it will position the element in the larger element.
JS
var myelement = $('.boxdiv');
var myelement2 = $('.boxdiv2');
putmycenter( myelement, 90, 90 );
putmycenter( myelement2, 160, 280 );
function putmycenter (element, x, y)
{
var boxdivxcentre = element.width()/2;
var boxdivycentre = element.height()/2;
var boxdivposx = (x - boxdivxcentre);
var boxdivposy = (y - boxdivycentre);
element.css({
"top" : boxdivposy + 'px',
"left" : boxdivposx + 'px'
});
}

smooth button grow and button shrink animation on hover

I am trying to make a fairly simple animation; on mouse over, the button will animate to be bigger. When not hovering, it will return to it's original size. However, whenever when I try this sample code, it warps the button to odd sizes
$('.btn').hover(function() {
$(this).removeClass('btn-primary').addClass('btn-warning');
$(this).stop().animate({
'height': $(this).height() * 2,
'width': $(this).width() * 1.3
}, 300);
}, function() {
$(this).removeClass('btn-warning').addClass('btn-primary');
$(this).stop().animate({
height: $(this).height(),
width: $(this).width()
}, 300);
});
http://jsfiddle.net/RBLqY/1/
how could this problem be solved?
I'm not entirely sure why your code is failing, seems like you have some sort of calculation error when returning to the original size. After fiddling around a bit I found this solution. By animating the padding instead of the height and width you don't have to worry about the height width ratio when it comes to resizing the link.
$('.btn').hover(function() {
$(this).removeClass('btn-primary').addClass('btn-warning');
$(this).stop().animate({
padding: '12px'
}, 300);
}, function() {
$(this).removeClass('btn-warning').addClass('btn-primary');
$(this).stop().animate({
padding: '7px'
}, 300);
});
jsfiddle
Hope this helps.

Jquery animating width accordion style banner

I built this simple accordion style banner. Here's what it's supposed to do:
Grab <li> containing images from selected <ul>.
Divide them equally within the container (div.banner)
On 'mouseenter', add class .active to the hovered <li>
Shrink the other <li>s widths (half their original width).
Enlarge active <li> to new width (remainder after halving the others)
On 'mouseleave', all return to original widths.
Works fine until you swipe over multiple panes quickly. If you do, the last of the floated <li>'s break to the next line. It appears the total width of the panes is exceeding their container.
Rounding error while animating? Does it have something to do with animate's default 'swing' easing?
Fiddle: http://jsfiddle.net/UNFc4/
var banner = $('.banner');
var list_items = banner.find('li');
var banner_width = $(banner).width();
var num_of_images = $(banner).find('li').length;
var original_width = banner_width / num_of_images;
var half_width = (banner_width / num_of_images) / 2;
var init = function () {
$(list_items).css('width', original_width);
$(list_items).on('mouseenter', function () {
$(this).addClass('active');
doAnimation();
});
$(list_items).on('mouseleave', function () {
resetAnimation();
$(this).removeClass('active');
});
}
var doAnimation = function () {
$(list_items).not(".active").stop().animate({
width: half_width + "px"
}, 500);
$(".active").stop().animate({
width: (original_width + (half_width * (num_of_images - 1))) + "px"
}, 500);
}
var resetAnimation = function () {
$(list_items).stop().animate({
width: original_width + "px"
}, 500);
}
init();
I could fix it by changing this line, slowing the animation of the others, giving things time to equal out. But, I'd rather solve what's going on here, hopefully learning a bit more about how jQuery's animate() works.
$(list_items).not(".active").stop().animate({
width: half_width + "px"
}, 480); // changed 500 to 480
For those interested, I realized I only needed the reset on the banner area. Now it works, as described, without all the jitteriness and the subsequent layout mis-alignments.
New Fiddle: http://jsfiddle.net/UNFc4/1/
$(list_items).on('mouseenter', function () {
$(this).addClass('active');
doAnimation();
});
$(list_items).on('mouseleave', function () {
$(this).removeClass('active');
doAnimation();
});
$(banner).on('mouseleave', function () {
resetAnimation();
});

Slide boxes with margin-left check if overslided

I made a simple content/box slider which uses the following javascript:
$('#left').click(function () {
$('#videos').animate({
marginLeft: '-=800px'
}, 500);
});
$('#right').click(function () {
$('#videos').animate({
marginLeft: '+=800px'
}, 500);
});
Here is the demo: http://jsfiddle.net/tjset/2/
What I want to do and I can't figure out how to show and hide arrows(left and right box) as the all the boxes slided.
So I clicked 4 time to the LEFT and slided all the boxes! then hide "left" so that you can't give more -800px
What can I do?
What you can do is check after the animation completes to see if the margin-left property is smaller or larger than the bounds of the video <div>. If it is, depending on which navigation button was clicked, hide the appropriate navigation link.
Check out the code below:
$('#left').click(function () {
// reset the #right navigation button to show
$('#right').show();
$('#videos').animate({
marginLeft: '-=800px'
}, 500, 'linear', function(){
// grab the margin-left property
var mLeft = parseInt($('#videos').css('marginLeft'));
// store the width of the #video div
// invert the number since the margin left is a negative value
var videoWidth = $('#videos').width() * -1;
// if the left margin that is set is less than the videoWidth var,
// hide the #left navigation. Otherwise, keep it shown
if(mLeft < videoWidth){
$('#left').hide();
} else {
$('#left').show();
}
});
});
// do similar things if the right button is clicked
$('#right').click(function () {
$('#left').show();
$('#videos').animate({
marginLeft: '+=800px'
}, 500, 'linear', function(){
var mRight = parseInt($('#videos').css('marginLeft'));
if(mRight > 100){
$('#right').hide();
} else {
$('#right').show();
}
});
});
Check out the jsfiddle:
http://jsfiddle.net/dnVYW/1/
There are many jQuery plugins for this. First determine how many results there are, then determine how many you want visible, then use another variable to keep track with how many are hidden to the left and how many are hidden to the right. So...
var total = TOTAL_RESULTS;
var leftScrolled = 0;
var rightScrolled = total - 3; // minus 3, since you want 3 displayed at a time.
instead of using marginLeft I would wrap all of these inside of a wrapper and set the positions to absolute. Then animate using "left" property or "right". There's a lot of code required to do this, well not MUCH, but since there are many plugins, I think you'd be better off searching jquery.com for a plugin and look for examples on how to do this. marginLeft is just not the way to go, since it can cause many viewing problems depending on what version of browser you are using.

jQuery: animate to height of div

I have this function:
function fixedFeeSize(i){
var num1 = $('#num' + i);
if (num1.hasClass("extended")) {
num1.stop(true, true).animate({height: '59px'},500);
num1.removeClass("extended");
}else{
var height = 0;
num1.animate({height: '360px'},500);
num1.addClass("extended");
}
return null;
}
Which expands / contracts a div, however I am struggling to get it to expand to the height of the div as each div (there will be 10+) is going to be different heights.
I tried num1.animate({height: 'auto'},500); which has not worked.
Is this the effect you're after?
jQuery(".menu a").mouseenter(function(){
jQuery(this).stop().animate({
height: 200, opacity: 0.5
}, 1000, "linear");
});
jQuery(".menu a").mouseleave(function(){
jQuery(this).stop().animate({
height: 18, opacity: 1
}, 1000, "linear");
});
Here's a jsfiddle:
http://jsfiddle.net/kKAZx/1/
For further reading, take a look at the full documentation of the .animate function: http://api.jquery.com/animate/
You can combine effects to make all kinds of fantastic, standard-compliant effects.

Categories

Resources