Need to solve problem with asynchronous code - javascript

I made a small game where there are 3 pictures of chests, and you have one attempt to choose a chest with a prize.
But the problem is with the asynchronous code, a notification of defeat or victory is displayed faster than the desired picture is put in the right place, After the message, a function that puts all the chests closed that also does not allow the picture to take its place.
var count=0;
var imgArray = new Array();
imgArray[0] = new Image();
imgArray[0].src ='https://i.pinimg.com/originals/ae/f7/15/aef715f93eadcdf77c4dfa3baf5859ad.jpg'
imgArray[1] = new Image();
imgArray[1].src = "https://previews.123rf.com/images/gl0ck33/gl0ck331106/gl0ck33110600002/9781614-wooden-chest-with-gold-coins.jpg";
imgArray[2] = new Image();
imgArray[2].src = "https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg";
var images = document.getElementsByTagName("img");
var k = Math.floor(Math.random() * 3) + 1;
console.log("Winning number " + k);
for (var i = 0; i < images.length; i++) {
images[i].addEventListener("click", function(e) {
count++;
console.log("Count " + count);
if(this.id == k){
count=0;
this.src = imgArray[1].src;//here picture with a gift
alert("You Win");// here problem,alert Faster than the picture above
TryAgain();//And this function is faster to put pictures with closed chests
return;
} else {
this.src = imgArray[0].src;//picture empty chest
}
if (count >= 1) {
count = 0;
alert("You lose!!!");//alert Faster than the picture above
TryAgain();
return;
}
}, false);
}
function TryAgain(e) {
for (var i = 0; i < images.length; i++){
images[i].src = imgArray[2].src;//picture with close chest
k = Math.floor(Math.random() * 3) + 1;
}
console.log(k);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="1">
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="2">
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="3">
<button id="btn" onclick="TryAgain()">Try Again</button>
</body>
</html>

Answer:
You need to wait for the images to get done loading before running alert.
alert completely halts the processing of code. Therefore if the image isn't loaded before it is executed you're not going to see the change occur.
A simple pattern to do this would be:
let self = this;
this.src = imgArray[1].src;
this.onload = function() {
alert("You Win");
self.onload = undefined;
TryAgain();
}
return;
Example:
var count=0;
var imgArray = new Array();
imgArray[0] = new Image();
imgArray[0].src ='https://i.pinimg.com/originals/ae/f7/15/aef715f93eadcdf77c4dfa3baf5859ad.jpg'
imgArray[1] = new Image();
imgArray[1].src = "https://previews.123rf.com/images/gl0ck33/gl0ck331106/gl0ck33110600002/9781614-wooden-chest-with-gold-coins.jpg";
imgArray[2] = new Image();
imgArray[2].src = "https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg";
var images = document.getElementsByTagName("img");
var k = Math.floor(Math.random() * 3) + 1;
console.log("Winning number " + k);
for (var i = 0; i < images.length; i++) {
images[i].addEventListener("click", function(e) {
let self = this;
count++;
console.log("Count " + count);
if(this.id == k){
count=0;
this.src = imgArray[1].src;//here picture with a gift
this.onload = function() {
alert("You Win");// here problem,alert Faster than the picture above
self.onload = undefined;
TryAgain();//And this function is faster to put pictures with closed chests
}
return;
} else {
this.src = imgArray[0].src;//picture empty chest
this.onload = function() {
alert("You Lose");// here problem,alert Faster than the picture above
self.onload = undefined;
TryAgain();//And this function is faster to put pictures with closed chests
}
return;
}
}, false);
}
function TryAgain(e) {
for (var i = 0; i < images.length; i++){
images[i].src = imgArray[2].src;//picture with close chest
k = Math.floor(Math.random() * 3) + 1;
}
console.log(k);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="1">
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="2">
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="3">
<button id="btn" onclick="TryAgain()">Try Again</button>
</body>
</html>

Images do not appear as soon as you set this.src
They appear when the browser is ready to show them, which may take some time.
Perhaps you can use the "load" event listener? This will fire once the image is visible. At that stage you can do the alert?
images[i].addEventListener("load", function(e) {
// This will run only once the image is loaded (i.e. visible)
} )

Related

How do I get the slideshow to disappear after one cycle through (javascript)

this intro slideshow works so far, it starts automatically when you load the webpage and cycles through the 4 photos. But I want the slideshow to disappear (to reveal the website homepage underneath) after it has cycled through the 4 photos only once, but need some help how to proceed forward.
<!DOCTYPE html>
<head>
</head>
<body>
<div id="slideshow">
<img id="pic" width="100%" height="auto" alt="Icon" src="one.jpg">
</div>
<script>
var i, imgs, pic;
function rotate() {
pic.src = imgs[i];
(i === (imgs.length - 1)) ? (i = 0) : (i++);
setTimeout(rotate, 1000);
}
function init() {
pic = document.getElementById("pic");
imgs = ["one.jpg", "two.jpg", "three.jpg", "four.jpg"];
var preload = new Array();
for (i = 0; i < imgs.length; i++) {
preload[i] = new Image();
preload[i].src = imgs[i];
}
i = 0;
rotate();
}
document.addEventListener("DOMContentLoaded", init, false);
</script>
</body>
</html>
var count = 0
function rotate() {
pic.src = imgs[i];
(i === (imgs.length - 1)) ? (i = 0) : (i++);
if (count < imgs.length) {
count++;
setTimeout(rotate, 1000);
} else {
document.getElementById("slideshow").style.display = 'none';
}
}
Hi,
you have to count your number of slides. Afterwards just check if you already finished.
greetings
<!DOCTYPE html>
<head>
</head>
<body>
<div id="slideshow">
<img id="pic" width="100%" height="auto" alt="Icon" src="one.jpg">
</div>
<script>
var i, imgs, pic;
function rotate() {
pic.src = imgs[i];
if(i<(imgs.length - 1)){
i++;
setTimeout(rotate, 1000);
}
}
function init() {
pic = document.getElementById("pic");
imgs = ["one.jpg", "two.jpg", "three.jpg", "four.jpg"];
var preload = new Array();
for (i = 0; i < imgs.length; i++) {
preload[i] = new Image();
preload[i].src = imgs[i];
}
i = 0;
rotate();
}
document.addEventListener("DOMContentLoaded", init, false);
</script>
</body>
</html>
if(i<(imgs.length - 1)){
i++;
setTimeout(rotate, 1000);
}
You need to check for how many time the rotate() method need to call.

Javascript Next and Previous images

Code is supposed to show next image when clicking on next arrow and previous image when clicked on previous arrow. It does not work though. (error occurs while assigning img.src=imgs[this.i]; it says Cannot set property 'src' of null
at collection.next) .
Javascript code :
var arr = new collection(['cake.png', 'image2.png', 'image3.png', 'image1.png']);
function collection(imgs) {
this.imgs = imgs;
this.i = 0;
this.next = function(element) {
var img = document.getElementById('element')
this.i++;
if (this.i == imgs.length) {
this.i = 0;
}
img.src = imgs[this.i].src;
}
this.prev = function(element) {
var img = document.getElementById('element');
this.i--;
if (this.i < 0) {
this.i = imgs.length - 1;
}
img.src = imgs[this.i].src;
}
}
<!DOCTYPE html>
<html>
<head>
<title>photos</title>
<script src="photos.js"></script>
</head>
<body>
<input type='button' value='<' name='next' onclick="arr.next('mainImg')" />
<img id='mainImg' src="cake.png">
<input type='button' value='>' name='prev' onclick="arr.prev('mainImg')" />
</body>
</html>
Not using jquery. I do not have enough experience in js either. Thank you for your time
You had three mistakes:
You referenced the images as img.src = imgs[this.i].src; and you just had an array of strings, not an array of objects with a src property. img.src = imgs[this.i]; is the correct way to get the URL.
You used
var img = document.getElementById('element');
when you should have used
var img = document.getElementById(element);
element is an argument coming from your onclick event. It holds the id of your image that you should be using. "element" is just a string. You try to find an element with id equal to element which doesn't exist.
Edit: You should also use < and > to represent < and >. Otherwise your HTML might get screwed up. More on that here.
var arr = new collection(['http://images.math.cnrs.fr/IMG/png/section8-image.png', 'https://www.w3.org/MarkUp/Test/xhtml-print/20050519/tests/jpeg444.jpg', "http://saturnraw.jpl.nasa.gov/multimedia/images/raw/casJPGFullS72/N00183828.jpg"]);
function collection(imgs) {
this.imgs = imgs;
this.i = 0;
this.next = function(element) {
var img = document.getElementById(element);
this.i++;
if (this.i >= imgs.length) {
this.i = 0;
}
img.src = imgs[this.i];
};
this.prev = function(element) {
var img = document.getElementById(element);
this.i--;
if (this.i < 0) {
this.i = imgs.length - 1;
}
img.src = imgs[this.i];
};
this.next("mainImg"); // to initialize with some image
}
<!DOCTYPE html>
<html>
<head>
<title>photos</title>
<script src="photos.js"></script>
</head>
<body>
<input type='button' value='<' name='next' onclick="arr.next('mainImg')" />
<img id='mainImg' src="cake.png">
<input type='button' value='>' name='prev' onclick="arr.prev('mainImg')" />
</body>
</html>
This is how I'd personally do it:
var myCollection = new Collection([
"http://images.math.cnrs.fr/IMG/png/section8-image.png",
"https://www.w3.org/MarkUp/Test/xhtml-print/20050519/tests/jpeg444.jpg",
"http://saturnraw.jpl.nasa.gov/multimedia/images/raw/casJPGFullS72/N00183828.jpg"
], "mainImg");
document.getElementById("next_btn").onclick = function() {
myCollection.next();
};
document.getElementById("prev_btn").onclick = function() {
myCollection.prev();
}
function Collection(urls, imgID) {
var imgElem = document.getElementById(imgID);
var index = 0;
this.selectImage = function() {
imgElem.src = urls[index];
};
this.next = function() {
if (++index >= urls.length) {
index = 0;
}
this.selectImage();
};
this.prev = function(element) {
if (--index < 0) {
index = urls.length - 1;
}
this.selectImage();
};
// initialize
this.selectImage();
}
<!DOCTYPE html>
<html>
<head>
<title>photos</title>
<script src="photos.js"></script>
</head>
<body>
<input id="next_btn" type='button' value='<' />
<img id='mainImg'>
<input id="prev_btn" type='button' value='>' />
</body>
</html>
Why sending string into arr.next('mainImg') function ?
your img element always have the same id, only change src.
and document.getElementById(element) is also the same img element.
html: <img id='mainImg' src="cake.png">
js: document.getElementById('mainImg')
consider img element as a container, and id is it's identifiler.
var start_pos = 0;
var img_count = document.getElementsByClassName('icons').length - 1;
var changeImg = function(direction){
pos = start_pos = (direction == "next")? (start_pos == img_count)? 0 : start_pos+1 : (start_pos == 0)? img_count : start_pos-1;
console.log(pos)
}
document.getElementById('left').onclick = function(){ changeImg("previous"); }
document.getElementById('right').onclick = function(){ changeImg("next"); }

Javascript image to div

So I am able to retrieve the images from instagram but I want the individual images to go into my gallery container div which I got a problem with. I have directed the images to the class "html5gallery" but the images does not goes in like other image urls :
<!-- Reference to html5gallery.js -->
<script type="text/javascript" src="../html5gallery/html5gallery.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery-instagram/0.2.2/jquery.instagram.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery-instagram/0.2.2/jquery.instagram.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
<script>
(function ($) {
var userId = "19410587";
var accessToken = "574298972.d868eb6.bab9c8fe820c4d4c80724edfb86236bd";
var numDisplay = "4";
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: "https://api.instagram.com/v1/users/"+userId+"/media/recent/?access_token="+accessToken,
success: function(data) {
var imgURL = '';
for (var i = 0; i < numDisplay; i++) {
var gallery = document.getElementById("html5gallery");
var img = new Image();
img.onload = function() {
document.getElementById('gallery').appendChild(img);
};
img.src = data.data[i].images.low_resolution.url;
imgURL += img.src + ' ';
$(".insta").append("<div class='instaBox'><a target='_blank' href='" + data.data[i].link +"'><img class='instagram-image' src='" + data.data[i].images.low_resolution.url +"' width='98' /></a></div>");
}
alert(imgURL);
}
});
})(jQuery);
</script>
<div style="display:none;margin:0 auto; " class="html5gallery" data-skin="horizontal" data-width="1200" data-height="680" >
<!-- Add images to Gallery -->
<a href="#" onload="javascript:document.img.src='data.data[i].images.low_resolution.url'">
<img src="images/Tulip_small.jpg" alt="Tulips">
<img src="images/Colourful_Tulip_small.jpg" alt="Colourful Tulips">
<img src="images/Swan_small.jpg" alt="Swan on Lake">
<img src="images/Red_Tulip_small.jpg" alt="Red Tulips">
<img src="images/Sakura_Tree_small.jpg" alt="Sakura Trees">
<img src="http://img.youtube.com/vi/1oHWvFrpocY/2.jpg" alt="Youtube Video">
<!-- Add Youtube video to Gallery -->
<img src="http://img.youtube.com/vi/ofr5EE9GsUs/2.jpg" alt="Youtube Video">
<!-- Add Youtube video to Gallery -->
<img src="http://img.youtube.com/vi/9bZkp7q19f0/2.jpg" alt="Youtube Video">
</div>
Change the class attribute to id or add the id attribute id="html5gallery"
<div style="display:none;margin:0 auto; "
class="html5gallery" id="html5gallery"
data-skin="horizontal" data-width="1200"
data-height="680" >
EDIT:
Try this to append image
var imgURL = '';
var gallery = $("#html5gallery");
for (var i = 0; i < numDisplay; i++) {
var img = new Image();
img.onload = (function(im) {
return function () {
gallery.append(im);
}
})(img);
img.src = data.data[i].images.low_resolution.url;
imgURL += img.src + ' ';
$(".insta").append("<div class='instaBox'><a target='_blank' href='" + data.data[i].link +"'><img class='instagram-image' src='" + data.data[i].images.low_resolution.url +"' width='98' /></a></div>");
}
I've never used the instagram API before, but I think this is what you want to achieve (code below). I've included both a Vanilla Javascript method as well as a jQuery method (so you can pick and use whichever one you prefer - vanilla is faster of course)
(function ($, window) {
var userId = "19410587";
var accessToken = "574298972.d868eb6.bab9c8fe820c4d4c80724edfb86236bd";
var numDisplay = "4";
// Define the gallery variable outside the for loop (performance)
// Vanilla JS
var galleryHTML = document.getElementById("html5gallery");
// jQuery
var $galleryHTML = $('#html5gallery');
// Moved the gallery outside of the for loop (performance, again)
var gallery = document.getElementById('gallery');
var insta = $('.insta');
// or var insta = document.getElementsByClassName('insta')[0] for vanilla JS
// create a function to do the fancy ajax
var fetchInstagram = function() {
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: "https://api.instagram.com/v1/users/"+userId+"/media/recent/?access_token="+accessToken,
success: function(data) {
for (var i = 0; i < numDisplay; i++) {
// I don't think you need the onload function here
// img.onload = function() {
// document.getElementById('gallery').appendChild(img);
// };
// Not sure what this is, but I don't think you need it (for what you want to do)
// $(".insta").append("<div class='instaBox'><a target='_blank' href='" + data.data[i].link +"'><img class='instagram-image' src='" + data.data[i].images.low_resolution.url +"' width='98' /></a></div>");
// Create the new image object
var newImage = document.createElement('img');
newImage.src = data.data[i].images.low_resolution.url;
// Insert the images into html5gallery
// Vanilla Javascript Way
// galleryHTML.appendChild(newImage);
// jQuery Way
// var $newImage = $(newImage);
// $galleryHTML.append($newImage);
}
}
});
};
// Making the function available in window for global use
window.fetchInstagram = fetchInstagram;
})(jQuery, window);
// Initiate the function
fetchInstagram();
// You can bind the function to other stuff like.. if you click a button
// $('#load-more').on('click', fetchInstagram);
I was able to get the 4 images to load in a div with the id of html5gallery on my end. Hope this helps!
If the human eye can only see 24fps or 30fps or more when playing a game or watching tv, I believe a programer can use less DIVs in HTML within the screen size, with a Javascript array of 3 million colors for a couple of DIVs and cheat it's position(because of our human eyes), based in a timer event with a bunch of frames per second than the ones I mentioned, example 1 millisecond. In my opinion this is something which I would like to test, if it's the question that drives us let the answer be our destination.
This is the fiddle so far: DEMO
<html>
<head>
<title></title>
<style>#placeDiv{position:absolute;left:0px;width:100px;height:100px;}
#placeDiv1{position:absolute;left:100px;width:100px;height:100px;}
#placeDiv2{position:absolute;left:200px;width:100px;height:100px;}
#b1{position:absolute;top:100px;left:0px}
#b2{position:absolute;top:100px;left:80px}
#b3{position:absolute;top:100px;left:170px}
#b4{position:absolute;top:100px;left:270px}
#b5{position:absolute;top:100px;left:320px}
</style>
</head>
<body>
<div id = "placeDiv">ok</div><div id = "placeDiv1">ok</div><div id = "placeDiv2">ok</div>
<button id="b1" onclick="forward()">Forward</button>
<button id="b2" onclick="backward()">Backward</button>
<button id="b3" onclick="skip2()">skip2</button>
<button id="b4" onclick="automatic()">auto</button>
<button id="b5" onclick="stop()">stop</button>
<script>
var myArray = ["black","yellow","green","red","blue","blue","black","gray"];
var myArray1 = ["yellow","blue","green","red","green","blue","black","gray"];
var myArray2 = ["yellow","blue","green","red","green","blue","black","gray"];
var i = 0;
document.getElementById("placeDiv").style.backgroundColor = myArray[i];
document.getElementById("placeDiv1").style.backgroundColor = myArray1[i];
document.getElementById("placeDiv2").style.backgroundColor = myArray2[i];
forward=function(){
if(i == myArray.length-1)
{i=0;}
else
{i=i+1;}
document.getElementById("placeDiv1").style.backgroundColor = myArray1[i];
document.getElementById("placeDiv").style.backgroundColor = myArray[i];
document.getElementById("placeDiv2").style.backgroundColor = myArray2[i];
}; skip2=function(){
if(i == myArray.length-4)
{i+=2;alert("This is the iterator "+i)}else if(i==7){i=0}else{i=i+1;};
document.getElementById("placeDiv1").style.backgroundColor = myArray1[i];
document.getElementById("placeDiv").style.backgroundColor = myArray[i];
};
backward=function(){
if(i == 0)
{i=myArray.length-1;i=myArray1.length-1;}
else
{
i=i-1;
}
document.getElementById("placeDiv1").style.backgroundColor = myArray1[i];
document.getElementById("placeDiv").style.backgroundColor = myArray[i];
//
}
var m=null;
automatic=function(){
clearInterval(m)
m = setInterval(function(){
if(i == myArray.length-1)
{i=0;}
else
{i=i+1;}
document.getElementById("placeDiv1").style.backgroundColor = myArray1[i];
document.getElementById("placeDiv").style.backgroundColor = myArray[i];
},1);
function b(x,y){
var a =setInterval(function(){document.getElementById("placeDiv").style.left=x+++"px";if (x==100){d();clearInterval(a);}},10);
function d(){var z = setInterval(function(){document.getElementById("placeDiv").style.left=x--+"px";if (x==0){c();clearInterval(z);}},10);}
function c(){var g = setInterval(function(){document.getElementById("placeDiv").style.left=x+++"px";if(x==100){d();clearInterval(g)}},10)};
//Aqui uma copia.
var v =setInterval(function(){document.getElementById("placeDiv").style.top=y+++"px";if (y==100){h();clearInterval(v);}},10);
function h(){var l = setInterval(function( {document.getElementById("placeDiv").style.top=y--+"px";if (y==0){ok();clearInterval(l);}},10);}
function ok(){var ja = setInterval(function( {document.getElementById("placeDiv").style.top=y+++"px";if(y==100 {h();clearInterval(ja)}},10)};
}
b(0,0);
stop=function(){clearInterval(m)};
};
</script>
</body>
</html>

loop a series of image in javascript

i want to loop a series of images in javascript. below is the code i have so far
<html>
<head>
</head>
<body>
<img src="images/image1.jpg" alt="rotating image" width="600" height="500" id="rotator">
<script type="text/javascript">
(function() {
var rotator = document.getElementById('rotator'); // change to match image ID
//var imageDir = 'images/'; // change to match images folder
var delayInSeconds = 1; // set number of seconds delay
// list image names
var images = ['1.jpg','2.jpg', '3.jpg', '4.jpg'];
// don't change below this line
var num = 0;
var changeImage = function() {
var len = images.length;
rotator.src = images[num++];
if (num == len) {
num = 0;
}
};
setInterval(changeImage, delayInSeconds * 50);
})();
</script>
</body>
</html>
It can only display the image i have declared in the "var image". if i have 10000 image , how to do that . I have tried using a 'for' loop but it failed .. any suggestions ?? thanks in advance
==============================================================
update version that Joseph recommend :
<html>
<head>
</head>
<body>
<img src="images/1.jpg" alt="rotating image" width="600" height="500" id="rotator">
<script type="text/javascript">
(function() {
var rotator = document.getElementById('rotator'), //get the element
var delayInSeconds = 1, //delay in seconds
var num = 0, //start number
var len = 9999; //limit
setInterval(function(){ //interval changer
num = (num === len) ? 0 : num; //reset if limit reached
rotator.src = num + '.jpg'; //change picture
num++; //increment counter
}, delayInSeconds * 1000);
}());
</script>
</body>
</html>
Assuming that images have the same sequential filenames, this would be best when looping through a lot of them:
(function() {
var rotator = document.getElementById('rotator'), //get the element
dir = 'images/', //images folder
delayInSeconds = 1, //delay in seconds
num = 0, //start number
len = N; //limit
setInterval(function(){ //interval changer
rotator.src = dir + num+'.jpg'; //change picture
num = (num === len) ? 0 : ++num; //reset if last image reached
}, delayInSeconds * 50);
}());
AFAIK, you can use the same logic to display the images in small chunk as your browser will crash if you try to display all 10000 images at the same time.So display 5-10 images on the page with your current logic and ask the user to retrieve next set.You can see this kind of implementation in many image sharing applications.Hope this will help you
(function () {
var rotator = document.getElementById('rotator'); // change to match image ID
var imgDir = 'images/'; // change to match images folder
var delayInSeconds = 1; // set number of seconds delay
// Yes I made changes below this line
var num = 0;
var changeImage = function () {
rotator.src = imgDir + num++ + ".jpg";
//var len = rotator.src.length;
if (num == 5) {
num = 0;
}
};
setInterval(changeImage, delayInSeconds * 1000);
})();

Cycling between 3 images (mobile Safari)

I have the following javascript. It works well when I am cycling between 2 images, but when I add a third it does not work correctly.
Here is my CSS:
img {
-webkit-transition-property: opacity;
-webkit-transition-duration: 2s;
position: absolute;
width: 320px;
height: auto;
}
img.fade-out {
opacity: 0;
}
img.fade-in {
opacity: 1;
}
Here is my javascript, which seems to work but seems laggy and definately not an elegant solution.
</head><body style="color: black">
<img id="one" class="fade-out" src="Wallpaper.png"/>
<img id="two" class="fade-out" src="Wallpaper0.png"/>
<img id="three" class="fade-out" src="Wallpaper1.png"/>
<script>
var images = ['Wallpaper.png', 'Wallpaper0.png', 'Wallpaper1.png'];
var index = 0;
var fade_in = one;
var fade_out = two;
var fade_foo = three;
fade_in.src = images[0];
fade_out.src = images[images.length - 1];
var fade = function () {
fade_in.src = images[index];
index = (index + 1) % images.length;
fade_in.className = 'fade-out';
fade_out.className = 'fade-in';
fade_foo.className = 'fade-out';
var fade_tmp = fade_in;
fade_in = fade_out;
fade_out = fade_foo;
fade_foo = fade_tmp;
setTimeout(fade, 15000);
};
fade();
</body></html>
For one thing, you're not changing fade_out.src. Try something like this:
fade_in.src = images[0];
fade_out.src = images[1]; // let's use image next to current for fade-out
var fade = function () {
fade_in.src = images[index];
index = (index + 1) % images.length;
fade_out.src = images[index]; // put next to current image into fade-out
// Code below does something misterious.
// You first switch classes between two img's, then switch variables themselves
// Why?
//fade_in.className = 'fade-out';
//fade_out.className = 'fade-in';
//var fade_tmp = fade_in;
//fade_in = fade_out;
//fade_out = fade_tmp;
setTimeout(fade, 15000);
};
Can't tell more since I don't know what exactly you're doing.
It seems you're only displaying one image at a time, so you don't need two variables, one will do. You just need to fade out the current image and bring in a new image:
var index = -1, count = /* total number of images */;
var image = null;
function fade() {
if (image != null)
image.className = 'fade-out';
index = (index + 1) % count;
image = document.getElementById('image-' + index);
image.className = 'fade-in';
setTimeout(fade, 15000);
}
fade();
This assumes that you have set up all the images in HTML as follows:
<img id="image-0" class="fade-out" src="..." />
<img id="image-1" class="fade-out" src="..." />
<img id="image-2" class="fade-out" src="..." />
...
Note that you can achieve cross-fading only if you have several images preloaded, as in the above example. If you use only one image and change the source, the previous image will be lost when you try to fade in the new one.
you're not waiting for you transitions to finish before you swap the source. we just need to rearrange the order of things.
var fade = function() {
fade_in.className = 'fade-out';
fade_out.className = 'fade-in';
setTimeout(function() {
index = (index + 1) % images.length;
fade_in.src = images[index]; // should be completely invisible at this time
var fade_tmp = fade_in;
fade_in = fade_out;
fade_out = fade_tmp;
}, 2000); // 2 seconds, same as your transition time
setTimeout(fade, 15000);
};
setTimeout(fade, 15000);
here the only work that the fade method does is to change the classes, which initiates the transitions. we set a delay that matches your transition time to update the index and swap the image source.
edits: i guess i'm not making it clear what's going on and the assumptions i'm making. here's my complete html except for the provided css which is the same. i also fixed an issue with image order since the last example.
<body>
<img id="one" class="fade-out" /><img id="two" class="fade-out" />
<script>
var images = ['16jog8h.jpg', '20_11_2007_0044537001195507712_joe_baran.jpg', '400davesrig.jpg'];
var index = 0;
var fade_in = document.getElementById('one');
var fade_out = document.getElementById('two');
// fade_in.src = images[0];
fade_out.src = images[0];
var fade = function() {
fade_in.className = 'fade-out';
fade_out.className = 'fade-in';
setTimeout(function() {
index = (index + 1) % images.length;
fade_in.src = images[index];
var fade_tmp = fade_in;
fade_in = fade_out;
fade_out = fade_tmp;
}, 2000);
setTimeout(fade, 5000);
};
fade();
</script>
</body>

Categories