I have searched the forum thoroughly for a solution to this with no luck. Hoping someone can help me here.
I have an empty div with no background image. When a user clicks on it, I have a function that sets the background image like this:
function myAnimation(element) {
var images = ["url(images/pig.png)", "url(images/cat.png)", "url(images/frog.png)", "url(images/dog.png)"];
var random = Math.floor(Math.random() * 4);
element.style.backgroundImage = images[random];
}
Although this works, the problem I'm having is finding the solution to when the user clicks on the image again. As there is only four possible numbers generated, I keep getting a repeating number from the var random method. I think I need a way to check the last number generated and if it's the same, it should try and generate a different number. This way there will be no repeating images. Hope this makes sense. Just so you know, I'm new to programming and only learning Javascript for the last 3 months. I think I may need a loop or another function inside this function, not sure.
I am checking prevNo with generated random number. If both are same, then call the function again. Else assign the random number to prevNo and load the image.
var prevNo = -1;
function myAnimation(element) {
var images = ["url(images/pig.png)", "url(images/cat.png)", "url(images/frog.png)", "url(images/dog.png)"];
var random = Math.floor(Math.random() * 4);
if( random == prevNo) {
myAnimation(element);
return;
} else {
prevNo = random;
}
element.style.backgroundImage = images[random];
}
You can filter your images, considering all items except the current background element, and take a random element of the result.
This is a example of how you can accomplish this:
function myAnimation(element) {
var currentBackgroundImage = element.style.backgroundImage;
var images = [
"url(https://place-hold.it/100x100&text=1)",
"url(https://place-hold.it/100x100&text=2)",
"url(https://place-hold.it/100x100&text=3)",
"url(https://place-hold.it/100x100&text=4)",
];
var restOfImages = images.filter(function (image) {
return image !== currentBackgroundImage;
})
var random = Math.floor(Math.random() * restOfImages.length);
element.style.backgroundImage = restOfImages[random];
}
Another way, without filter:
function myAnimation(element) {
var currentBackgroundImage = element.style.backgroundImage;
var images = [
"url(https://place-hold.it/100x100&text=1)",
"url(https://place-hold.it/100x100&text=2)",
"url(https://place-hold.it/100x100&text=3)",
"url(https://place-hold.it/100x100&text=4)",
];
var restOfImages = [];
for(var i = 0; i < images.length; i++) {
if (images[i] !== currentBackgroundImage) {
restOfImages.push(images[i]);
}
}
var random = Math.floor(Math.random() * restOfImages.length);
element.style.backgroundImage = restOfImages[random];
}
And here is a working snipplet:
function myAnimation(element) {
var currentBackgroundImage = element.style.backgroundImage;
var images = [
"url(https://place-hold.it/100x100&text=1)",
"url(https://place-hold.it/100x100&text=2)",
"url(https://place-hold.it/100x100&text=3)",
"url(https://place-hold.it/100x100&text=4)",
];
var restOfImages = images.filter(function (image) {
return image !== currentBackgroundImage;
})
var random = Math.floor(Math.random() * restOfImages.length);
element.style.backgroundImage = restOfImages[random];
}
var el = document.getElementById('container');
el.onclick= function() { myAnimation(el); };
#container{
width: 100px;
height: 100px;
background-color: red;
}
<div id="container"></div>
You can repeatedly use Array.splice to remove a random element.
var images = [...
var random = Math.floor(Math.random() * 4);
element.style.backgroundImage = images.splice(random, 1)[0];
I'm using the same function across the entire site so I'm using local storage with a window onload call to headerPic():
const originalArr = ["image1.jpg", "image2.jpg", etc...];
function headerPic() {
let headerImgArray = localStorage.getItem("headerList") ? JSON.parse(localStorage.getItem("headerList")) : originalArr;
if (headerImgArray.length < 1) {
headerImgArray = originalArr;
}
const randomName = headerImgArray[Math.floor(Math.random() * headerImgArray.length)];
document.getElementById("headerImg").src = `imagesHeader/${randomName}`;
headerImgArray.splice(headerImgArray.indexOf(randomName), 1);
if (headerImgArray.length < 1) {
headerImgArray = originalArr;
}
localStorage.setItem("headerList", JSON.stringify(headerImgArray));
}
Related
I'm looking to create a code in which a card would be drawn randomly by pressing a button. However, I would like some cards to be rarer than others, but I don't know how to integrate this, the code is not at all my favorite domain ...
Thank you very much for your help and the tips you can give me!
var spongebob = "<img src = 'http://www.homastudio.com/img/spongebob.png'>";
var patrick = "<img src = 'http://www.homastudio.com/img/patrick.png'>";
var squidward = "<img src = 'http://www.homastudio.com/img/squidward.png'>";
var sandy = "<img src = 'http://www.homastudio.com/img/sandy.png'>";
var krabs = "<img src = 'http://www.homastudio.com/img/krabs.png'>";
var larry = "<img src = 'http://www.homastudio.com/img/larry.png'>";
var images = [spongebob, patrick, squidward, sandy, krabs, larry]
var names = ["Spongebob Squarepants", "Patrick Star", "Squidward Tentacles", "Sandy Cheeks", "Eugene Krabs", "Larry Lobster"]
function displayImage(){
var rn = Math.random();
rn = rn*6;
rn = Math.floor(rn);
document.getElementById("pic").innerHTML=images[rn];
document.getElementById("name").innerHTML=names[rn];
}
What you're after is called a Weighted Random selection, that is to say it is still a random selection, but some items are weighted higher. The algorithm is fairly simple.
You start with a list of items, and you assign each one a relative weight. The higher the weight, the more likely it is to be picked. Then, pick a random number between 0 and the total weight of all items and you step through the items subtracting each items weight from the random number you selected. when the number reaches zero, you have your item.
Heres an example.
function WeightedBroker(){
this.totalWeight = 0;
this.items = [];
this.addItem = function(value,weight){
this.items.push({value,weight});
this.totalWeight+= weight;
}
this.pickItem = function(){
var rnd = Math.floor(Math.random() * this.totalWeight);
for(var i=0;i<this.items.length;i++){
if(rnd<=this.items[i].weight)
return this.items[i].value;
rnd -= this.items[i].weight;
}
}
}
var broker = new WeightedBroker();
broker.addItem("a",100);
broker.addItem("b",10);
broker.addItem("c",1);
for(var i=0;i<10;i++)
console.log(broker.pickItem());
Applying this to your code is pretty easy, you will want to change those 2 arrays (one with img html, and one with names) to objects containing the properties name and src. You add each of these items to the broker I wrote above with appropriate weights for each according to your requirement. Something like this:
function WeightedBroker(){
this.totalWeight = 0;
this.items = [];
this.addItem = function(value,weight){
this.items.push({value,weight});
this.totalWeight+= weight;
}
this.pickItem = function(){
var rnd = Math.floor(Math.random() * this.totalWeight);
for(var i=0;i<this.items.length;i++){
if(rnd<=this.items[i].weight)
return this.items[i].value;
rnd -= this.items[i].weight;
}
}
}
var broker = new WeightedBroker();
broker.addItem({src:"<img src = 'http://www.homastudio.com/img/spongebob.png'>",name:"Spongebob Squarepants"},100);
broker.addItem({src:"<img src = 'http://www.homastudio.com/img/patrick.png'>",name:"Patrick Star"},100);
broker.addItem({src:"<img src = 'http://www.homastudio.com/img/squidward.png'>",name:"Squidward Tentacles"},100);
broker.addItem({src:"<img src = 'http://www.homastudio.com/img/sandy.png'>",name:"Sandy Cheeks"},100);
broker.addItem({src:"<img src = 'http://www.homastudio.com/img/krabs.png'>",name:"Eugene Krabs"},100);
broker.addItem({src:"<img src = 'http://www.homastudio.com/img/larry.png'>",name:"Larry Lobster"},100);
var item = broker.pickItem();
document.getElementById("pic").innerHTML=item.src;
document.getElementById("name").innerHTML=item.name;
<div id="name"></div>
<div id="pic"></div>
instead of having the array just have images do something like the following (where a low number in 'rarity' means more rare:
var spongebob = {
url:"<img src = 'http://www.homastudio.com/img/spongebob.png'>",
rarity: 1
};
var patrick = {
url:"<img src = 'http://www.homastudio.com/img/patrick.png'>",
rarity: 2
};
var squidward = {
url:"<img src = 'http://www.homastudio.com/img/squidward.png'>",
rarity: 4
};
var images = [spongebob, patrick, squidward];
var imageChoiceArr = [];
for(var i=0;i<images.length;i++) {
image = images[i];
for(var ii=0;ii<image.rarity;ii++) {
imageChoiceArr.push(image.url);
}
}
Then pick randomly from the 'imageChoiceArr'
Js beginner here.
I have a function like this:
generateSteps: function() {
var stepsLength = this.data.steps.length;
var dataStepsInit = this.data.steps;
for (var i = 0; i < stepsLength; i++) {
var stepsItem = dataStepsInit[i].ITEM;
var arrayItem = this.animationNodes[stepsItem - 1];
var transition = this.animationParameters[i].transition;
var options = this.animationParameters[i].options;
var speed = this.animationParameters[i].speed;
var delay = this.animationParameters[i].delay;
arrayItem.delay(delay).show(transition, options, speed);
if (dataStepsInit[i].AUDIOID) {
var audioClass = dataStepsInit[i].AUDIOID;
var audioPlayer = this.template.find("audio." + audioClass);
setTimeout(playAudioOnDelay,delay);
};
var playAudioOnDelay = function() {
audioPlayer[0].pause();
audioPlayer[0].currentTime = 0;
audioPlayer[0].play();
};
}
}
What it does is generate data from JSON and display animated elements one by one on delay. Animation part work fine. I can assign required animations and delay to DOM elements and show them in right order.
But what I want to do in the same time is also to play an audio on delay (so I use setTimeout). Everything is almost fine, I play audio in right time (correct delay value) but I always play the same audio (which is last element) because audioPlayer always is the same DOM node.
I think this have something to do with this or I mixed a scope?
Try this:
generateSteps: function() {
var stepsLength = this.data.steps.length;
var dataStepsInit = this.data.steps;
for (var i = 0; i < stepsLength; i++) {
var stepsItem = dataStepsInit[i].ITEM;
var arrayItem = this.animationNodes[stepsItem - 1];
var transition = this.animationParameters[i].transition;
var options = this.animationParameters[i].options;
var speed = this.animationParameters[i].speed;
var delay = this.animationParameters[i].delay;
arrayItem.delay(delay).show(transition, options, speed);
if (dataStepsInit[i].AUDIOID) {
var audioClass = dataStepsInit[i].AUDIOID;
var audioPlayer = this.template.find("audio." + audioClass);
setTimeout(playAudioOnDelay(audioPlayer),delay);
};
}
function playAudioOnDelay(audioPlayer){
return function(){
audioPlayer[0].pause();
audioPlayer[0].currentTime = 0;
audioPlayer[0].play();
}
}
}
Essentially, your problem looks like this: http://jsfiddle.net/po0rLnwo/
The solution is : http://jsfiddle.net/gpfuo1s8/
Check the console in your browser.
I have created a "prev/next" slideshow using javascript, now I want to add a counter(1/10, 2/10, 3/10...) beside my "prev/next" buttons but nothing seemed to work.
This is my first time attempting to make a website, I know nothing about jQuery, so please stick with html+javascript if possible. Here is my script
var image = new Array(
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/_MG_7747.jpg",
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/1109163s.jpg")
var imgNumber=1
var numberOfImg=2
function previousImage(){
if(imgNumber>1){
imgNumber--
}
else{
imgNumber = numberOfImg
}
document.slideImage.src = image[imgNumber-1]
}
function nextImage(){
if(imgNumber < numberOfImg){
imgNumber++
}
else{
imgNumber = 1
}
document.slideImage.src = image[imgNumber-1]
}
if(document.images){
var image1 = new Image()
image1.src = "http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/_MG_7747.jpg"
var image2 = new Image()
image2.src = "http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/1109163s.jpg"
}
Script+html: http://jsfiddle.net/nLHY9/5/
(Prev/Next buttons seem not to be working on this----they work fine when I launched them from laptop to browser.)
you could have used some existing javascript image sliders, for example, sliderman slider, for your current code, you can do like, add an element like span, to hold the count, and you could add a function like:
function changeCounter(cur, total) {
document.getElementById("counter").innerHTML = cur + "/" + total;
}
and call it in your previousImage() and nextImage() functions, as in this demo jsfiddle
There are many pure css slideshows that are beautiful and can do impressive things. However, as you try to support older browsers, the pure css slideshows get less and less impressive or even impossible. JavaScript is the most flexible and powerful way to go. That being, I wanted to help you clean up your code. I only had a few minutes, so this is a quickly thrown together plugin, but it should get you on the right track.
First, a few notes on your code:
//you're missing semicolons everywhere. ";"
/* "var image" is very unclear.
* it's an array, so it should be plural "images"
* there aren't images in this array - it's image urls or sources
* instead of "new Array" you could just use "[]"
*/
var image = new Array(
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/_MG_7747.jpg",
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/1109163s.jpg")
var imgNumber=1 //the name doesn't mean anything. I have to assume that you mean "currentImgNumber" or something to that effect
var numberOfImg=2 //this could be determined by checking the length of your array - myArray.length
And here's my exampe plugin:
Live demo here (click).
/***** This section is how you use the plugin. I start writing with the usage and then I make it mean something *****/
window.onload = function() { //when the page is loaded
var fooElem = document.getElementById('foo'); //get an element where we will attach the plugin
var foo = Object.create(slideshow); //create a new slideshow object
foo.create({ //create a slideshow with the given options
element: fooElem, //the element where the slideshow will be
sources: [ //image urls
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/_MG_7747.jpg",
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/1109163s.jpg"
]
});
//we can make more of these and with different options
var barElem = document.getElementById('bar');
var bar = Object.create(slideshow);
bar.create({
element: barElem,
sources: [
"http://eggboss.com/wp-content/uploads/2013/09/The-Gentleman-233x300.png",
"http://fc07.deviantart.net/fs71/f/2013/040/8/a/profile_picture_by_classy_like_a_sir-d5uf426.jpg"
]
});
};
/**** now let's create the plugin and make it work as it is used above *****/
var slideshow = {
currentIndex: 0,
imgs: [],
create: function(options) {
options.element.className+= ' slideshow'; //add a class to the main element for styling
this.imgs = this.getImgs(options.sources); //make img html
var controls = this.getControls(); //make controls
//add the html to the element from the options
var frag = document.createDocumentFragment();
this.imgs.forEach(function(img) {
frag.appendChild(img);
});
frag.appendChild(controls);
options.element.appendChild(frag);
},
getImgs: function(sources) {
var imgs = [];
sources.forEach(function(src, i) {
var img = document.createElement('img');
img.src = src;
imgs.push(img);
if (i > 0) {
img.style.display = 'none'; //hide all but first image
}
});
return imgs;
},
getControls: function() {
var that = this; //so that we can access "this" within the click functions
var controls = document.createElement('div');
controls.className = 'controls';
var counter = document.createElement('span');
counter.className = 'counter';
this.setCounter(counter);
var prev = document.createElement('a');
prev.textContent = 'Prev';
prev.className = 'prev';
prev.addEventListener('click', function() {
newIndex = (that.currentIndex) ? that.currentIndex-1 : that.imgs.length-1;
that.changeImg(newIndex, counter);
});
var next = document.createElement('a');
next.textContent = 'Next';
next.className = 'next';
next.addEventListener('click', function() {
newIndex = (that.currentIndex !== that.imgs.length-1) ? that.currentIndex+1 : 0;
that.changeImg(newIndex, counter);
});
controls.appendChild(prev);
controls.appendChild(next);
controls.appendChild(counter);
return controls;
},
changeImg: function(newIndex, counter) {
this.imgs[this.currentIndex].style.display = 'none';
this.imgs[newIndex].style.display = 'inline';
this.currentIndex = newIndex;
this.setCounter(counter);
},
setCounter: function(counter) {
counter.textContent = (this.currentIndex+1)+' / '+this.imgs.length;
}
};
I have been working on a simple math game and am having problems getting the overall answer results to return after the end of the game.
Here is what my return function looks like
function pShowResults() {
var pNumResults = document.getElementById("results");
for (var i = 0; i <= 10; i++) {
pNumStore.push(pNumGuess[i]);
var pNumTable = document.createElement("div");
pNumTable.innerHTML = (pNumGuess[i]);
pNumResults.appendChild(pNumTable);
}
}
Here is the full script
Pretty much need debugging help. I new to this so I'm guessing there is a ton that's off, but as long as I can get the results fed back I should be fine.
You are not passing the value of x in many placess
$(document).ready(function () {
//declare arrays and variables for use below
var pNum1 = [];
var pNum2 = [];
var pNumAns = [];
var pNumGuess = [];
var pNumStore = [];
var pNumCarry = 0;
var pNumTrack = 0;
var pNumMessageRight = ['Awesome Job!', 'Correct!', 'Great Job!'];
var pNumMessageWrong = ['Oh No! That Was Wrong!', 'Incorrect!', 'That\'s Wrong'];
$(".Play").click(function () {
$("#popup").attr("class", "on");
pNumTrack = 0;
pNumGen(pNumTrack);
});
$(".pNumSubmit").click(function () {
pNumCalc(pNumTrack-1);
});
$(".pNumNext").click(function () {
pNumGen(pNumTrack);
});
function pNumGen(x) {
pNum1[x] = (Math.round(Math.random() * 51));
pNum2[x] = (Math.round(Math.random() * 51));
pNumAns[x] = pNum1[x] + pNum2[x];
$(".pNum1").html(pNum1[x]);
$(".pNum2").html(pNum2[x]);
$(".pNumGuess").val("");
$(".pNum1").html(pNumTrack[x]);
if (pNumTrack == 2) {
$(".pNumNext").html("");
$(".pNumSubmit").html("Close");
pShowResults();
}
pNumTrack++;
}
function pNumCalc(x) {
pNumGuess[x] = $(".pNumGuess").val();
if (pNumGuess[x] == pNumAns[x]) {
$(".message").html(pNumMessageRight[Math.floor(Math.random() * pNumMessageRight.length)]);
$(".pNumNext").html("Next Question >")
} else {
$(".message").html(pNumMessageWrong[Math.floor(Math.random() * pNumMessageWrong.length)]);
$(".pNumNext").html("Maybe The Next Question >")
}
}
function pShowResults() {
var pNumResults = document.getElementById("results");
for (var i = 0; i < pNumGuess.length; i++) {
pNumStore.push(pNumGuess[i]);
var pNumTable = document.createElement("div");
pNumTable.innerHTML = (pNumGuess[i]);
pNumResults.appendChild(pNumTable);
}
}
});
Demo: Fiddle
There is a function called pNumCalc in your code which you have set to take in an argument, but you never pass one in. You use the argument to store the results in the pNumGuess array, but since the argument is never passed in, the guesses are never stored, and you end up with undefined as the answers the user gave.
Updated fiddle: http://jsfiddle.net/dwdX9/2/. Not sure how close this is to what you actually want though, but hopefully it gets you on the right track.
Because StackOverflow wants code to to be included when JSFiddle is...:
pNumCalc(pNumTrack)
You forget to define array before use it.
function pShowResults() {
var pNumStore = new Array();
var pNumResults = document.getElementById("results");
for (var i = 0; i <= 10; i++) {
pNumStore.push(pNumGuess[i]);
var pNumTable = document.createElement("div");
pNumTable.innerHTML = (pNumGuess[i]);
pNumResults.appendChild(pNumTable);
}
}
I must suggest you should use jquery instead.
After visiting your Fiddle seems like there are many problems with the code. and also your question is unclear.
for e.g.
$(".pNumSubmit").click(function () {
//why x value not passed?
pNumCalc();
});
function pNumCalc(x) {
pNumGuess[x] = $(".pNumGuess").val();
if (pNumGuess[x] == pNumAns[x]) {
$(".message").html(pNumMessageRight[Math.floor(Math.random() * pNumMessageRight.length)]);
$(".pNumNext").html("Next Question >")
} else {
$(".message").html(pNumMessageWrong[Math.floor(Math.random() * pNumMessageWrong.length)]);
$(".pNumNext").html("Maybe The Next Question >")
}
}
Please clear which array is returning undefined so that others can help you.
I'm studying javascript for the first time and I've some doubt: I have two arrays; the first one contain the image of a person, the second one his personal informations (the arrays' length is the same because they contain the same number of people). I'd like to write the content in my page so print the image and the infos of the first user, then the image and the infos of the second and so on...
How can I do it?
this is the code:
function jsonCard()
{
var richiestaCard = new XMLHttpRequest();
richiestaCard.onreadystatechange = function()
{
if(richiestaCard.readyState == 4)
{
var objectcardjson = {};
window.arrayCard= []; //creazione dell'array che conterrĂ le cards
objectcardjson = JSON.parse(richiestaCard.responseText);
arrayCard = objectcardjson.cards; //the first array
}
}
richiestaCard.open("GET", "longanocard.json", true);
richiestaCard.send(null);
}
function jsonEntity()
{
var richiestaEntity = new XMLHttpRequest();
richiestaEntity.onreadystatechange = function()
{
if(richiestaEntity.readyState == 4)
{
var objectentityjson = {};
window.arrayEntity= []; //creazione dell'array che conterrĂ le entity
objectentityjson = JSON.parse(richiestaEntity.responseText);
arrayEntity = objectentityjson.cards; //the second array
}
}
richiestaEntity.open("GET", "longano.json", true);
richiestaEntity.send(null);
}
function displayArrayCards()
{
jsonCard();
jsonEntity();
var inizioTag = "<img src=";
var fineTag = "\>";
for(i = 0; i < arrayCard.length; i++)
{
...
}
}
I'd like to have the image and then the infos (for the first user), the image and the infos for the second and so on all included in a div.
Try something along the lines of
function displayArrayCards()
{
jsonCard();
jsonEntity();
var wrapper = document.getElementById('div you want to put all of these users into');
for(i = 0; i < arrayCard.length; i++)
{
var userDiv = document.createElement('div');
var cardImg = document.createElement('img');
img.src = arrayCard[i];
/** Set other attributes for img **/
var entityDiv = document.createElement('div');
entityImg.innerHTML = arrayEntity[i];
/** Set other attributes for div **/
userDiv.appendChild(cardImg);
userDiv.appendChild(entityDiv);
wrapper.appendChild(userDiv);
}
}
Honestly there are a lot of ways to do this. Above is simply what I would do.