Change images randomly on click without repeating - javascript

I found this code on Stack Overflow: change images on click.
And it works for me. I want it to be random, but how can i prevent it from repeating the images. It should first repeat the images, when the user has clicked through all images.
I have made an JSfiddle with my code: http://jsfiddle.net/gr3f4hp1/
JQuery code:
var images = ["02.jpg","03.jpg","01.jpg"];
$(function() {
$('.change').click(function(e) {
var image = images[Math.floor(Math.random()*images.length)];
$('#bg').parent().fadeOut(200, function() {
$('#bg').attr('src', 'items/'+image);
$(this).fadeIn(200);
});
});
});

Keep track of the numbers that you have generated, and if its a repeat then get a new number.
You can Work Around This
var usedImages = {};
var usedImagesCount = 0;
function displayImage(){
var num = Math.floor(Math.random() * (imagesArray.length));
if (!usedImages[num]){
document.canvas.src = imagesArray[num];
usedImages[num] = true;
usedImagesCount++;
if (usedImagesCount === imagesArray.length){
usedImagesCount = 0;
usedImages = {};
}
} else {
displayImage();
}
}

you can try this code .
var images = ["02.jpg","03.jpg","01.jpg"];
var imagecon = [];
$(function() {
$('.change').click(function(e) {
if(images.length == 0) { // if no image left
images = imagecon; // put all used image back
imagecon = []; // empty the container
}
var index = Math.floor(Math.random()*images.length);
var image = images[index];
imagecon.push(image); // add used image
images.splice(index,1); // remove it to images
$('#bg').parent().fadeOut(200, function() {
$('#bg').attr('src', 'items/'+image);
$(this).fadeIn(200);
});
});
});

you could add a class to every image that appears like:
image.addClass("viewed")
and write an if statement that show the image only if it hasn't the class viewed:
if(!image.hasClass(viewed)){
(show the image methods);
image.addClass("viewed")
}
I'm not going to make all the code for you, just try this way, learn, fail, success, have fun! :D

Try this image change according to imgCnt variable.
var images = ["01.jpg","02.jpg","03.jpg","01.jpg"];
var imgCnt=1;
$(function() {
$('.change').click(function(e) {
// var image = images[Math.floor(Math.random()*images.length)];
if(imgCnt >= images.length){
imgCnt=0;
}
var image =images[imgCnt];
// alert(image);
$('#bg').parent().fadeOut(200, function() {
$('#bg').attr('src', 'items/'+image);
$(this).fadeIn(200);
imgCnt++;
});
});
});
Demo

There are lots of method here i just push the value of visited image in to Visited array
Campate two array show only differ element
var images = ["02.jpg","03.jpg","01.jpg"];
var visited = [];
$(function() {
$('.change').click(function(e) {
var image = images[Math.floor(Math.random()*images.length)];
visited.push(image);
$('#bg').parent().fadeOut(200, function() {
y = jQuery.grep(images, function(value) {
if(jQuery.inArray(value, visited) == -1){
$('#bg').attr('src', 'items/'+image);
$(this).fadeIn(200);
}
});
} });
});
});
I hopes its help

Related

Javascript Add two Integer Variables?

So I am trying to create something where when a user clicks a div element, it adds a number to a total, sort of like a checkout system.
I have written the following javascript
JS
var optionOne = 5;
var optionTwo = 10;
var basePrice = 0;
function doMath() {
$("#option1checkout").click(function() {
// Add optionOne to basePrice
});
$("#option1cancel").click(function() {
// Don't do anything to basePrice
});
$("#option2checkout").click(function() {
// Add optionTwo to basePrice
});
$("#option2cancel").click(function() {
// Don't do anything to basePrice
});
};
I want it to add option 1 and 2 to basePrice whenever they click the option1checkout or option2checkout div element and do nothing when they click the cancel div elements.
I just feel like if I just do "basePrice + optionOne;" in the click functions it would be manual and not actually adding the integer values.
Any other way to do this?
What wrong with this approach:
var mousePrice = 5;
var coverPrice = 10;
var mouseSelected=0;
var coverSelected=0;
var basePrice = 500;
function doMath() {
$("#mouse").click(function() {
basePrice+=mousePrice;
});
$("#omouseCancel").click(function() {
if(mouseSelected>0){
basePrice-=(mousePrice*mouseSelected);
}
});
$("#cover").click(function() {
basePrice+=coverPrice;
});
$("#coverCancel").click(function() {
if(coverSelected>0){
basePrice-=(coverPrice*coverSelected);
}
});
};

