Any help here is much appreciated. I would like to use jQuery to solve the following...
There are two divs. I would like to randomly fade in one of the divs (green or red), wait a few seconds, then fade it away. Then randomly fades in another one. I've tried using math.random();but I can't seem to get it working correctly.
So basically it chooses either the red or green div.. fades it away after a few seconds, randomly chooses the red or green div... then fades it away after a few seconds. And It just keeps repeating.
html:
<div id="one">This is the first block</div>
<div id="two">This is the second block</div>
css:
#one {
background: red;
width:300px;
height:100px;
}
#two {
background: green;
width:300px;
height:100px;
}
Give both divs a class name like .fade for easier to manage.
Then you can do like this:
(function randomFade() {
var fadeDivs = $('.fade'),
el = fadeDivs.eq(Math.floor(Math.random() * fadeDivs.length));
el.fadeIn('1000').delay(2000).fadeOut('1000',randomFade);
})();
Fiddle Demo
You could do this:
function fadeRandomly() {
// fade both out at first
$('#one').fadeOut(/* duration */);
$('#two').fadeOut(/* duration */);
if (Math.random() > 0.5) {
$('#one').fadeIn(/* duration */);
} else {
$('#two').fadeIn(/* duration */);
}
}
setInterval(fadeRandomly, /* duration between animations */);
This should work:
var rnd = Math.floor(Math.random() * 2) + 1;//outputs either 1 or 2
if (rnd == 1) {
$('#one').fadeIn(500).delay(500).fadeOut(500);
} else {
$('#two').fadeIn(500).delay(500).fadeOut(500);
}
Hope this helps!
something like: I added a function just in case you have more divs to deal with you and you want to expand the scope of your fades.
var a = ['one', 'two']; // the name of your divs
function fadeRandomDiv(min, max) {
var divtofade = a[Math.floor(Math.random() * (max - min + 1) + min)];
// delay 4 seconds, then fade out
jQuery( "#" + divtofade ).fadeIn( "slow" ).delay(4000).fadeOut("slow");
}
fadeRandomDiv(1, a.length - 1)
if you want to repeadedly call it.
// every 3 seconds call the function
setInterval(function(){
fadeRandomDiv(1, a.length - 1);
}, 3000);
Related
I'm trying to create a simple slideshow effect. I have 10 images, and I've created a basic HTML page with 2 buttons to go to the right or left image. On clicking the button, the images change.
Now, I'm trying to add a basic fade functionality to the changing image. But the fade effect isn't getting displayed. When I put alerts, I notice that the fade is taking place, but without the alerts it is too fast to be visible. Also, it is happening on the previous image, instead of the next one.
<html>
<head>
<style>
.main {
text-align: center;
}
.centered {
display: inline-block;
}
#image {
border: solid 2px;
width: 500px;
height: 500px;
}
#number {
font-size: 30px;
}
</style>
<script>
function goLeft() {
var image = document.getElementById("image");
var pos = document.getElementById("number");
if(Number(pos.innerHTML)==1) {
image.src = "Images\\10.jpg"
pos.innerHTML = 10;
} else {
image.src = "Images\\" + (Number(pos.innerHTML)-1).toString() + ".jpg"
pos.innerHTML = (Number(pos.innerHTML)-1).toString();
}
for (var i=0; i<25; i++) {
setTimeout(changeOpacity(image, i), 1000);
}
}
function changeOpacity(image, i) {
alert(parseFloat(i*4/100).toString());
image.style.opacity = (parseFloat(i*4/100).toString()).toString();
}
function goRight() {
var image = document.getElementById("image");
var pos = document.getElementById("number");
if(Number(pos.innerHTML)==10) {
image.src = "Images\\1.jpg"
pos.innerHTML = 1;
} else {
image.src = "Images\\" + (Number(pos.innerHTML)+1).toString() + ".jpg"
pos.innerHTML = (Number(pos.innerHTML)+1).toString();
}
for (var i=0; i<25; i++) {
setTimeout(changeOpacity(image, i), 1000);
}
}
</script>
</head>
<body>
<div class="main">
<div class="centered">
<img id="image" src="Images\1.jpg">
</div>
</div>
<div class="main">
<div class="centered">
<span id="number">1</span>
</div>
</div>
<div class="main">
<div class="centered">
<button onclick="goLeft()" style="margin-right:50px;">Go Left</button>
<button onclick="goRight()" style="margin-left:50px;">Go Right</button>
</div>
</div>
</body>
The problem is this block of code that is in your goLeft method, and goRight method:
for (var i=0; i<25; i++) {
setTimeout(changeOpacity(image, i), 1000);
}
You are creating 25 timers that, and each timer will execute approximately 1 second later.
Creating animations is best left to the CSS.
In your CSS add:
#image {
transition: opacity 0.5s ease;
}
And then in your JavaScript, simply: image.style.opacity = 1.0;
When the opacity changes, CSS will automatically transition the opacity length at the speed defined in the css, e.g 0.5s. Feel free to experiment.
I also added a jsfiddle here: http://jsfiddle.net/dya7L8wq/
You misunderstood setTimeout and the for loop.
Norman's answer provides a good solution with CSS, but he doesn't talk too much about why your code is not working. So I'd like to explain.
for (var i=0; i<25; i++) {
setTimeout(changeOpacity(image, i), 1000);
}
You assumption is:
invoke changeOpacity(image, 0) after 1 second
invoke changeOpacity(image, 1) 1 second after step 1
invoke changeOpacity(image, 2) 1 second after step 2
invoke changeOpacity(image, 3) 1 second after step 3
....
And the last step is invoking changeOpacity(image, 24) 1 second after previous step.
What actually happens is:
The loop is finished almost immediately!
In each iteration, setTimeout queues an asynchronous function invocation, and it's done! That says, it will return right away, rather than wait until changeOpacity returns.
And then, after about 1 second, changeOpacity fires 25 times almost at the same time, because you queued it 25 times in the for loop.
Another problem here is: in changeOpacity invocations, passed-in parameter i are not 1, 2, 3...., they all have the same value that causes for loop to exit (1 second ago) - 25, because JS doesn't have a block scope prior to ES6 (in ES6 we have keyword let for it).
In a pure JS solution, to ensure the time sequence we'd usually queue next invocation at the end of every step:
function changeOpacity() {
// do something here
// before the function returns, set up a future invocation
setTimeout(changeOpacity, 1000)
}
Here's an example to print a list of numbers from 1 to 5:
var go = document.getElementById('go')
var op = document.getElementById('output')
var i = 0
function printNum() {
var p = document.createElement('p')
p.innerHTML = ++i
op.appendChild(p)
// next step
if(i < 5) {
setTimeout(printNum, 500)
}
}
go.onclick = printNum
<button id="go">GO</button>
<div id="output"></div>
Why use pure JavaScript?
Use jQuery.
It has a pretty neat fadeTo() function and a useful fadeIn() function.
Might wanna use that ;)
I want fadeIn and fadeOut effect on div one by one sequentially with regular interval. I tried with following code but it will all div at a time fadeIn and fadeOut.
HTML
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
jQuery
function fade()
{
$("div").each(function(){
$(this).fadeOut(3000);
});
$("div").each(function(){
$(this).fadeIn(3000);
});
}
setInterval(fade,6000);
Update
I want First of all div one by one disappear from screen. When all div disappear then one by one show. This should happen regular interval.
JS Fiddle
There are different ways to execute deferred actions sequentially. Here is a good article about this http://www.paulirish.com/2008/sequentially-chain-your-callbacks-in-jquery-two-ways/
According to the comments and your later defined needs, you can solve it like this and use fadeTo instead of fadeIn/fadeOut
var start = $('div:first');
function fade(lobj){
lobj.fadeTo('slow',lobj.css('opacity')==1 ? 0 : 1,function(){
var nobj = lobj.next();
if(nobj.length)
fade(nobj);
else
fade(start);
});
}
fade(start);
http://jsfiddle.net/sofl/1n30hp49/15/
I guess you should use the function next on jQuery, like this, I just wrote forking in your snippet on jsfiddle:
http://jsfiddle.net/1n30hp49/17/
In this code above I also used the $el to define who is going to be the next element:
function fade( el, timer ){
el.fadeOut( timer , function() {
$( this ).fadeIn( timer , function() {
fade( $( this ).next(), timer ) ;
} ) ;
} ) ;
}
var timer = 1000 ;
//run function
fade( $( "div:first-child" ), 1000 ) ;
try to do this, if so, let me know if it works! att.
A reliable way to do this would be to use jQuery animation queues and a deferred object in a recursive loop. The advantage of this method is the ease you can add animations into the fade function. It is also much easier to read than a bunch of nested callbacks.
// Get all the div elements
var divs = $('div');
/**
* Fade in a specific indexed div element
* #param {integer} i
* #return {object} $.promise
*/
function fade(i)
{
return divs.eq(i)
.fadeIn(3000)
.delay(6000)
.fadeOut(3000)
.promise();
}
/**
* Recursive sequence runner
* #param {integer} i
*/
function runSequence(i) {
// If i is null/false set it to 0
i = ! i ? 0 : i;
// Run animation on item i
var promise = fade(i);
// Use the promise to queue up the next item
// by calling this function again when the
// animation is complete
promise.then(function() {
if (i > divs.length) {
i = 0;
}
runSequence(++i);
});
}
// Run the sequence for the first time
runSequence();
JSFiddle example
There's been some great answers here but just to add to the diversity, here's another way with just good-ol' Fade in's and outs:
PLEASE NOTE
Stackoverflow's method of including third party scripts in their snippets interferes with this example so I had to add a container div around the other divs. For a purer example see the fiddle.
function fade() {
var thisObj = this;
thisObj.out = function(el, timer) {
el.fadeOut( timer , function() {
if ($( this ).prev().length > 0) {
thisObj.out( $( this ).prev(), timer );
} else {
thisObj.in( $( "#container").find("div:first-child" ), timer );
}
} ) ;
}
thisObj.in = function(el, timer) {
el.fadeIn( timer , function() {
if ($( this ).next().length > 0) {
thisObj.in( $( this ).next(), timer ) ;
} else {
thisObj.out( $( "#container").find("div:last-child" ), timer );
}
} );
}
}
new fade().out( $( "#container").find("div:last-child" ), 1000 );
#container div {
background : #00f;
height: 50px;
width : 50px;
margin : 5px;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
To change the order of the fade in and out, just change last-child to first-child.
I created an image slider that ends on one image, but now I'd like to take it a step further and make it loop.
Here is my code in the head tag
<style>
#picOne, #picTwo, #picThree, #picFour, #picFive{
position:absolute;
display: none;
}
#pics {
width:500px;
height:332px;
}
</style>
<script src="http://code.jquery.com/jquery-1.4.4.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#picOne').fadeIn(1500).delay(3500).fadeOut(1500);
$('#picTwo').delay(5000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picThree').delay(10000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picFour').delay(15000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picFive').delay(20000).fadeIn(1500).delay(3500);
});
</script>
and here is where it is implemented in the body code
<div id="pics">
<center>
<img src="img/dolllay.jpg" width="500" height="332" id="picFive" />
<img src="img/dye.jpg" width="500" height="332" id="picTwo" />
<img src="img/dollsit.jpg" width="500" height="332" id="picThree" />
<img src="img/heirloom.jpg" width="500" height="332" id="picFour" />
<img src="img/heritage.jpg" width="500" height="332" id="picOne" />
</center>
</div>
Could I turn it into a function and then loop it? Can I get any guidance on that? Thank you very much
Everyone's answering the question, but not solving the problem.
Sure, you can just put a loop wrapper around it (preferably one that doesn't terminate), but why not just program it right? Why have all the hardcoded times, and why not make it more robust?
Try rewriting your code like this. It makes it much easier to modify the pictures you loop through:
var pictures = ["picOne", "picTwo", "picThree", "picFour", "picFive"];
var index = 0;
var displayImage = function() {
if (index == pictures.length) { return; }
$("#" + pictures[index++]).fadeIn(1500).delay(3500).fadeOut(1500, displayImage);
};
displayImage();
Then, if you want to loop back, you simply tweak the displayImage function:
var displayImage = function() {
if (index == pictures.length) { index = 0; }
$("#" + pictures[index++]).fadeIn(1500).delay(3500).fadeOut(1500, displayImage);
};
TRY IT at jsfiddle
EDIT
On more careful reading of your question, I see that my original answer didn't do exactly what you needed. You have it set so that every five seconds, one will have faded out and the other one will have faded in. Currently, mine takes 6.5 seconds, since mine is all operating sequentially instead of concurrently. To make it come close to matching yours, just change the 1500s to 750s:
$("#" + pictures[index++]).fadeIn(750).delay(3500).fadeOut(750, displayImage);
This will take the right amount of time. It's slightly different from yours, in that one fades out all the way before the other fades in. The alternative is to actually skip the fadeIn and keep the fadeout. This is a lot closer to the way yours looks.
$("#" + pictures[index++]).show().delay(3500).fadeOut(1500, displayImage);
Or, make a very small fadein, to help reduce the flash of the new image:
$("#" + pictures[index++]).fadeIn(100).delay(3500).fadeOut(1400, displayImage);
Final Edit (really!)
Ok, to get the fadeIn and fadeOut to work reliably at the same time, the solution was to use neither. I went back to using animate, instead. As a result, I had to completely rewrite the displayImage function, but this is exactly what you need:
var displayImage = function () {
if (index == pictures.length) {
index = 0;
}
$("#" + pictures[index]).show().delay(3500).animate({
opacity: 0.2
}, {
step: function (now) {
var idx = (index + 1) % pictures.length;
var val = 1.2 - now;
$("#" + pictures[idx]).show().css("opacity", val);
},
complete: function () {
$("#" + pictures[index++]).hide();
displayImage();
}
});
};
What this does is move the sequence to "show->fadeIn and Out" instead of "fade in -> show -> fade out". To make your transition smooth, I only fade it out to 0.2 instead of 0. The step function is what fades the other one in at the same time. Once the new pic is visible, I completely hide the old pic.
Here's the working fiddle for it.
$(document).ready(function() {
setInterval(example, 10000); // repeat every 10 seconds
});
function example() {
$('#picOne').fadeIn(1500).delay(3500).fadeOut(1500);
$('#picTwo').delay(5000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picThree').delay(10000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picFour').delay(15000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picFive').delay(20000).fadeIn(1500).delay(3500);
}
A better way would be to give each pic the same class such as 'fadeinout'. This will mean you don't have to re-write your code when you add/remove more pics.
eg
<img id="picFive" class="fadeinout" ....
/* not sure if they are even <img>s but whatever they are*/
Then do
$(document).ready(function() {
beginFades();
});
function beginFades() {
$('.fadeinout').each( function(i,el) { // find all elements with fadeinout
//for each one, trigger the start of the fading after i*5000 milliseconds
//i is the index of the element as it was found by jQuery - this will be in
//document order (which actually may not be what you have but I'm guessing
//it is)
setTimeout(function(){
makeImgFadeInOut($(el))
}, i*5000);
});
}
function makeImgFadeInOut(el) {
//trigger a single fadeIn, fadeOut.
//But add a callback function to the end of fadeOut which retriggers the whole
//thing
el.fadeIn(1500).delay(3500).fadeOut(1500, function(){makeImgFadeInOut(el);});
}
WORKING DEMO (WITH DIVS)
You can use setInterval to loop it forever, or setTimeout to loop it for a specific duration.
<script type="text/javascript">
$(document).ready(function() {
setInterval(ImageSlider, 1000);
});
function ImageSlider() {
$('#picOne').fadeIn(1500).delay(3500).fadeOut(1500);
$('#picTwo').delay(5000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picThree').delay(10000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picFour').delay(15000).fadeIn(1500).delay(3500).fadeOut(1500);
$('#picFive').delay(20000).fadeIn(1500).delay(3500);
}
</script>
If you want to have total control upon your elements you can use this:
var elements = [{
el: '#pic1',
delay: 3500,
fadeIn: 1500,
fadeOut: 1500
},
{
el: '#pic2',
delay: 3500,
fadeIn: 1500,
fadeOut: 1500
}
//... other elements
]
var index = null;
(function loop(){
index = index || 0;
index = index % elements.length();
$(elements[index].el).fadeIn(elements[index].fadeIn, function(){
$(this).delay(elements[index].delay)
.fadeOut(elements[index].fadeOut, function(){
index++;
window.setTimeout(loop, 5000);
});
})();
Edit : forgot to execute the first iteration of the loop function and removing the useless call for index inside the loop
The good thing about how this loop works is that it doesn't use the SetInterval function.
and the code inside the loop need to finish what it does inside before iterating again.
(you won't have this hideous bug if you click an other tab and go back to your carousel)
#ElRoconno answer is pretty good too if you require less configuration
Use any of this-
setInterval() - executes a function, over and over again, at specified time intervals
setInterval(function(){alert("Hello")},3000);
setTimeout() - executes a function, once, after waiting a specified number of milliseconds.
setTimeout(function(){alert("Hello")},3000);
What is the difference between both setInterval and setTimeout
for you may be the setTimeout will not work as it will run only once after a delay and setInterval will go on to make continuous repetitive call until the window.clearInterval(intervalVariable) is been called
I have created an example on jsfiddler here. Basically you don't have to do this one at a time. Just get the whole collection of images as an array and loop over them. Hope this helps
$(document).ready(function () {
var arr = $('.pics')
arr.hide();
$(arr[0]).fadeIn(1500).delay(3500).fadeOut(1500);
var index = 1;
var maxIndex = arr.length - 1;
setInterval(function () {
/*arr.hide();
var pic = $(arr[index]);
pic.show();
*/
var pic = $(arr[index]);
pic.fadeIn(1500).delay(3500).fadeOut(1500);
index++;
if (index >= maxIndex) {
index = 0;
}
}, 6500);
});
There's really no need for setInterval here since you can use the callback built-into .fadeOut(), nor having to enumerate an array of images. You can do something as simple as:
var idx = 0;
fade();
function fade() {
if (idx >= $('img').length) idx = 0;
$('img').eq(idx).fadeIn(1500).delay(3500).fadeOut(1500, fade);
idx++;
}
jsFiddle example
$(document).ready(function fadeIt() {
$("#cool_content > div").hide();
var sizeLoop = $("#cool_content > div").length;
var startLoop = 0;
$("#cool_content > div").first().eq(startLoop).fadeIn(500);
setInterval(function () {
$("#cool_content > div").eq(startLoop).fadeOut(1000);
if (startLoop == sizeLoop) {
startLoop = 0
} else {
startLoop++;
}
$("#cool_content > div").eq(startLoop).fadeIn(1500);
}, 2000);
});
Here I want a class of divs to animate, infinitely!
However, because the interval is set to two seconds there is period where no div is showing!
What would be an appropriate way to loop the animation of these divs?
I thought about using a for loop but couldn't figure out how to pass a class of divs as arguments. All your help is appreciated.
Thanks!
Ok, generally, you should know that Javascript is a single threaded environment. Along with this, the timer events are generally not on time accurately. I'm not sure how jQuery is doing fadeIn and fadeOut, but if it's not using CSS3 transitions, it's going to be using timeOut and Intervals. So basically, there's a lot of timer's going on.
If you go with the for loop on this one, you'd be blocking the single thread, so that's not the way to go forward. You'd have to do the fade in/out by yourself in the setInterval.
Setting the opacity on each interval call. Like div.css('opacity', (opacity -= 10) + '%')
If you're trying to fade in and out sequentially, I think maybe this code would help
var opacity = 100,
isFadingIn = false;
window.setInterval(function() {
if (isFadingIn) {
opacity += 10;
if (opacity === 100) isFadingIn = false;
} else {
opacity -= 10;
if (opacity === 0) isFadingIn = true;
}
$('#coolContent > div').css('opacity', opacity + '%');
}, 2000);
Consider the following JavaScript / jQuery:
$(function(){
var divs = $('#cool_content > div').hide();
var curDiv;
var counter = 0;
var doUpdate = function(){
// Hide any old div
if (curDiv)
curDiv.fadeOut(1000);
// Show the new div
curDiv = divs.eq(counter);
curDiv.fadeIn(1000);
// Increment the counter
counter = ++counter % divs.length;
};
doUpdate();
setInterval(doUpdate, 2000);
});
This loops infinitely through the divs. It's also more efficient than your code because it only queries the DOM for the list of divs once.
Update: Forked fiddle
instead of
if (startLoop == sizeLoop)
{
startLoop = 0
}
else
{
startLoop++;
}
use
startLoop =(startLoop+1)%sizeLoop;
Check the demo http://jsfiddle.net/JvdU9/ - 1st div is being animated just immediately after 4th disappears.
UPD:
Not sure I've undestood your question, but I'll try to answer :)
It doesn't matter how many divs you are being looped - 4, 5 or 10, since number of frames are being calculated automatically
x=(x+1)%n means that x will never be greater than n-1: x>=0 and x<n.
x=(x+1)%n is just shorten equivalent for
if(x<n-1)
x++;
else
x=0;
as for me first variant is much readable:)
And sorry, I gave you last time wrong demo. Correct one - http://jsfiddle.net/JvdU9/2/
Could someone please check my code? Thank you
Here is the fiddle site if you want to test:
http://jsfiddle.net/66QYr/
I would like to have the first 3 text to appear on the left (vertically)
and then the next 3 text appear on the right (vertically)
then the next 2 text appear on the lower right bottom (vertically)
and the last 2 text appear on the lower left bottom (vertically)
http://i197.photobucket.com/albums/aa253/tintingerri/Test/pic001.png
<html>
<head>
<title>tintin</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
#tintin{
position: relative;
top: 211px;
left: 12px;
font-size:14pt;
font-weight:bold;
font-family: Calibri;
color:red;
filter:alpha(opacity=0);
opacity:0;}
.image{
height:350px;
width: 855px;}
</style>
<script type="text/javascript">
var txt=['text1','text2', 'text3', 'text4', 'text5', 'text6', 'text7', 'text8', 'text9', 'text10'], init=0,i=0,k=0,speed=20,el;
var loopCount=1000;
var j=0;
//var padd = 20; //set this to an approriate increment
function fade(){
init==0?i++:i--;
el.filters?el.style.filter='alpha(opacity='+i+')':el.style.opacity=i/100;
el.firstChild.nodeValue=txt[k];
if(i==100)init=1;
if(i==0) {init=0;k++;j++;
el.style.paddingLeft=20*k;
}
if(k==txt.length)k=0;
if (j<loopCount) setTimeout('fade()',speed);
}
window.onload=function(){
el=document.getElementById('tintin');
fade();
}
</script>
</head>
<body>
<div id="tintin"> </div>
<div class="image" style="background-image:url('pic007s.jpg')">;
</div>
</body>
</html>
There are two problems you're trying to solve here:
Positioning the text in the appropriate places
Getting them to fade in
Step One
The first problem can be solved with some simple CSS. Start out with a container:
#container {
position:relative;
width:150px;
height:150px;
}
<div id="container"></div>
The width and height can be anything, but you do have to tell it something. We're going to be putting our text in this container, but then use position:absolute. This will take them out of the normal document flow, and collapse the container if we have told it an explicit height.
The next step is the text. You're going to want four divs, with the text inside as paragraphs:
<div class="text" id="text1">
<p>text 1</p>
<p>text 2</p>
<p>text 3</p>
</div>
Do this for each of the four blocks of text that you want to have. Use the same class name on each one, but give each their own, unique ID (text2, text3, etc.).
Finally, just use (as I said earlier) absolute positioning to place them where you'd like:
.text { position:absolute; }
#text1 { top:0; left:0; }
#text2 { top:0; right:0; }
...and so on. When you're done, you should have something that looks like this:
Step Two
Fading elements in requires animation. You kind of have a basic animation function, but I suggest you read Robert Penner's article on tweening and animation. It was written for ActionScript, but the exact same principles apply.
For now, here's a good general-purpose JavaScript method that will take an element and fade it in:
function fadeIn(totalTime, elem, after) {
var cos = Math.cos,
PI = Math.PI,
startTime = +new Date(),
endTime = startTime + totalTime,
timer;
elem.style.opacity = 0;
elem.style.filter = 'alpha(opacity=0)';
timer = setInterval(function () {
var currentTime = +new Date();
currentTime = currentTime > endTime ? 1 : (currentTime - startTime) / totalTime;
var distance = (1 - cos(currentTime * PI)) / 2;
elem.style.opacity = distance;
elem.style.filter = 'alpha(opacity=' + distance * 100 + ')';
if (currentTime === 1) {
clearInterval(timer);
if (after) {
after();
}
}
}, 40);
}
You tell this function how long you want the animation to last (in milliseconds), and you can also give it a function to execute when the fading is done (if you want; it's not necessary).
If I understood your question correctly, you want all the texts to start invisible, and then fade in, one at a time, clockwise from the top. We can make them invisible with CSS, but then if the user has JS disabled, the page will appear blank. So you need to first "get" all of the elements (either with some kind of getByClass function or with four different calls to getElementById) and set their opacity to 0.
So you can make the first group of texts fade in by doing the following:
var text1 = document.getElementById('text1');
fadeIn(1000, text1);
The problem is, by doing this, there's no way to tell when to start the next animation. So we need to make a function, with the help of closures, to help keep track of things (this assumes that you've already gotten the elements in JS and made them invisible):
var tracker = (function () {
var texts = [text1, text2, text3, text4],
i = 0;
return function () {
var text = texts[i];
if (text) {
fadeIn(1000, text, tracker);
i += 1;
}
};
}());
This function cycles through each element and fades it in when the previous one is done. (It's okay if the code doesn't make a lot of sense; closures are tricky things.)
Here is the final result, in JSFiddle. Good luck.