Using css3 transitions instead of jQuery animate - javascript

I'm animating a block of html that fades in (opacity) and moves slightly from the left (margin-left)...
$('.latest-stats').delay(1000).animate({ opacity: 1, marginLeft: '55px' }, 1000, function () {
...code in here
}
.latest-stats {
position:absolute;
top:250px;
opacity:0;
margin-left:40px;
}
There is a delay and I need to perform some functions within that block of HTML after the transiiton has finished. Can this be done in css, maybe by adding a class that has the transitions upon it?

The Added CSS Class:
.transitioned {
opacity:1;
margin-left:55px;
transition:all 1s;
-ms-transition:all 1s;
-moz-transition:all 1s;
-o-transition:all 1s;
-webkit-transition:all 1s;
}
The jQuery: (UPDATED)
setTimeout(function(){
$('.latest-stats').addClass('transitioned');
setTimeout(function(){
//your code here
},1000);
},1000);
but I just have to ask, is there a specific reason you wanna do this? I mean what's wrong with the jQuery animate?

We rejig the JS to just add the class rather than the any styles:
setTimeout(function(){
$('.latest-stats').toggleClass('transitioned').each(function () {
// Call back functions here
});
}, 1000);
I use setTimeout() since delay() only works for animations. I use each() to add my callback function, since toggleClass() doesn't have a callback, and this way I don't need to load an extra library.
Then the CSS handles the changes to the styles, keeping all the visual aspects in one location:
.latest-stats {
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
transition: all 0.5s;
position:absolute;
opacity:0;
margin-left:40px;
padding: 30px;
background:red;
margin:40px;
}
.latest-stats.transitioned {
opacity:1;
-webkit-transform:translate(55px, 0);
-moz-transform:translate(55px, 0);
transform:translate(55px, 0);
}
Note I'm using translate to shift the element rather than margin-left as the browser doesn't have to change the layout or perform a repaint on the element, which can improve the animation. However, check for browser support and provide fallbacks when necessary/appropriate.
Here's a JSFiddle.

Related

Simple fadein not running smooth

I am a beginner in jQuery and JS and I wanted to make a simple fade in animation using the following code. Unfortunately the code is not running smooth, and despite reading up all the basics (at least I suppose so) I cannot get it to run smoothly. Can anyone point me in the correct direction on how to make a smooth fade in animation?
All my elements are visible in the beginning. I don't want to start with hidden elements as this could result in problems in my UI if there is no JS enabled.
Thank you.
$(function () {
$("#center_block").animate(
{
opacity: 0,
}, 0, function () {
$("#center_block").animate({
opacity: 1,
}, 250);
});
});
If you have a slow processor on your computer or if you are viewing javascript animations a mobile device the processor might not be able to cope with the animation. If you use CSS3 animations then the inbuilt browsers hardware acceleration is used, which is a lot more efficient.
All I am doing is using CSS3 animation to apply the fade.
#keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity:1;
}
}
#center_block {
animation: 1s ease-out fadeIn;
}
<div id="center_block">Look at me, I'm Mr Center Block</div>
There really is no need for JavaScript at all here. CSS animations can do this more easily with better performance (because they will leverage GPU hardware acceleration):
span {
font-size:3em;
font-weight:bold;
font-family:Arial;
border:1px solid grey;
background-color:aliceblue;
display:inline-block;
padding:10px;
opacity:0;
/* Configure the element to use the animation */
animation: 3s infinite fade;
}
#keyframes fade {
0% { opacity:0; }
50% { opacity:1; }
100% { opacity:0; }
}
<span>Hello</span>
Or, if you don't want the animation to be automatic and have some sort of trigger, then just add a CSS class to the object at the right time:
document.querySelector("button").addEventListener("click", function(){
document.querySelector("span").classList.add("animate");
});
span {
font-size:3em;
font-weight:bold;
font-family:Arial;
border:1px solid grey;
background-color:aliceblue;
display:inline-block;
padding:10px;
opacity:0;
}
.animate {
/* Configure the element to use the animation */
animation: 3s infinite fade;
}
#keyframes fade {
0% { opacity:0; }
50% { opacity:1; }
100% { opacity:0; }
}
<button>Click to Start</button>
<span>Hello</span>
I would advise using CSS animations as much as possible for the smoothest performance. A great library to get you started is animate.css. To use it, include the css library in your project and use javascript to add predefined classes to your components. In your case:
$('#center_block').addClass('animated fadeIn');
would fade in the #center_block element nicely.
If you don't want to hide the elements incase JS is disabled, then you need to hide them first using JS. Also, you're currently using 250ms, which is incredibly fast, and unlikely to be perceived by users.
$(document).on('ready', function(){
$('#center_block').hide().fadeIn(250);
});
If your elements already have opacity: 0; for the CSS, then you can add a transition to handle the animation:
#center_block{
opacity: 0;
transition: all .25s linear;
}
Then change the CSS value of opacity whenever the triggering condition is met:
$('#center_block').css('opacity','1');

