I'm trying to randomly load some images to the page's html divs and my code is sometimes working, like on the first page load, but on maybe the second or third it causes the page to blank out and buffer and crashes the tab.
Here's a link to the full file (Excluding image srcs):
Here's the full js file: (be careful because it will crash the tab if you reload it several times)
https://repl.it/GBvG/2
var topnum = 7; //will later be used to represent current index
var rando; //will later be used as a swap index
var temporary; //will later be used as a temporary holder so we can swap rando and topnum
var myCard = document.getElementsByClassName('card');
var myArray = [
'Images/aceheart.png',
'Images/aceheart.png',
'Images/kingheart.png',
'Images/kingheart.png',
'Images/queenheart.png',
'Images/queenheart.png',
'Images/tenheart.png',
'Images/tenheart.png'
];
function create(){
while(topnum > 0){ //loops over all 8 elements
rando = Math.floor((Math.random() * topnum) + 0);
//will swap elements as long as the random index we got is not the same as the current index
if(myArray[rando] !== myArray[topnum]){
temporary = myArray[topnum];
myArray[topnum] = myArray[rando]; //randomizes topindex value
myArray[rando] = temporary;
topnum--;
}; // end of if
}; //end of while
for(var i = 0; i <= 8;i++){
var imgElement = "<img src='" + myArray[i] + "' alt='test' width='200px' height='275px'/>";
myCard[i].innerHTML = imgElement;
}; //end of for loop
}; // end of create
I'm almost positive the problem is with this snippet, though I don't know why:
for(var i = 0; i <= 8;i++){
var imgElement = "<img src='" + myArray[i] + "' alt='test' width='200px' height='275px'/>";
myCard[i].innerHTML = imgElement;
}; //end of for loop
You have 8 cards but your loop runs 9 iterations.
Change
for(var i = 0; i <= 8;i++)
To
for(var i = 0; i < 8;i++) // use `<` instead of `<=`
Also, as Gerardo Furtado mentioned in the comments, you should put topnum-- outside the if in the while loop. Otherwise you'll have an infinite loop.
while(topnum > 0) {
rando = Math.floor((Math.random() * topnum) + 0);
if(myArray[rando] !== myArray[topnum]){
// ...
}
topnum--; // <-- move the decrement here
}
Related
I'm trying to write an array of images, but I have a lot of images so I'm trying to use "for loop" to generate it.
my current code is :
var images = [
"/images/image0000.png",
"/images/image0005.png",
"/images/image0010.png",
"/images/image0015.png",
"/images/image0020.png",
"/images/image0025.png",
"/images/image0030.png",
"/images/image0040.png",
"/images/image0045.png",
"/images/image0050.png"
];
I have more images to add. so I would like to know how to use for loop to generate this.
The last image is /images/image3360.png
Thank you!
I think you don't want to generate the actual images, but rather fill an array with filenames. The simplest way would be:
const MAX = 3360;
const PREFIX = "/images/image";
const EXT = ".png";
const arr = [];
for (let i = 0; i <= MAX; i += 5) {
arr.push(
PREFIX + ("0000" + i).slice(-4) + EXT
);
}
The slice thing comes from this answer.
const step = 5; // Steps
const imgNumber = 3360/step; // Image number
const images = []; // Array to hold images
for(i = 0; i<=imgNumber; i++) {
const currNum = i*step; // Calculate suffix
let str = "/images/image0000";
str = str.substring(0, str.length - currNum.toString().length); // Compile number
images.push(`${str}${currNum}.png`); // Store the image in the array
}
console.log(images);
You can do it like this:
let images = [];
for (let i = 0; i <= 3360; i += 5) {
let imageString = "";
let numberOfZeros = 4 - i.toString().length;
for (let j = 0; j < numberOfZeros; j++) {
imageString += "0";
}
images.push("/images/image" + imageString + i.toString() + ".png");
}
This essentially runs a for loop which increments by 5 each time, calculates the amount of leading zeros needed, then runs another for loop to add these leading zeros, and inserts a concatenation of this and the actual number inside the string which gets pushed to the array.
I'm trying to get this loop to return a value, for each value in an array every 1 second.
The returned value is a random value generated earlier, and each loop will add i to the number and output it. (ran[0]+i) (ran[1]+i) etc.
I need the output in the same order as my example, but with a 1 second interval and something to generate my returns/consolelogs instead of having to type in all 4, or however many I use (could be random).
The code is for an animation but I cannot get the SVG working here and its irrelevant to the problem I think.
var ran = [];
var qan = 4;
for(i=0;i<(qan);i++){
rd = Math.floor(Math.random()*360);
ran.push(rd);
};
for(i=0;i<10;i++){
/*need to have (random.length) number of console logs and interval loops by 1 second*/
console.log((ran[0]+i) + " loop " + (i));
console.log((ran[1]+i) + " loop " + (i));
console.log((ran[2]+i) + " loop " + (i));
console.log((ran[3]+i) + " loop " + (i));
};
You may do like this;
var ran = [];
var qan = 4;
for(let i=0;i<(qan);i++){
rd = Math.floor(Math.random()*360);
ran.push(rd);
setTimeout(function(){console.log(ran[i])},1000*i);
}
Or by using var instead of let you can still do like this by utilizing an IIFE to return a callback with an encapsulated i value.
var ran = [];
var qan = 4;
for(var i=0;i<(qan);i++){
rd = Math.floor(Math.random()*360);
ran.push(rd);
setTimeout((function(j){ return function(){ console.log(ran[j]) } })(i),1000*i);
}
Update: I hope i am getting closer.. I just console.log the array itself but the items increase by i in each round. (10 rounds / frames)
var randar = new Array(4).fill().map(e => ~~(Math.random()*360));
console.log("starting random array ",randar); // let's see how the random array starts
for (let i = 0; i < 10; i++){
setTimeout(function(){console.log(randar.map(e=> e+i))} ,1000*i);
}
Note: I use arrows mostly but if you have concerns about IE or Safari then it's best to replace them with conventional function calls.
I am creating images flip game in jquery. I am having trouble with images. In image flip game we have only two images of the same type. I have 44 img tags and 22 images. I am taking images randomly.
Q1. How to take two images only of the same type?
Q2. If one image is clicked it should be displayed as it is working now but when any other image is clicked then if the sources (src) of both the images are same, both should be hidden forever. If not both should turn over again.
Here is my code of the script.
<script>
var imgSources = new Array();
var twoImagesOnly = [];
for(var c = 1; c < 22; c++){
imgSources.push(c + ".png");
}
$('#add').click(function(){
addElements(44);
$('#add').attr('disabled', 'true');
});
function addElements(times){
var main = $('#main');
for(j = 1; j <= times; j++){
var div = $("<div>");
var img = $("<img>");
img.attr('src', getImage());
img.attr('width', '100');
img.attr('height', '100');
img.click(function(event){
$(this).slideUp();
event.stopPropagation();
});
div.click(function(){
$(this).children('img').slideDown();
});
div.addClass('div');
div.append(img);
img.addClass('myimg');
main.append(div);
img.slideUp('fast');
}
}
var counter;
function getImage(){
var rand = Math.floor(Math.random() * 22) + 1;
var str = '';
if($.inArray(rand, twoImagesOnly) == -1){
str = rand + '.png';
twoImagesOnly[counter] = rand;
counter++;
}else{
getImage();
}
return str;
}
</script>
and here JSFiddle
Seems someone beat me to the punch with half of my solution while I was editing the fiddle, but I'll post this just because the second half should help you a bit with ensuring that only 2 of each card are posted.
First off, to initialize the array, use the following:
for(var c = 1; c < 23; c++){
imgSources.push(c + ".png");
imgSources.push(c + ".png");
}
This will iterate 22 times, adding files 1.png through 22.png twice each.
Then, to ensure only two of each image are used:
function getImage(){
var rand = Math.floor(Math.random() * imgSources.length);
var str = imgSources[rand];
imgSources.splice(rand,1);
return str;
}
What this will do is remove each array item as they are used, sort of like drawing cards from a deck, ensuring that only two of each image are used and avoiding the "keep trying until it works" approach you had.
Fiddle
Q1. A quick solution to be sure that exactly two images are present, could be to push twice to your array:
for(var c = 1; c < 22; c++){
imgSources.push(c + ".png");
imgSources.push(c + ".png");
}
And then randomize it (see https://stackoverflow.com/a/2450976/3207406 for function example)
And then fetch the image in order with a function like
getImage(i)
Q2. Regarding the "two clicks",
you could use one global variable:
first_image
Which will be null if no image was previously shown.
Otherwise, it will contain the details of the currently show image (like source and id). If the sources don't match, then you can turn back the two pictures after some time.
I'm trying to loop through an array of images but can't seem to get past image 2.
The array should also loop back to 1 when the last image has passed...
var WorkArray = new Array('work/01.png', 'work/02.png', 'work/03.png', 'work/04.png');
var nelements = WorkArray.length;
preload_image_object = new Image();
var i = 0;
for(i=0; i<=nelements; i++) {
preload_image_object.src = WorkArray[i];
}
function cC() {
var nelements = WorkArray.length;
var i = 0;
for(i=0; i<=nelements; i++) {
nelements = WorkArray[i];
}
document.getElementById("work").style.backgroundImage="url('"+WorkArray[i]+"')";
}
You can save the current file and use modulo to run in cyclic manner.
It will look something like that:
var WorkArray = new Array('work/01.png', 'work/02.png', 'work/03.png', 'work/04.png');
var currentImage = 0
function nextImage(){
currentImage = (currentImage + 1) % WorkArray.length;
document.getElementById("work").style.backgroundImage="url('"+WorkArray[currentImage]+"')";
}
You are overwriting nelements with the current element of the loop:
nelements = WorkArray[i];
The following should fix your loops:
var WorkArray = new Array('work/01.png', 'work/02.png', 'work/03.png', 'work/04.png');
var preload_image_object = new Image();
/* Lets get rid of `nelements`, as its just confusing. Get the length here.
* If, for performace reasons you want to use elements, the best way is to reverse
* aka for(var i = WorkArray.length-1; i >= 0 ; i--)
* Also, its simpler to declare the var in your for-loop itself instead of outside of it.
*/
for(var i = 0; i <= WorkArray.length; i++){
preload_image_object.src = WorkArray[i];
}
Also, again for simplifications sake, your application of the background-image could be done inside your for loop as well, and can be made to look cleaner with some spaces and omitting the ' inside your url():
document.getElementById("work").style.backgroundImage = "url(" + WorkArray[i] + ")";
I was wondering if it's possible to get a sequence of pictures into an array. I'd like to use plain JavaScript, because I have zero experience in PHP or any other language to achieve this.
So I created a map called "images", which contains 50 images. The first one is called: "1", the second one is called: "2" and so on. They all are the same type (.jpg).
I can do this manually like:
var pictures = new Array();
pictures[0] = "images/1.jpg";
pictures[1] = "images/2.jpg";
//and so on
But only a mad man would do this. also when I upload a new picture to the "images" folder, I have to manually add the new image to the array, so I was thinking about a while loop which checks if each image in the folder is stored into the array.
You could try:
var pictures = new Array();
for(var x=1; x<51; x++ ) {
pictures[x-1] = "images/"+x+".jpg";
}
var numberOfImages = 50; // or whatever
var im, pictures = new Array();
for (var i = 0; i < numberOfImages ; i++) {
im = "images/" + i + ".jpg";
pictures.push(im);
}
var arr = [];
for (var i = 0, max = 50; i < max; i += 1) {
arr[i] = "images/" + i + ".jpg";
}
If you want a change number of images, try this:
function bar (numberOfImages) {
var arr = [];
for (var i = 0; i < numberOfImages; i += 1) {
arr[i] = "images/" + i + ".jpg";
}