flickering jquery animations - javascript

Hey guys I'm in the process of making this website here: http://craigmarkdrums.com (bare in mind that it's still very early days, so no judging, yeh hehe) and take a look at the menu. In firefox it works fine, but in chrome and safari you can see a flickering in the right hand corner. i think what is happenning is it's the box changing size. they are all li's in a ul. here is my jquery:
$(function()
{
$('#nav li').hover(function()
{
$(this).children().stop(true, true).fadeIn();
$(this).stop().animate({
width: '90px'
}, 300, 'swing');
$(this).siblings().stop().animate({
width: '42px'
}, 300, 'swing');
}, function()
{
$(this).children().stop(true, true).fadeOut();
$(this).stop().animate({
width: '50px'
}, 200);
$(this).siblings().stop().animate({
width: '50px'
}, 200);
});
});
any ideas what i'm doing wrong, or how i could improve this code?
cheers
Matt

You're intuition is correct. To accomplish this effect using floats, you'd need to handle the animation yourself and resize all LIs in a single step, making sure the sum of their widths matched the containing element. Or try using absolute positioning and handling the offsets yourself.
.. Or you could cheat and put the whole thing inside a container div whose background was the photo your using. That way any bleed through would be of the photo, not the white background.

I'd suggest moving over to a flexible box layout for this (CSS3). You can just increase the size of the box you want and the others will shrink away by themselves.
This page has a lot of examples of the flex-box layout (Take a look at the second example)
Add this css to your menu panels:
-moz-box-flex: 1;
-webkit-box-flex: 1;
box-flex: 1;
And then set the width of the hovered element. For added fluidity, try adding some slight transition delays like this (I've separated the values for easy reading and understanding):
-moz-transition-property: width;
-moz-transition-duration: 0.2s;
-moz-transition-easing: ease-in-out;
-webkit-transition-property: width;
-webkit-transition-duration: 0.2s;
-webkit-transition-easing: ease-in-out;
transition-property: width;
transition-duration: 0.2s;
transition-easing: ease-in-out;

Related

jQuery - grow div from center to animate in

Alright I have these divs that I have been animating in/out previously by doing hide() or show(), however that does not look clean and Id like to have them grow out from the center, i.e. grow from width of nothing to their current width.
I am new to jquery animations and don't know how to do this properly. I have tried setting the initial width to 0 and doing:
function panelIn(labDiv) {
var neww = "700px";
$(labDiv).animate({
width: neww
}, 2000);
}
But that grows the div to the right. How can I achieve this? Are there any good ;libraries for animating in divs, i.e. introducing them on the page?
Depending on what you're doing, you might want to just use CSS and .toggleClass().
CSS
#labDiv{
height:700px;
width:700px;
transform:scale(0);
transform-origin:center center;
transition: transform 2000ms ease;
}
#labDiv.show{
transform:scale(1);
}
jQuery
function panelIn(labDiv){
labDiv.toggleClass('show');
}

How to prevent transition to run on page load after height is set with javascript in Safari?

I have a div on a page with liquid height that i want to animate with CSS transitions to collapse/expand.
I set the default height of the div using JS, so if i change the height with CSS, it can easily revert back to the original state. Works fine, the issue is that the height animation will run on page load in Safari. (works fine in Chrome) Any idea how to fix this?
CSS:
div {
background: red;
transition: all 1s cubic-bezier(0.77, 0, 0.175, 1) 0s;
overflow: hidden;
}
div.hide {
height:10px !important;
}
JS:
$div = $('div');
$div.height($div.height());
$div.click(function(){
$div.toggleClass('hide');
});
Demo:
https://jsfiddle.net/69taau5m/1/
It might be a little hacky but you could always apply the transition to your div on click as well.
Did this pretty quick but it works. Check out the fiddle. Could always add some logic to only apply css on the first click.

how to achieve *SMOOTH* fade in and out animation on mobile with jquery and css3?