Strange behavior of link fading

I am creating a "scroll to top" link for my personal webpage but I have ran into some strange behavior that I cannot seem to correct.
I want the link to fade in when the user scroll to a certain amount of pixels and then fade out again if the user scrolls up above this point. Pretty standard behavior.
The markup is pretty simple:
The CSS:
#scroll-top {
position: fixed;
right:30px;
bottom:30px;
width: 30px;
height:30px;
color: #38555e;
z-index: 99;
border-radius: 50%;
border:2px solid #38555e;
text-align: center;
background:#fff;
-webkit-transition:all 0.2s linear;
-moz-transition:all 0.2s linear;
-o-transition:all 0.2s linear;
transition:all 0.2s linear;
display:none;
}
#scroll-top:hover {
background:#38555e;
color:#fff;
border-color:#fff;
}
and the Jquery code:
$(window).scroll(function () {
if(!( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) )) {
if ($(this).scrollTop() > 100) {
$('#scroll-top').fadeIn(2000);
} else {
$('#scroll-top').fadeOut(2000);
}
}
});
DEMO: http://jsfiddle.net/chc91n5f/4/
My problem is that when the link is faded in, it waits about 2 seconds and then fades in fast instead of starting the fading immediately and fading slowly. Also when the link fades out it waits and then fades out fast.
What am I missing here?
The fadeIn and fadeOut functions in jQuery are shorthands for animating the opacity.
jQuery animates properties as putting them inline and changing it untill it reaches a specific point. In your case it's changing the opacity to lets say 0.35677 and the browser animates this change.
In order to have a more sleek animation use CSS class (visible for instance) to modify the opacity.
body {
height:2000px;
background:red;
}
#scroll-top {
position: fixed;
right:30px;
bottom:30px;
width: 30px;
height:30px;
color: #38555e;
z-index: 99;
border-radius: 50%;
border:2px solid #38555e;
text-align: center;
background:#fff;
-webkit-transition:all 0.2s linear;
-moz-transition:all 0.2s linear;
-o-transition:all 0.2s linear;
transition:all 0.2s linear;
opacity: 0;
}
#scroll-top:hover {
background:#38555e;
color:#fff;
border-color:#fff;
}
#scroll-top.visible {
opacity: 1;
}
And use the following code to change it:
if ($(this).scrollTop() > 100) {
$('#scroll-top').addClass('visible');
} else {
$('#scroll-top').removeClass('visible');
}
I believe the problem is in your scroll function..
In the most simple explanation.
When you scroll (1 tick with your scrollwheel) the code looks if you are past 100px. In most basic browsers and OS's the scrolling distance is 122px (correct me if i'm wrong). Problem is.. if you scroll 3 clicks with your mousewheel. you are 3 times past 100px and the animation of the fadeIn wil queue 3 times. At a certain point jQuery has enough of it and says you know what.. if you want the same long animation for a few times. i will skip a few times to spead my workload.
So much for the simple explanation.
You can disable this with a clearQueue (http://api.jquery.com/clearqueue/) and it will disable the flashing animation. edited like this
$(window).scroll(function () {
if(!( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) )) {
if ($(this).scrollTop() > 100) {
$('#scroll-top').animate({opacity: 1},1000).clearQueue();
console.log("test");
} else {
$('#scroll-top').animate({opacity: 0},1000);
}
}
});
Demo: http://jsfiddle.net/2uox7ep7/5/
Its because it keeps on fading in/out as you scroll even when it is already fading and thus the delay. You can use a variable like visible to keep track of the visibility
http://jsfiddle.net/chc91n5f/7/