Animation Array in JavaScript

I've come up with this little animation that uses images in an array, but it's sloppy. What I'd really like is to modularize it so that I can use multiple instances of the same function to animate different arrays depending on which key is pressed. Also, I'd like to get it so that the animation stops when the key is released, if possible. I realize that calling all of those variables globally is a big no-no, but I have no idea how to make it work otherwise! Last but not least, I'd like to figure out how to get that last bit of inline script over to the external file and have it still work correctly. Any help would be much appreciated! But please note, I'm a novice with JavaScript, so please try to be as specific/detailed as possible so I can learn from your wisdom! Thank you!
I've created a jsfiddle.
HTML:
<div id="wrapper">
<span id="jajo"><img id="my_img" src="jajo.png" /></span>
<script>element = document.getElementById("jajo"); </script>
</div><!--wrapper-->
JavaScript:
var i = 0;
var element;
var waveArray = ["wave0.png","wave1.png","wave2.png","wave3.png","wave4.png","wave5.png"];
var jumpArray = ["jump0.png","jump1.png","jump2.png","jump3.png","jump4.png","jump5.png"];
var foodArray = ["food0.png","food1.png","food2.png","food3.png","food4.png","food5.png"];
document.onkeydown = function(event) {
var keyPress = String.fromCharCode(event.keyCode);
if(keyPress == "W") { // if "w" is pressed, display wave animation
increment ();
document.onkeyup = function(event) { // if "w" is released, display default image
document.getElementById("jajo").innerHTML= "<img alt='Jajo' src='jajo.png'>";
}
} else if(keyPress == "A") { // if "a" is pressed, display jump animation
} else if(keyPress == "S") { // if "s" is pressed, display food animation
}
}
function increment (){
i++;
if(i > (waveArray.length - 1)){
i = 0;
}
setTimeout(animation,1000/30);
}
function animation() {
var img = '<img src="' + waveArray[i] + '" alt="Jajo" />';
element.innerHTML = img;
setTimeout(increment, 2000/30);
}
Demo
http://jsfiddle.net/ghQwF/4/
Module
var animation = (function() {
var delay = 1000 / 30;
var map = {}, active = [], timer;
function animate() {
for(var i=0, l=active.length; i<l; ++i) {
var data = map[active[i]];
++data.index;
data.index %= data.array.length;
data.image.src = data.array[data.index];
}
timer = setTimeout(animate, delay);
}
function begin(e) {
var key = String.fromCharCode(e.keyCode),
data = map[key];
if(!data) return;
if(!active.length) timer = setTimeout(animate, delay);
if(!~active.indexOf(key)) active.push(key);
}
function end(e) {
var key = String.fromCharCode(e.keyCode),
data = map[key];
if(!data) return;
data.image.src = data.default;
var index = active.indexOf(key);
if(!~index) return;
active.splice(index, 1);
if(!active.length) clearTimeout(timer);
}
return {
add: function(data) {
data.index = data.index || 0;
data.image = data.image || data.target.getElementsByTagName('img')[0];
data.default = data.default || data.image.src;
map[data.key] = data;
},
remove: function(key) {
delete map[key];
},
enable: function() {
document.addEventListener('keydown', begin, false);
document.addEventListener('keyup', end, false);
},
disable: function() {
document.removeEventListener('keydown', begin, false);
document.removeEventListener('keyup', end, false);
clearTimeout(timer);
active = [];
}
};
})();
Example
animation.enable();
animation.add({
key: 'W',
target: document.getElementById('jajo'),
array: [
"http://static.spoonful.com/sites/default/files/styles/square_128x128/public/crafts/fingerprint-flowers-spring-craft-photo-420x420-aformaro-01.jpg",
"http://static.spoonful.com/sites/default/files/styles/square_128x128/public/crafts/paper-flowers-spring-craft-photo-420x420-aformaro-11.jpg",
"http://static.spoonful.com/sites/default/files/styles/square_128x128/public/crafts/tissue-paper-flowers-kaboose-craft-photo-350-fs-IMG_8971_rdax_65.jpg"
]
});
animation.add({ /* ... */ });
Methods
add
Adds a new animation, with parameters:
key: key to activate animation
target: wrapper of the image (optional if image is specified)
image: image to animate (optional, defaults to first image in target)
default: default url of the image (optional, defaults to original url)
index: initial position in array (optional, defaults to 0)
array: array of images
remove
Removes the animation related with key specified.
disable
Disables animations (typing keys would have no effect), and stops current ones.
enable
Enable animations (typing keys can start animations).

