Multiple Image fadeIn onLoad (at the same time) - javascript

I want to fade in multiple images at the same time as the page loads. Just like this website does it: http://www.struckaxiom.com/work. I have the script to do it only on one image, but I want to have more images included.
This is the single photo script. Please help.
document.write("<style type='text/css'>#thephoto {visibility:hidden;}</style>");
function initImage() {
imageId = 'thephoto'
image = document.getElementById(imageId);
setOpacity(image, 0);
image.style.visibility = "visible";
fadeIn(imageId,ImageId2,0);
}
function fadeIn(objId, opacity) {
if (document.getElementById) {
obj = document.getElementById(objId);
if (opacity <= 100) {
setOpacity(obj, opacity);
opacity += 10;
window.setTimeout("fadeIn('"+objId+"',"+opacity+")", 100);
}
}
}
function setOpacity(obj, opacity) {
opacity = (opacity == 100)?99.999:opacity;
// IE/Win
obj.style.filter = "alpha(opacity:"+opacity+")";
// Safari<1.2, Konqueror
obj.style.KHTMLOpacity = opacity/100;
// Older Mozilla and Firefox
obj.style.MozOpacity = opacity/100;
// Safari 1.2, newer Firefox and Mozilla, CSS3
obj.style.opacity = opacity/100;
}
window.onload = function() {initImage()}
// -->
</script>
Thanks!

Simple array and loop are all you need.
First, add such array on top of the code:
var images = [ "thephoto1", "thephoto2", "thephoto3" ];
(With the ID of all desired images)
Next change the function name to initImages to reflect the fact it will initialize more than one image and finally add that loop:
function initImages() {
for (var i = 0; i < images.length; i++) {
imageId = images[i];
image = document.getElementById(imageId);
setOpacity(image, 0);
image.style.visibility = "visible";
fadeIn(imageId, 0);
}
}
That's it, no need to touch the other functions.
Live test case with cute cats: http://jsfiddle.net/yahavbr/e863X/ :-)

You could just wrap all of your images in a single container like this:
<div id="imageContainer">
<img src="img1.jpg">
<img src="img2.jpg">
<img src="img2.jpg">
</div>
Change your CSS to this:
<style type='text/css'>#imageContainer {visibility:hidden;}</style>
Change your first function to this:
function initImage() {
containerId = 'imageContainer'
container = document.getElementById(containerId);
setOpacity(container, 0);
container.style.visibility = "visible";
fadeIn(containerId,0);
}
By running the fading effect on the container you can then add as much content to the container and it will all fade in together and you never have to update your code.

The way they are doing is using jQuery (an excellent implementation). All of the images are in the same container and are selected using the jQuery class selector. Then they fade in all elements that fit within the viewable area. Their js file is not minimized so you could reverse engineer most of that functionality. The important thing to note is not that it is showing each row at a time but every element that fits in the viewing area. Their key function looks like this:
var elTop = $(el).offset().top - $(window).scrollTop();
var elHeight = $(el).height();
// if between top of footer and top of window
if (elTop + elHeight > 40 && elTop < $(window).height()) {
if ($.inArray($(el).attr("data-unique-id"), elementsInView) < 0) {
addToView(el);
}
} else {
if ($.inArray($(el).attr("data-unique-id"), elementsInView) >= 0) {
removeFromView(el);
}
}
addToView and removeFromView add and remove the element from an array, then fade is executed on the array.

Related

Current image flickers back after fade out in javascript carousel