Fading in via CSS transition doesn't work properly

I'm trying to animate a page element using CSS transition on opacity property. Fading out works properly, but Fading in doesn't. What am I doing wrong?
Some facts are really strange:
Without using .no-display class everything works as expected (but I should use it).
Replaying function's commands in browser console does work as expected (but function does not).
The code:
HTML
<p>Fade in</p>
<p>Fade out</p>
<div class="no-display invisible" id="square"></div>
CSS
.no-display {
display: none;
}
.invisible {
opacity: 0;
}
#square {
width: 500px;
height: 500px;
background-color: red;
border: 1px solid black;
-webkit-transition: opacity 2s ease;
-moz-transition: opacity 2s ease;
-ms-transition: opacity 2s ease;
-o-transition: opacity 2s ease;
transition: opacity 2s ease;
}
JavaScript
function fadeIn() {
square.classList.remove("no-display");
square.classList.remove("invisible");
}
function fadeOut() {
square.classList.add("invisible");
setTimeout(function() { square.classList.add("no-display"); }, 2000 );
}
Or: http://jsfiddle.net/V2Sar/6/.
Note, I can't use any frameworks such as jQuery. I have to work only with pure JavaScript.
The easy way to trigger CSS transitions with JS is to toggle classnames, and the easy way to do that is through the classList API.
js
var square = document.getElementById("square");
function fadeIn() {
square.classList.remove("invisible");
}
function fadeOut() {
square.classList.add("invisible");
}
css
#square {
opacity: 1;
transition: opacity 2s ease;
}
#square.invisible {
opacity: 0;
}
http://jsfiddle.net/V2Sar/5/
Also, make sure your scripts are at the end of the <body> so you don't need to worry about whether the DOM is constructed yet (separate option in jsfiddle for this).
The browser support isn't great (no support in IE9) but there is a shim available at https://github.com/eligrey/classList.js
Let me know if this isn't good enough for you and I'll post some alternatives as well.
The only problem is "display: none;". Simply replace it with 'visibility: hidden'.
The reason is that 'display: none' doesn't build the resulting element in the DOM. As such, it cannot fade in something that does not exist. When its created, its created in a visible way.
'visibility: hidden', however, does build the resulting element in the DOM, simply doesn't show it. Because it exists, it can fade in when required.

expand div height onmouseover

I need height on the div 50px in default and it has to be changed to 300px onmouseover. I coded in below manner to implement it.
<style type="text/css">
#div1{
height:50px;
overflow:hidden;
}
#div1:hover{
height:300px;
}
</style>
<body>
<div id="div1"></div>
</body>
This code is working fine but as per CSS property on hover its immediately changing its height. Now, I need a stylish way like slowly expanding div onmouseover and contracting onmoveout. How to expand and contract div on hover?
There are a few approaches -- here is CSS and Jquery, which should work in all browsers, not just modern ones:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("#div1").hover(
//on mouseover
function() {
$(this).animate({
height: '+=250' //adds 250px
}, 'slow' //sets animation speed to slow
);
},
//on mouseout
function() {
$(this).animate({
height: '-=250px' //substracts 250px
}, 'slow'
);
}
);
});
</script>
<style type="text/css">
#div1{
height:50px;
overflow:hidden;
background: red; /* just for demo */
}
</style>
<body>
<div id="div1">This is div 1</div>
</body>
#div1{
-webkit-transition: all .3s ease-in-out;
-moz-transition: all .3s ease-in-out;
-o-transition: all .3s ease-in-out;
-ms-transition: all .3s ease-in-out;
transition: all .3s ease-in-out;
}
Easy!
In a "modern" browser, you can just apply a css transition effect:
#div1 {
-moz-transition: 4s all ease-in-out;
-ms-transition: 4s all ease-in-out;
-webkit-transition: 4s all ease-in-out;
-o-transition: 4s all ease-in-out;
}
This would apply a transition effect over 4 seconds with a ease-in-out easing for compatible firefox, ie, chrome/safari (webkit) and opera browser. Read more:
CSS Transitions
You can take this one step ahead and check if the current browser supports css transitions, if available, use them for animation and if not use a javascript animation script. Example for that:
BarFoos animations
You can use jQuery's .animate() This will act on any element with with a class of "tab", and will revert on mouse-out.
$('.tab').hover(function() {
$(this).stop()
$(this).animate({
height: '+=250'
}, 500)
}, function() {
$(this).stop()
$(this).animate({
height: '-=250'
}, 500)
})
You can use jquery's .mouseover http://api.jquery.com/mouseover/, .mouseout http://api.jquery.com/mouseout/, and .animate http://api.jquery.com/animate/ to perform that.
On the .mouseover event, you would animate the height to be 300px, and on the .mouseout event you would animate to 50px. Make sure you call .stop on the div before you call animate, otherwise you will have odd issues.