I know that I can fade in and out with jquery, but on mobile it will be jittery and like low fps or something. After a lot of searching I've found out I can use css3 transition to go to opacitiy 0, but the problem is the element will still have the place to itself. even with visibility:none, it will keep the space it was in. the only way is to use display:none but as I know I can't animate that.
So is there a way to achieve smooth fade in and out animation on mobile with a combination of jquery and css3? or even just one? Thank you.
**EDIT**: Okay the answer for fadeout is working pretty well, now a fade in would be sweet. the problem is I think I have to pul a millisecond delay after ('#id').css('display','block') and before ('#id').css('opactity','1'). don't if it is efficient and all. but it works that way but all my other animations wouldn't work. still am really confused.
You should always try and use CSS3 transitions, instead of jQuery animations. Here I use a CSS3 transition to fade out the .square, and then I wait until the transition has ended to set the display to none.
If you animate an element in jQuery, for example, using fadeOut, you'll see what happens. It basically sets the opacity to 1, and then brings that value down to 0 in tiny increments. This is very inefficient. So it's better to always use CSS3 transitions and animations wherever possible.
Fade out: https://jsfiddle.net/danhaswings/znLL0ws5/1/
Fade in: https://jsfiddle.net/danhaswings/kjgmxa8x/
HTML
<div class="square"></div>
CSS
.square {
width: 100px;
height: 100px;
background-color: red;
transition: opacity 1s ease-in-out;
}
jQuery
var $square = $('.square');
$square.css('opacity', '0');
$square.one("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend", function() {
$(this).css('display', 'none');
});
What sort of phone are you testing on to get such slow / jittery animations? Mine seems to work fine for all of the animations that are supported on mobile browsers.
In any case, you can always try to use css keyframes.
Annoyingly, you cannot animate certain attributes (such as display) but it does allow for quite a lot of things including opacity as shown below.
div {
width: 100px;
height: 100px;
background: red;
margin: 20px;
}
.to_hide {
-webkit-animation: hide 5s forwards;
animation: hide 2s forwards;
}
#-webkit-keyframes hide {
from {
opacity: 1;
}
40% {
opacity: 0;
}
100% {
position: absolute;
opacity: 0;
}
}
<div class="to_hide"></div>
<div></div>
Keyframes on MDN
Ultimately, on mobiles you should try to avoid using animations as mobile browsers are not optimized for such things. Your website should degrade gracefully in both size, layout, content and also animations.
Should go smoothly if you use jQuery's fadeIn(), which will fade in an element with
display: none
$element.fadeIn();
function show() {
$("#el").fadeIn();
}
#el {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="show()">Show</button>
<div id="el">Hello</div>
Have a look at this article
You should always look to avoid animating properties that will trigger layout or paints, both of which are expensive and may lead to skipped frames.
You should be able to achieve a fade transition combining the opacity and transform properties

Vertically slideown over whole page