Can't add to an array with Javascript inside a for loop

I'm trying to write some code to find all the linked images on a webpage. So far I'm able to generate an array of all the links (imageLinks) but in the code below the final console.log(linkedImages) always shows an empty array.
The thing I can't wrap my head around is where I've commented "This works / But this doesn't work:"
What am I doing wrong? Any help is greatly appreciated for this somewhat noob. Thanks!
//Create an array of all the links containing img tags
var imageLinks = $("img").parent("a").map(function () {
var h = $(this).attr("href");
return h;
}).get();
//This correctly shows all the links:
//console.log(imageLinks);
//Declare an array to hold all the linked images
var linkedImages = [];
//Loop through all the links to see if they're images or not
for (var l = 0; l < imageLinks.length; l++) {
var currLink = imageLinks[l];
function myCallback(url, answer) {
if (answer) {
//This works:
console.log(url + ' is an image!');
//But this doesn't work
linkedImages.push(url);
} else {
//alert(url+' is NOT an image!');
}
}
function IsValidImageUrl(url, callback) {
var img = new Image();
img.onerror = function () {
callback(url, false);
}
img.onload = function () {
callback(url, true);
}
img.src = url
}
IsValidImageUrl(currLink, myCallback);
};
//HELP! This always evaluates as just "[]"
console.log(linkedImages);
What #SLaks said. Since the loading of images is async, your callback doesn't fire until after the images have been loaded. To fix the problem, you can use $.Deferred from jQuery (I am assuming you are using jQuery since there is a $(...) in your code):
function callback(dfd, url, answer) {
if (answer) {
//This works:
console.log(url+' is an image!');
//But this doesn't work
dfd.resolve(url);
} else {
//alert(url+' is NOT an image!');
dfd.reject();
}
}
//Create an array of all the links containing img tags
var imageLinks = $("img").parent("a").map(function() {
var h = $(this).attr("href");
return h;
}).get();
//This correctly shows all the links:
//console.log(imageLinks);
//Declare an array to hold all the linked images
var linkedImages = [];
//Loop through all the links to see if they're images or not
var dfds = [];
for (var l=0; l<imageLinks.length; l++) {
var currLink = imageLinks[l];
var dfd = $.Deferred();
dfd.done(function(url) { linkedImages.push(url); });
dfds.push(dfd.promise());
(function(dfd, url) {
var img = new Image();
img.onerror = function() { callback(dfd, url, false); }
img.onload = function() { callback(dfd, url, true); }
img.src = url
})(dfd, currLink);
};
$.when.apply(null, dfds).done(function() {
console.log(linkedImages);
});
Have not tested this, but the general idea for how to use deferred to reach your goal is in there.

jquery / javascript - storing reference to array - not array values