I am building a image carousel with fade in/out animation with javascript and jquery.
Before the next images fades in, the current image shows up briefly although it's faded out. This happens even though I use onload to make sure the next image is loaded and sized properly.
(The live code is: www.jbkphotographs.com/nepal.html)
function moveToNextImg(){
if(current === imgArray.length-1){
current = 0;
}
else{
current++;
}
updateIndex();
//#imgWrapper is <div> that contains <img>
$("#imgWrapper").fadeOut("slow",loadImg);
}
function loadImg(){
imgName = imgArray[current].getAttribute("src");
nextImg.src = imgName.replace("_Thumb","");
nextImg.id = "currentImg";
nextImg.onload = function(){
if((nextImg.height) > (nextImg.width)){
nextImg.style.width = "42.5%"
}
else{
nextImg.style.width = '750px';
}
imgWrapper.appendChild(nextImg);
}
$("#imgWrapper").fadeIn("slow");
}
I saw it. You have that effects befause you are fading in the image before it has been loaded.
a) You should preload the images , before sliding to have the fadein
fadeout effect
b) Otherwise put the fade in effect in the onload
callback of the images:
function moveToNextImg(){
if(current === imgArray.length-1){
current = 0;
} else {
current++;
}
updateIndex();
//#imgWrapper is <div> that contains <img>
$("#imgWrapper").fadeOut("slow",loadImg);
}
function loadImg(){
imgName = imgArray[current].getAttribute("src");
nextImg.src = imgName.replace("_Thumb","");
nextImg.id = "currentImg";
//This code will run only when images will be loaded
nextImg.onload = function(){
if((nextImg.height) > (nextImg.width)){
nextImg.style.width = "42.5%"
}
else{
nextImg.style.width = '750px';
}
imgWrapper.appendChild(nextImg);
$("#imgWrapper").fadeIn("slow");
}
//any code here will run immediately before the onload runs
}

Load blocking jQuery animate