How do I fade in a div that has a set opacity?

I have a div filled with info at this blog and I have it set at a certain opacity using CSS. How would I have it "fade in" using jQuery to 90 or 100% on hover of that div?
.infoHolder2 {
position:absolute;
color:#FFF;
background:#9f9377;
padding:15px;
padding-top:23px;
z-index:5;
width:97.7%;
bottom:8px;
margin:-8px;
opacity:0.2;filter:alpha(opacity=20)
}
<div class="infoHolder2"><div id="title">I'm {Title} and I like <span id="stuff"></span>.
</div><img id="portrait" src="{PortraitURL-128}"><img id="portraitCover"
src="http://static.tumblr.com/ux4v5bf/3Uolhxkyl/cover.png">
<div id="infoHolder">{Description}</div></div>
Try jquery fadeto().
This should do the trick (fade to 90% in 500 ms):
$(".infoHolder2").fadeTo(500, 0.9);
I think that the following should work:
$('.infoHolder2').fadeTo(500,'1');
It's worth noting the order of the arguments in the fade() method, duration is first, followed by the value of the desired opacity. For some reason I always get them mixed up when writing them down. Thanks #alex for the comment.
You could, also, if you wanted to, use:
$('.infoHolder2').animate({'opacity':'1'},500);
But, unless you're animating other properties, it becomes a little less concise for the same effect.
JS Fiddle demo to cover both options.
References:
fadeTo(),
animate().
Edited in response to OP's requirements to run this on hover()
$('ul li').hover(
function(){
var which = $(this).index();
if (which == 0){
$(this).fadeTo(500,'1');
}
else {
$(this).animate({'opacity':'1'},500);
}
},
function(){
$(this).fadeTo(500, 0.5);
}
);
JS Fiddle demo.
Use jQueries fadeTo
Usage
http://api.jquery.com/fadeTo/
fadeTo(duration, opacity)
Example
//90% Opacity
$('.infoHolder2').fadeTo("slow", 0.90);
//100% Opacity
$('.infoHolder2').fadeTo("slow", 1);
On Hover
$('.infoHolder2').hover(
function(){
$(this).fadeTo('slow', 0.90);
},function(){
$(this).fadeTo('slow', 0.50);
}
);
Live Demo
You can use fadeTo().
To fade to 90% opacity, use this...
$('.infoHolder2').hover(function() {
$(this).fadeTo(1000, 0.9);
}, function() {
$(this).fadeTo(1000, 0);
});
jsFiddle.
also by CSS3 without using jquery
.image {
position: relative;
overflow: hidden;
-webkit-transition: all 0.5s ease-out;
-moz-transition: all 0.5s ease-out;
transition: all 0.5s ease-out;
opacity:1;
filter:alpha(opacity=100);
}
.image:hover {
opacity:0;
filter:alpha(opacity=0);
}

Categories