I'm trying to combine a few similar functions into a single functions, which need to make calls to different arrays / variables, but I'm not quite getting it right. Here's my code:
var initialPreloadArray = ['scenes/icons_orange.png','scenes/icons_blue.png','scenes/icons_green.png','site/pedestal_h.png']; //These must be loaded before we advance from the intro screen
var initialPreloadCounter = 0;
var secondaryPreloadArray = ['site/restart-black.png','site/back_black.png','interludes/city.png','interludes/town.png','interludes/country.png']; //These must be loaded before we can advance from the initial decision scene
var secondaryPreloadCounter = 0;
var vehiclesPreloadArray = ['vehicles/vehicles.png','site/close.png']; //These must be loaded before we can display the vehicles
var vehiclesPreloadCounter = 0;
var arrName; //Store the variable name of the array for the stage of preloading we're in
var arrCounter; //Stores the variable name of the counter for the stage of preloading we're in
function setPreloadStage(preloadStage){
if (preloadStage == initial){
arrName = initialPreloadArray;
arrCounter = initialPreloadCounter;
} else if (preloadStage == 'secondary'){
arrName = secondaryPreloadArray;
arrCounter = secondaryPreloadCounter;
} else if (preloadStage == 'vehicles'){
arrName = vehiclesPreloadArray;
arrCounter = vehiclesPreloadCounter;
}
preloadImages(preloadStage);
}
//Recurse through scene xml and populate scene array
function preloadImages(preloadStage) {
console.log(arrName[arrCounter]);
var img = new Image();
img.src = 'images/' + arrName[arrCounter];
if(!img.complete){
jQuery(img).bind('error load onreadystatechange', imageComplete(preloadStage));
} else {
imageComplete(preloadStage);
}
//$j.preloadCssImages({statusTextEl: '#textStatus', statusBarEl: '#status'});
}
function imageComplete(preloadStage){
arrCounter++;
var preloadLength = arrName.length-1;
if (arrName && preloadLength && arrName[arrCounter]) {
if (preloadLength == arrCounter){
if (preloadStage == 'initial'){
initialImagesLoaded();
} else if (preloadStage == 'secondary'){
secondaryImagesLoaded();
} else if (preloadStage == 'vehicles'){
vehiclesLoaded();
}
}
preloadImages(preloadStage);
}
}
Anybody have an idea what I'm doing wrong?
Actually, here’s an even more obvious problem:
jQuery(img).bind('error load onreadystatechange', imageComplete(preloadStage));
You would have to do this:
jQuery(img).bind('error load onreadystatechange', function () {
imageComplete(preloadStage)
});
I suggest that you should use an array to manage state.
define an array holding your stages, like this:
var stages = [
{
label : 'initial',
imgs : [ 'img/whoobee.png', ...more here...],
doneSoFar: 0,
allDone: function(){}
},
{ label : 'secondary', imgs : .....},
{ label : 'whatever', imgs : ....}
];
NB: You will need to set the "allDone" fn for each stage appropriately.
Then a fn that kicks off one stage:
function kickoffPreloadOneStage(stage) {
console.log ("preloading stage " + stage.label);
preloadNextImage(stage);
}
function preloadNextImage(stage) {
var img = new Image();
img.src = 'images/' + stage.imgs[stage.doneSoFar];
if(!img.complete){
jQuery(img).bind('error load onreadystatechange', function() {
imageComplete(preloadStage);
});
}
else {
imageComplete(preloadStage);
}
}
function imageComplete(stage){
stage.doneSoFar++;
var preloadLength = stage.imgs.length-1;
if (stage.doneSoFar == preloadLength) {
stage.allDone(); // call the allDone function. may want to pass stage back
}
else {
preloadNextImage(stage);
}
}
To do all stages, use code like this:
var i;
for(i=0; i < stages.length; i++) {
kickoffPreloadOneStage(stages[i]);
}
You can also go OO, defining those functions as members of a Stage() class, but ....what I suggested is a reasonable simplification without getting too complicated.

Generic Javascript Image Swap

I'm building a navigation bar where the images should be swapped out on mouseover; normally I use CSS for this but this time I'm trying to figure out javascript. This is what I have right now:
HTML:
<li class="bio"><img src="images/nav/bio.jpg" name="bio" /></li>
Javascript:
if (document.images) {
var bio_up = new Image();
bio_up.src = "images/nav/bio.jpg";
var bio_over = new Image();
bio_over.src = "images/nav/bio-ov.jpg";
}
function over_bio() {
if (document.images) {
document["bio"].src = bio_over.src
}
}
function up_bio() {
if (document.images) {
document["bio"].src = bio_up.src
}
}
However, all of the images have names of the form "xyz.jpg" and "xyz-ov.jpg", so I would prefer to just have a generic function that works for every image in the navbar, rather than a separate function for each image.
A quick-fire solution which should be robust enough provided all your images are of the same type:
$("li.bio a").hover(function() {
var $img = $(this).find("img");
$img[0].src = $img[0].src.replace(".jpg", "") + "-ov.jpg";
}, function() {
var $img = $(this).find("img");
$img[0].src = $img[0].src.replace("-ov.jpg", "") + ".jpg";
});
This should work will all image formats as long as the extension is between 2 and 4 characters long IE. png, jpeg, jpg, gif etc.
var images = document.getElementById('navbar').getElementsByTagName('img'), i;
for(i = 0; i < images.length; i++){
images[i].onmouseover = function(){
this.src = this.src.replace(/^(.*)(\.\w{2,4})$/, '$1'+'-ov'+'$2');
}
images[i].onmouseout = function(){
this.src = this.src.replace(/^(.*)-ov(\.\w{2,4})$/, '$1'+'$2');
}
}
Here's an idea in plain javascript (no jQuery):
function onMouseOverSwap(e) {
e.src = e.src.replace(/\.jpg$/", "-ov.jpg"); // add -ov onto end
}
function onMouseOutSwap(e) {
e.src = e.src.replace(/(-ov)+\.jpg$/, ".jpg"); // remove -ov
}

Categories

Resources