I have built a gallery viewer with a preload function.
The preload function is as follows:
$.preloadFullImages = function() {
// Create array of images
var set = [];
$('.slide-item img').each(function() {
var img = $(this).data('src');
var id = $(this).parent().attr('id');
$(this).remove();
set.push([img,id]);
});
// Set current image
var current = 0;
var iterate = function() {
var current_src = set[current][0];
var current_id = set[current][1];
var temp = '<img src="'+current_src+'" />';
var target = '#'+current_id;
var targetImg = '#'+current_id+' img';
// Load 'temp' image
$(temp).bind('load', function() {
// Show image
$(target).append(temp);
$(targetImg).show();
$(this).remove();
});
if ( ++current < set.length ) iterate();
};
iterate();
};
On load of the page, images are loaded sequentially.
The problem is until all the images are loaded, the animation between images (prev and next arrows) is stunted and doesn't work correctly. I want the gallery viewer to transition smoothly between slides (images) even if not all images are loaded.
You can see a live demo here: http://www.davidclapp.net/portfolio
The issue is especially apparent on the iPhone (safari).
Is there a way to ensure the animation is smooth even whilst images are still loading?
Edit: I am using this plugin for CSS3 transitions - http://ricostacruz.com/jquery.transit/
$.preloadFullImages = function(callback) {
...
if ( ++current < set.length ) iterate();
else if(callback) callback(); //check if callback exists, then call it.
};
iterate();
};
These two lines being the important part.
$.preloadFullImages = function(callback) {
if ( ++current < set.length ) iterate();
else callback();
make a function to call the beginning of your animation, pass it to "preloadFullImages"

Initializing a plugin AFTER a foreach loop

So I'm trying to implement stellar.js but it must be initialized after an each loop is finished. The loop must add data attributes to the images that are going to be made parallax by the plugin.
The images are in a list:
<ul>
<li class="item">
<div class="item-image" data-stellar-background-ratio="0.7" data-image="http://picjumbo.picjumbocom.netdna-cdn.com/wp-content/uploads/IMG_7706-1300x866.jpg"></div>
</li>
...
</ul>
I must add data-stellar-vertical-offset attribute to each of them that will offset the image by half of its height, so it can be vertically centered initially.
Here is the JS:
/* Inserting the background image */
$('.item-image').each(function () {
var $this = $(this);
$this.css('background-image', 'url(' + $this.data('image') + ')');
})
/* Creating loop that will run as many times as items are in there */
var items = $('.item-image').length;
var currentItem = 0;
$('.item-image').each(function () {
var $this = $(this);
/* Taking the origin height, halving it and putting it as offset so the image can be vertically aligned */
var img = new Image();
img.src = $(this).data('image');
img.onload = function () {
var H2 = this.height;
$this.attr('data-stellar-vertical-offset', -(H2 / 2));
}
currentItem++;
/* Initializing the plugin after every item is looped */
if (currentItem >= items) {
$.stellar();
}
})
However when the plugin is initialized it isn't using the data attribute. If it's put in a timeout like this:
if (currentItem >= items) {
setTimeout(function () {
$.stellar();
}, 10)
}
.. it works but it seems to me like an ugly hack. Is there a better way for this to be done?
Here is a jsfiddle: http://jsfiddle.net/9f2tc/1/
I believe what you want is to initialize stellar once after all the images have been downloaded. The simplest approach is to check each time in the onload handler:
img.onload = function () {
var H2 = this.height;
$this.attr('data-stellar-vertical-offset', -(H2 / 2))
if (++currentItem === items) {
$.stellar();
}
}
jsfiddle: http://jsfiddle.net/X6e9n/2/
However, there are issues with the onload event not firing for images in certain cases. See the caveats section on the jQuery page: http://api.jquery.com/load-event/ The problems listed apply to the load event itself not just jQuery's .load() See Javascript callback for knowing when an image is loaded for solutions. The first answer notes the handler should be attached before the src attribute is set, which you don't do here, but it doesn't seem to be a problem for me in this case.

Reset size of all images in a class

I've searched the forums already but I couldn't find anything like this specifically.
I have a page set up with a bunch of images (gallery type thing) and when they user clicks on an image it will change size from the 200x200 thumbnail to the full sized 600x600.
My issue is that one can continue to click these images and the previous one will remain the enlarged. I would like to limit the amount of expanded images to one.
This is the javascript:
function toggleSize(image) {
if (image.style.width != "600px") {
image.style.width = "600px";
image.style.height = "600px";
} else {
image.style.width = "200px";
image.style.height = "200px";
}
and the html for each image is as follows:
<img class="galleryImage" src="../m/54.jpg" onclick="toggleSize(this)" />
the galleryImage class looks like this:
.galleryImage {
margin: -2px -2px -3px -2px;
width: 200px;
height: 200px;
}
So essentially, in theory, I would want every element of the class galleryImage to reset to its original width and height of 200x200.
Any help would be greatly appreciated.
You can search all your images with a given class (and discard the current) using getElementsByClassName and by looping the result resume them to the starting state.
Returns an array of all child elements which have any of the given
class names. When called on the document object, the complete document
is searched, including the root node. You may also call
getElementsByClassName() on any element; it will return only elements
which are descendants of the specified root element with the given
class names.
After this, you can call your toggle function.
Code:
function resetImages(classToFind, image) {
var elems = document.getElementsByClassName(classToFind);
if (!elems) return;
for (var i = elems.length - 1; i >= 0; i--) {
var elem = elems[i];
if (elem === image) continue
elem.style.width = "200px";
elem.style.height = "200px";
}
}
function toggleSize(image) {
resetImages('galleryImage',image);
if (image.style.width != "600px") {
image.style.width = "600px";
image.style.height = "600px";
} else {
image.style.width = "200px";
image.style.height = "200px";
}
}
Demo: http://jsfiddle.net/IrvinDominin/DfSbT/
This is a jquery solution, code not tested. But image resize will work as you expected.
function toggleSize(image) {
// Get the current image size
var currentImageHeight = $(image).height();
// If it is 600, that means user clicked on a enlarged thumbnail
// Just resize it
if(currentImageHeight == 600){
$(image).width(200);
$(image).height(200);
}
// User clicked on other thumbnail. Resize previously enlarged thumbs
else{
$('.galleryImage').width(200);
$(image).width(600);
$(image).height(600);
}
}

toggle body background

I hope someone can help me with this, I have this javascript code that toggles my body background
function changeDivImage() {
imgPath = document.body.style.backgroundImage;
if (imgPath == "url(images/bg.jpg)" || imgPath == "") {
document.body.style.backgroundImage = "url(images/bg_2.jpg)";
} else {
document.body.style.backgroundImage = "url(images/bg.jpg)";
}
}
I activate it with this link:
change
my problem is that it works fine in IE and firefox, but in chrome, the links work twice then stop working, it basically switches to bg_2.jpg then once clicked again switches back to bg.jpg then it never works again :/
also, is there an easier way to accomplish this? css only maybe? basically i have two body background pictures and i want to be able to click on the link to toggle 1, then click again to toggle 2 instead, then back to 1, etc...
lastly, how can i make the two backgrounds fade in and out? instead of just switch between the two?
Use CSS classes!
CSS Rules
body { background-image: url(images/bg.jpg); }
body.on { background-image: url(images/bg_2.jpg); }
JavaScript:
function changeDivImage() {
$("body").toggleClass("on");
}
If you want to fade, you will end up having to fade the entire page. Use can use jQuery's fadeIn and fadeOut.
Here is your solution:
(This also supports additional images).
var m = 0, imgs = ["images/bg.jpg", "images/bg_2.jpg"];
function changeDivImage()
{
document.body.style.backgroundImage = "url(" + imgs[m] + ")";
m = (m + 1) % imgs.length;
}
Here is the working code on jsFiddle.
Here is the jQuery version on jsFiddle.
UPDATE: CROSS-FADING Version
Here is the cross-fading jQuery version on jsFiddle.
You wouldn't want the whole page (with all elements) to fade in/out. Only the bg should fade. So, this version has a div to be used as the background container. Its z-depth is arranged so that it will keep itself the bottom-most element on the page; and switch between its two children to create the cross-fade effect.
HTML:
<div id="bg">
<div id="bg-top"></div>
<div id="bg-bottom"></div>
</div>
<a id="bg-changer" href="#">change</a>
CSS:
div#bg, div#bg-top, div#bg-bottom
{
display: block;
position: fixed;
width: 100%;
/*height: 500px;*/ /* height is set by javascript on every window resize */
overflow: hidden;
}
div#bg
{
z-index: -99;
}
Javascript (jQuery):
var m = 0,
/* Array of background images. You can add more to it. */
imgs = ["images/bg.jpg", "images/bg_2.jpg"];
/* Toggles the background images with cross-fade effect. */
function changeDivImage()
{
setBgHeight();
var imgTop = imgs[m];
m = (m + 1) % imgs.length;
var imgBottom = imgs[m];
$('div#bg')
.children('#bg-top').show()
.css('background-image', 'url(' + imgTop + ')')
.fadeOut('slow')
.end()
.children('#bg-bottom').hide()
.css('background-image', 'url(' + imgBottom + ')')
.fadeIn('slow');
}
/* Sets the background div height to (fit the) window height. */
function setBgHeight()
{
var h = $(window).height();
$('div#bg').height(h).children().height(h);
}
/* DOM ready event handler. */
$(document).ready(function(event)
{
$('a#bg-changer').click(function(event) { changeDivImage(); });
changeDivImage(); //fade in the first image when the DOM is ready.
});
/* Window resize event handler. */
$(window).resize(function(event)
{
setBgHeight(); //set the background height everytime.
});
This could be improved more but it should give you an idea.
There's a cleaner way to do this. As a demo, see:
<button id="toggle" type="button">Toggle Background Color</button>
var togglebg = (function(){
var bgs = ['black','blue','red','green'];
return function(){
document.body.style.backgroundColor = bgs[0];
bgs.push(bgs.shift());
}
})();
document.getElementById('toggle').onclick = togglebg;
http://jsfiddle.net/userdude/KYDKG/
Obviously, you would replace the Color with Image, but all this does is iterate through a list that's local to the togglebg function, always using the first available. This would also need to run window.onload, preferably as a window.addEventListener/window.attachEvent on the button or elements that will trigger it to run.
Or with jQuery (as I notice the tag now):
jQuery(document).ready(function ($) {
var togglebg = (function () {
var bgs = ['black', 'blue', 'red', 'green'];
return function () {
document.body.style.backgroundColor = bgs[0];
bgs.push(bgs.shift());
}
})();
$('#toggle').on('click', togglebg);
});
http://jsfiddle.net/userdude/KYDKG/1/
And here is a DummyImage version using real images:
jQuery(document).ready(function ($) {
var togglebg = (function () {
var bgs = [
'000/ffffff&text=Black and White',
'0000ff/ffffff&text=Blue and White',
'ffff00/000&text=Yellow and Black',
'ff0000/00ff00&text=Red and Green'
],
url = "url('http://dummyimage.com/600x400/{img}')";
return function () {
document.body.style.backgroundImage = url.replace('{img}', bgs[0]);
bgs.push(bgs.shift());
}
})();
$('#toggle').on('click', togglebg);
});
http://jsfiddle.net/userdude/KYDKG/2/

Categories