I have a container with a lot of small images.
<div id="container">
<img src="1.jpg" />
<img src="2.jpg" />
<img src="3.jpg" />
...
<img src="100.jpg" />
</div>
I set opacity to 0. (not hidding)
Then I want to show(fadeIn) random image after half second. for example 5th, 1st, 55th ...
Any suggestions, thanx a lot
try this
<script type="text/javascript">
//generate random number
var randomnumber=Math.floor(Math.random()*$("#container").children().length);
$(function() {
//hide all the images (if not already done)
$("#container > img").hide();
//set timeout for image to appear (set at 500ms)
setTimeout(function(){
//fade in the random index of the image collection
$("#container > img:eq(" + randomnumber + ")").fadeIn();
}, 500);
});
</script>
put an id to each image, with a number pattern, and then fade a image with a random generated id, using math.random from javascript
function getImage(minim,maxim) {
return "img" + Math.round(Math.random()*(maxim-minim)+minim);
}
It is not clear (to me) if you want to start fading after half a second, or fade in in half a second. However, going with fade in after half a second. If you want to do it otherwise, just ignore the stuff with setTimeout()
The general overview of what you want to do is:
Create a function when the page has loaded that is called after half a second (setTimeout)
That function should generate a random number, with the min as 0, and the max as the number of children of the #container element minus 1
Fade the child of the #container with the index supplied by the random number.
Pusdo code (It is a long time since I have done anything with jQuery. Or Javascript for that matter)
function onDocumentReady(){
setTimeout(500, "fadeInRandom()");
}
function fadeInRandom(){
var numElements = $("#container").children().length;
var randomElem = Math.random() * (numElements-1);
$("#container").children()[randomElem].fadeIn();
}
If you want to fade-in all images instead, theres no need to use all the random stuff, just cicle and delay a random number
between 500ms and 1 second. You have to put hide function anyway. Or with opacity use animate css.
$('#container img').each(function(index) {
$(this).delay( Math.random()*500+500 ).fadeIn();
});
you won't find nothing simpler than that, and with the same effect
I would use the random number generated to create the image's 'src' attribute and build the jQuery selector accordingly:
setInterval ( showRandomImage, 500 );
function showRandomImage()
{
var randNo = Math.floor(Math.random() * 101);
$("#container > img[src=" + randNo + "'.jpg']")
.animate({opacity: 0}, 500).fadeIn('slow');
}
Related
I have the following HTML structure:
<div class="change me">Item 1</div>
<div class="change me">Item 2</div>
<div class="change me">Item 3</div>
<div class="change me">Item 4</div>
<div class="change me">Item 5</div>
<div class="change me">Item 6</div>
And CSS:
body {
font-family: Helvetica, Arial, sans-serif;
font-size:20px;
}
div {
background-color: #fff;
display: block;
border-bottom: 1px solid #ccc;
background-image: url(http://cdn.sstatic.net/Img/mini-hero-bg.png?v=7f269bbbdb22);
}
.change {
background-image: none;
}
Now I would like to pic a random div with Javascript / jQuery and "remove" the class "change" so that the default background image of the specific div will be visible. My code looks like that atm:
var divs = $(".me").toArray();
var divlength = divs.length;
setInterval(function(){
var randomnum = Math.floor(Math.random()*divlength);
var randomdiv = divs[randomnum];
$(randomdiv).addTemporaryClass("change", 1000);
}, 1000);
$.fn.extend({
addTemporaryClass: function(className, duration) {
var elements = this;
setTimeout(function() {
elements.addClass(className);
}, duration);
return this.each(function() {
$(this).removeClass(className);
});
}
});
I need to improve this to achieve the following:
I would like to have a smoother change from no-background-image to the visibility of the default background-image. Some fading effect or something like that. Already tried to add some transition to the div CSS but with no success.
Sometimes there is no "change"-class removing and for some time no background-image of any div visible but I need at least one image being visible everytime
I need to start the "remove"-class-thing immediately on page load so that there is already one background-image of a random div visible
Here is the current fiddle: http://jsfiddle.net/uRd6N/500/
Thx for your help, I am a noobie and not really familiar with JS / jQuery. If you know a better way to do this whole thing you could tell me too.
Regards
I have taken a look, and updated your Fiddle at http://jsfiddle.net/uRd6N/513/
Some changes I made:
var randomnum = Math.floor(Math.random()*(divlength-1));
Remember, array indexes start at 0, not 1, therefore I made the random number decrement by 1, otherwise your last div in the array would never have been reached.
var divs = $(".me").toArray();
var divlength = divs.length;
I declared these two variables outside of the scope of the setInterval function, to optimize the code a little more.
clearTimeout(doChange);
var doChange = setTimeout(function() {
elements.addClass(className);
}, duration);
I assigned the setTimeout to a variable and cleared it upon each call of the function, to avoid bubbling.
I am still looking into the transition, however another issue I spot is that there is no control mechanism to make sure that the last selected random number does no occur again on the next pick. This will need to be controlled.
Update 1
I have added random first div with background image on load, and removed it with first interval.
Update 2 (Duplicate Random Number Control)
Alright, I have managed to piece together some very simply logic that checks if the chosen random number is a re occurrence of the last chose number, and it decrements or increments the random number by 1, but ALWAYS within the scope of the div count, so it's safe. It's nothing smart, or complex, just simple procedural code. I added console logs, open your console and take a look at it in action. Code is as follows:
console.log("Chosen number is "+randomnum);
if(randomnum == lastnum){
console.log("We have a duplicate ("+randomnum+")");
if( (randomnum-1) >= 0 ){
randomnum = (randomnum-1);
console.log("Duplicate solved, it is now "+randomnum);
}else if( (randomnum+1) <= (divlength) ){
randomnum = (randomnum+1);
console.log("Duplicate solved, it is now "+randomnum);
}
}
lastnum = randomnum;
See the final udpated fiddle at this url: http://jsfiddle.net/uRd6N/537/
Happy coding!
Im currently having a problem with my background image slider. It works perfectly fine the first time it runs, but the second time it 'bumps' the picture to the right when visible, instead of doing that when not visible. I hope some of you would take the time to look into this. Would be appreciated.
The code I'm using :
html part:
<div id="logo">
<img src="images/5.jpg">
<img src="images/6.jpg">
<img src="images/7.jpg">
<img src="images/8.jpg">
<img src="images/9.jpg">
<img src="images/10.jpg">
<img src="images/11.jpg">
</div>
css part:
#logo img {
min-height: 100%;
width:110%;
height: 100%;
position: fixed;
top:0px;
left: 0px;
}
JavaScript:
var slideshow = 0;
var currentImageIndex = 0;
var nextImage = function () {
var $imgs = $('#logo > img');
currentImageIndex++;
if (currentImageIndex > $imgs.length) {
currentImageIndex = 1;
}
$('#logo > img:nth-child(' + currentImageIndex + ')')
.fadeIn(function () { //.fadeIn() .show()
$(this).animate({
left: '-75px'
}, 8000, 'linear')
$(this).delay(100).fadeOut(nextImage), 1200; //.fadeOut() .show()
$(this).css({
left: '0px'
})
})
};
And it's triggered when clicked:
$( ".hexagoncontainer7" ).click(function() {
if (slideshow == 0) {
nextImage();
slideshow=1;
}
});
There are a few things to improve here. Hopefully this will give you a good start:
Currently, you're searching the DOM for your images twice upon each nextImage() call:
var $imgs = $('#logo > img'); and $('#logo > img:nth-child(' + currentImageIndex + ')').
Searching the DOM is computationally expensive, and you should do it only when necessary. Instead, if you need to work with the same elements over and over again (as you do with your images), select them once, and store them in variables for later use.
In the following lines:
$(this).animate({left: '-75px'}, 8000, 'linear')
$(this).delay(100).fadeOut(nextImage), 1200; //.fadeOut() .show()
$(this).css({left: '0px'})
a few things need to be fixed. First, line 3 removes any offset on your images left over from the previous pass. You want this step at the beginning of your sequence of steps (even before fadeIn), not at the end where its effect will be delayed.
Next, you do not need the delay(100) call before fadeOut(), because animate() lets you provide a callback which will be called once the animation completes. Supply your fadeOut code in the callback.
Also, notice that fadeOut first takes duration as a parameter, then the complete callback, i.e. your call should be fadeOut(1200, nextImage) if you want the fade-out effect to execute over 1200 ms.
Finally, jQuery lets you chain functions, which will save you a few calls to the jQuery function.
You should consider removing the click handler on #logo after the first click, to avoid unexpected behavior when users click more than once.
At the moment your images are stacked in reverse order over each other. You need to hide all but the first one with CSS.
Don't forget the semicolons and name your functions as actions, i.e. loadNextImage - your code will be easier to read.
Here is a working fiddle with all the changes: http://jsfiddle.net/stiliyan/4bo0258p/ (forked from the one isherwood posted)
In case you want to learn more best practices with jQuery I strongly recommend the Try jQuery course by CodeSchool.
Sorry for the question isn't very clear, basically
I have got the php code to search for photos in the directory based on the userId given in the url. So if the userId = 1, it will go to Photos/1 and get all the photos in that directory and output it into an array that I can use in Javascript. It works.
I have an external javascript to my php/html code.
I am changing the attr of the div's to display the photos. I have 5 "photo containers" in the array called photodisplay:
var photodisplay =
[
$("#photo1"),
$("#photo2"),
$("#photo3"),
$("#photo4"),
$("#photo5"),
];
Then I have a loop to change the attribute/img src:
function preloadingPhotos() {
for (var x=0; x<galleryarray.length; x++)
{
photodisplay[x].attr("src", "Photos/" + userid + "/" + galleryarray[x]);
console.log("preloaded photos");
}
displayPhoto();
}
It works. Providing no more than 5 photos because that is how many photocontainers I have. But what if I had photos? The question is: Would I be able to do a loop to keep changing the photos in the photodisplay array?
I also have code for the photocontainers to fade in and out:
function displayPhoto(){
photodisplay[0].fadeIn(3000);
photodisplay[0].delay(3000).fadeOut(3000, function() { //first callback func
photodisplay[1].fadeIn(3000);
photodisplay[1].delay(3000).fadeOut(3000, function() { //second callback func
photodisplay[2].fadeIn(3000);
photodisplay[2].delay(3000).fadeOut(3000, function() { //third callback func
photodisplay[3].fadeIn(3000);
photodisplay[3].delay(3000).fadeOut(3000, function() { // fourth callback func
photodisplay[4].fadeIn(3000);
photodisplay[4].delay(3000).fadeOut(3000, function() {
setTimeout(displayPhoto(), 3000);
});
});
});
});
});
}// end of function displayPhoto
Which requires me to manually enter the number of the array of the photodisplay.
I would thinking of adding more to the array with duplications of the photocontainers. But I don't think that would work since I would have to manually enter the number of the array in the code above to make it fade in and out.
Sorry if this is confusing. I tried my best to explain my problem. I hope someone can help. Don't worry about the retrieving images in the directory part, because it works. It increases the array of photos accordingly, I just don't know how to adjust this change with my javascript.
The method you are using, does not scale as you have a callback function for every element in your slideshow.
What you should do, is put all images in a list (or a list of div's) and hide them all / change the z-index so that only the active one shows. The you can loop through your elements using .next() on the list items to get the next one (or the first one if .next().length is 0).
This will clean up your code and is pretty easy to do yourself but there are also loads of jQuery plugins that do it for you.
You need a little bit of abstraction here. So instead of manually code numbers, try another approach. For this example I've used jQuery; since you've tagged your question with it, I assume it's okay:
// Set a default value and store the current photo in it.
var currentPhoto = 0;
// Calculate the total number of photos
var photoTotal = photodisplay.length;
var photoTimeout = false;
// Create a function to go to the next photo
var nextPhoto = function () {
// Keep track of the new current
currentPhoto = (currentPhoto + 1) % photoTotal;
// Just to be sure clearTimeout
clearTimeout(photoTimeout);
// Fadein each photo; you might want to do something to reset the style
photodisplay[0].fadeIn({
duration: 3000,
complete: function () {
photoTimeout = setTimeout(nextPhoto, 3000);
}
});
}
nextPhoto();
You don't want to define JS from the backend like that; just have PHP render the markup, then use JS to query and parse the markup for the presentational layer.
Let's assume your markup looks like this:
<div id="photocontainers">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<!-- A hidden array of images. -->
<div id="images">
<img src="http://placehold.it/100x100&text=1" />
<img src="http://placehold.it/100x100&text=2" />
<img src="http://placehold.it/100x100&text=3" />
<img src="http://placehold.it/100x100&text=4" />
<img src="http://placehold.it/100x100&text=5" />
<img src="http://placehold.it/100x100&text=6" />
<img src="http://placehold.it/100x100&text=7" />
<img src="http://placehold.it/100x100&text=8" />
<img src="http://placehold.it/100x100&text=9" />
<img src="http://placehold.it/100x100&text=10" />
<img src="http://placehold.it/100x100&text=11" />
</div>
So your server renders this; #images is just a hidden container, that basically preloads all the image assets you'll cycle between in #photocontainers.
var cycleImages = function() {
// Cache selectors that we'll need.
var $photoContainers = $('#photocontainers').children(),
$images = $('#images img'),
// Use `.data()` to get the starting point, or set to 0
// (if this is the first time the function ran).
startImage = $images.data('nextImage') || 0;
// Loop from the starting point, filling up the number of
// photocontainers in the DOM.
for (var i = startImage; i < startImage + $photoContainers.length; i++) {
var $targetImage = $images.eq(i % $images.length),
$targetPhotoContainer = $photoContainers.eq(i - startImage);
// Get rid of the current contents.
$targetPhotoContainer.empty();
// Clone the desired image, and append it into place.
$targetImage.clone().appendTo($targetPhotoContainer).fadeOut(0).fadeIn();
}
// Let's figure out which starting image is next up, and store that
// with `.data()`.
var nextImage = startImage + $photoContainers.length;
if (nextImage >= $images.length) {
nextImage -= $images.length;
}
$images.data('nextImage', nextImage);
}
// When the DOM is ready, call the method, then
// call it again however often you'd like.
$(document).ready(function() {
cycleImages();
setInterval(function() {
cycleImages();
}, 3000);
});
Here's a plunkr showing that in action: http://plnkr.co/SumqkXYpRXcOqEhAPOHm
I have 10 divs with class "animate" and IDs from "one" to "ten", for example:
<div class="animate" id="six">
bla bla content
</div>
I need to cycle the visibility of these ten layers in a continuous loop.
The method doesn't have to be very efficient, it just has to work OK.
I have tried running them through a for loop and fade in then fade out them one by one but they all became visible at the same time then faded out together at each iteration.
The code I used for that:
layer_ids = ['one','two','three','four','five','six','seven','eight','nine','ten'];
for(i = 0; i < 300; i++)
{
animate_id = layer_ids[i%10];
element_selector = '.animate#'+animate_id;
$(element_selector).fadeIn(1500).delay(1000).fadeOut(1500);
}
I expected that at the first iteration the first one would be shown then hidden, then the second one, etc.
How can I show then hide them in sequence?
Another thing I'd like to know is how I can run this continuously. I tried with a while(1) but the page froze.
Would rather do this without 3rd party plugins if possible.
Smoothly transitions between content.
Use the setInterval milliseconds value to decide how long you would like to display each section.
Add as many DIVs as needed to the HTML, the code will count them.
Demo: http://jsfiddle.net/wdm954/QDQhu/4/
Any specific reason you want to do this with cycle?
Think the same could be accomplished with much less code:
var els = $("div.animate").hide();
function rotate(){
for (var i=0;i<els.length;i++){
$(els[i]).delay(i*1000).fadeIn(1500).delay(1000).fadeOut(1500);
}
setTimeout(rotate, i*1000);
}
rotate();
Example on jsfiddle, and it isn't restricted to the number of elements.
Version 1, fades in the next element while the currently visible element is still fading out. This looks nice if they're positioned on top of each other.
var roller = $('.animate'),
curr = roller.length-1;
function fadeOut() {
roller.eq(curr).fadeOut(1500, fadeIn);
}
function fadeIn() {
curr = (curr+1) % roller.length;
roller.eq(curr).fadeIn(1500, fadeOut);
}
fadeOut();
http://jsfiddle.net/kaFnb/2/
Version 2, fades the next element in only once the previous element has been faded out. This works well when the content isn't positioned on top of each other (like in the fiddle example).
var roller = $('.animate'),
curr = roller.length-1;
function toggleNextRoller() {
roller.eq(curr).fadeOut(1500);
curr = (curr+1) % roller.length;
roller.eq(curr).fadeIn(1500, toggleNextRoller);
}
toggleNextRoller();
http://jsfiddle.net/kaFnb/1/
I put together a little example for you. hope it helps:
$(function () {
function animateBoxes(targetElement, delay) {
var anims = targetElement;
var numnberOfAnims = anims.size();
anims.eq(0).addClass('visible').fadeIn();
setInterval(function () {
$('.visible').fadeOut(function () {
$(this).removeClass('visible').next().addClass('visible').fadeIn();
if ($(this).index() + 1 == numnberOfAnims) {
anims.eq(0).addClass('visible').fadeIn();
}
});
}, delay);
}
animateBoxes($('.animate'), 2000);
});
Html:
<div class="animate visible">
Content 1
</div>
<div class="animate">
Content 2
</div>
<div class="animate">
Content 3
</div>
<div class="animate">
Content 4
</div>
<div class="animate">
Content 5
</div>
CSS:
.animate
{
display:none;
border:solid 1px red;
padding:30px;
width:300px;
}
First, some visualization of the code.
I have the following images that are dynamically generated from jquery. They're made upon user request:
<img id="i13133" src="someimage.jpg" />
<img id="i13232" src="someimage1.jpg" />
<img id="i14432" src="someimage2.jpg" />
<img id="i16432" src="someimage3.jpg" />
<img id="i18422" src="someimage4.jpg" />
I have an AJAX loop that repeats every 15 seconds using jQuery and it contains the following code:
Note: The if statement is inside the Ajax loop.
Where imgId is the requested ID from the Ajax call.
//Passes the IDs retrieved from Ajax, if the IDs exist on the page the animation is triggered.
if ( $('#i' + imgId ).length )
{
var pickimage = '#i' + imgId;
var stop = false;
function highlight(pickimage) {
$(pickimage).animate({color: "yellow"}, 1000, function () {
$(pickimage ).animate({color: "black"}, 1000, function () {
if (!stop) highlight(pickimage);
});
});
}
// Start the loop
highlight(pickimage);
}
It works great, even with multiple images. But I had originally used this with one image.
The problem is I need an interrupt. Something like:
$(img).click(function () {
stop = true;
});
There's two problems:
1.)This obviously stops all animations. I can't wrap my head around how I could write something that only stops the animation of the image that's clicked.
2.)The Ajax retrieves IDs, sometimes those IDs appear more than once every few minutes, which means it would repeat the animations on top of each other if the image exists. I could use some help figuring out how to detect if an animation is already running on an image, and do nothing if the animation is already triggered on an image.
You can hit two birds with one stone ;)
1) Don't use the stop variable. Add a class to each img:
// Instead of: var stop = false;
$(pickimage).addClass("animating");
// Instead of: if (!stop) highlight(pickimage);
if ($(pickimage).hasClass("animating")) highlight(pickimage);
// Instead of: $(img).click(function () { stop = true; });
$(img).click(function () { $(this).removeClass("animating"); });
2) Same thing, check the class!
if ($(pickimage).hasClass("animating")) return;