i'm working on a project where i need a semi-transparent div to slideover the entire page at a certain point. i have a version working currently, but it's not as smooth as i'd like it to be.
http://jsfiddle.net/27e310e8/
jQuery from above example:
var windowWidth = $(window).innerWidth();
var windowHeight = $(window).innerHeight();
function blackOut() {
$('#fail-screen').css({
"width": windowWidth + "px",
"height": windowHeight + "px"
});
$('#fail-screen').delay(1000).animate({
top: '0px'
}, 1000, 'linear');
}
$(document).ready(function () {
blackOut(windowWidth, windowHeight);
});
as you can see i'm getting the innerWidth and height to set the "fail-screen" div, as setting it to 100% wasn't working well. i'm using jQuery to animate the top position of the "fail-screen" div.
again, i'm just looking to refactor this code and improve overall presentation and performance. i'm open to using animation/physic libraries if anyone knows of any that would be good to use here.
appreciate any suggestions.
As #Jason has mentioned, I strongly recommend using CSS transforms instead of fiddling with the offsets. That is being not only are CSS transforms offloaded to the GPU (intelligently determined by the browser as of when needed, but you can also force it), but it allows for subpixel rendering. Paul Irish published a rather good write-up on this topic back in 2012.
Also, your code is slightly problematic in the sense that it fails to handle viewport resize events. In fact, a more straightforward solution would simply be using position: fixed, and then playing around with CSS transform to bring the element into view after a delay.
See updated fiddle here: http://jsfiddle.net/teddyrised/27e310e8/2/
For the JS, we simply use the .css() method. The delay, animation duration and even the timing function can be easily done via CSS.
The new JS is rather straightforward: we set the transform of #fail-screen so that we move it back to its original vertical position. jQuery automagically prefixes the transform property ;)
$(document).ready(function () {
$('#fail-screen').css({
'transform': 'translateY(0)'
});
});
For the CSS, we initially set a vertical translation (translateY) of -100%, which means we push the element upwards by its own height. Using fixed positioning and declaring all four offsets as 0, we can force the element to fill the viewport without any advanced hack of listening to window resize events via JS. Remember that you will have to add vendor prefixes to the transform property to maximize cross-browser compatibility.
CSS can also handle transition delay, duration and even the timing function, i.e. transition: [property] [duration] [timing-function] [delay]; Since in your jQuery code you have set both duration and delay to be 500ms, it should be transition: all 0.5s linear 0.5s. However, the linear timing function doesn't look good — perhaps using ease-in-out would be better, or even a custom cubic-bezier curve, perhaps?
Also, I recommend moving the opacity to the background-color value, simply because if you set an opacity on the element itself, all child nodes will be rendered at 0.6 opacity, too... it might be something that you do not want to achieve.
#fail-screen{
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: rgba(0,0,0,.6); /* Moved opacity to background-color */
position: fixed; /* Use fixed positioning */
z-index: 303;
/* Use CSS transform to move the element up by its own height */
-webkit-transform: translateY(-100%);
-ms-transform: translateY(-100%);
-o-transform: translateY(-100%);
transform: translateY(-100%);
/* CSS transition */
transition: all .5s ease-in-out .5s;
}

Slide + fade effect using CSS transitions

I'm trying to replicate this effect using CSS effects or transitions.
Using animations I can animate the opacity, but only fadeIn, and the height (which should control the slide) doesn't seem to work at all :(
The closest I've got is by using javascript to set a temporary class on the element I want to animate, and on which I apply the initial opacity. But height doesn't work either. And there seems to be a slight delay on animation start.
Any other ideas?
So I ended up using the solution posted in the question Simon mentioned: With javascript I wrap the element I want to animate within a "wrapper" DIV on which I apply the animation. The wrapper will get its height changed from 0 to the height of the content DIV every time the label is clicked:
fiddle here
I know it requires some javascript, but the idea is to make the animation in CSS, and this is what it does. And if JS is disabled, the toggle will still work...
You can't currently animate on height when one of the heights involved is auto, you have to set two explicit heights. There's an extensive workaround posted as an answer to this similar question.
I made an alteration to your JS Fiddle, I beleive this is what you want; please see it here.
You need to specify a height on the div originally (0) and don't forget overflow:hidden; so that the content doesn't 'spil out' of the div. You will still need jQuery / Javascript however, to toggle a class but it means much less Javascript is required. (I toggled the class "change" which you will see on that fiddle)
input {
display:none;
}
label {
display:inline-block;
}
div {
white-space: pre;
background: #eee;
color: #333;
overflow:hidden;
height:0;
opacity:0;
-moz-transition:height 1s opacity 1s;
-webkit-transition:height 1s opacity 1s;
-o-transition:height 1s opacity 1s;
-ms-transition:height 1s opacity 1s;
transition:height 1s, opacity 1s;
}
.changed {
height:200px;
opacity: 1;
}
I added a few vendor prefixes to the transition CSS propery as I'm not sure what browser you'll be using and I'm on firefox so I need the -moz- prefix lol :)
The only problem I can see with this is that height:auto or height:100% doesn't animate, so you'll need to specify ems or px... If this is going to be a problem (like if the content will be dynamic), I would advise using jQuery for the height animation.

Categories