I am currently working on a small site and thought it would be quirky if the site adopted a random colour scheme on each visit - meaning each time a user visited the site, they would see a slightly different version.
I have attempted doing this using JavaScript but the site generates a new colour on each page visit...
Any help would be great - if it can be done solely using JS that is?
$(document).ready(function(){
// Generate random colour for the header of the site...
let colours = [
'#F8E71C',
'#1cf8b1',
'#1cb1f8',
'#c21cf8',
'#f81c3a',
];
let randomNumber = Math.floor(Math.random() * colours.length) + 1;
let header = $('.site-head');
let cardColour = $('.card__border');
localStorage.setItem("siteTheme", colours[randomNumber]);
if (localStorage.getItem("siteTheme")) {
header.css({
backgroundColor: localStorage.getItem("siteTheme"),
});
cardColour.css({
backgroundColor: localStorage.getItem("siteTheme"),
});
}
});
Your issue is that you generate a random color and then set it in localStorage, every time.
I refactored your code into functions with an initial check.
$(document).ready(function() {
let header = $('.site-head');
let cardColour = $('.card__border');
if (localStorage.getItem("siteTheme")) {
setColorScheme();
} else {
createColorScheme();
}
function createColorScheme() {
let colours = [
'#F8E71C',
'#1cf8b1',
'#1cb1f8',
'#c21cf8',
'#f81c3a',
];
let randomNumber = Math.floor(Math.random() * colours.length) + 1;
localStorage.setItem("siteTheme", colours[randomNumber]);
setColorScheme();
}
function setColorScheme() {
header.css({
backgroundColor: localStorage.getItem("siteTheme"),
});
cardColour.css({
backgroundColor: localStorage.getItem("siteTheme"),
});
}
});
Note: I think you have an error in the random generator part, sometimes the random color becomes undefined, I think it's because of the + 1.
Why don't you check localStorage before storing another random color sheme?
$(document).ready(function(){
// Generate random colour for the header of the site...
let colours = [
'#F8E71C',
'#1cf8b1',
'#1cb1f8',
'#c21cf8',
'#f81c3a',
];
let header = $('.site-head');
let cardColour = $('.card__border');
if (!localStorage.getItem("siteTheme")) {
let randomNumber = Math.floor(Math.random() * colours.length) + 1;
localStorage.setItem("siteTheme", colours[randomNumber]);
}
header.css({
backgroundColor: localStorage.getItem("siteTheme"),
});
cardColour.css({
backgroundColor: localStorage.getItem("siteTheme"),
});
});
Related
Completely new to JS and jQuery here. The code iterates through each one of the bars and when you press the Reset button, it should shrink the bars down to zero. However, I am trying to get this bar graph animation to stop but once you press the button, it goes through the animation and resets back again to where it was before. Any help would be appreciated!
function barGraph(data) {
//Create graph
var graph = document.createElement("div");
graph.id = "barGraph";
//inserting bar graph before previous 'label' div
const target = document.querySelector('#labels');
target.parentNode.insertBefore(graph, labels);
//Styling for graph
graph.style.position = "relative";
graph.style.marginTop = "20px";
graph.style.height = "500px";
graph.style.backgroundColor = "Gainsboro";
graph.style.borderBottomStyle = "solid";
graph.style.borderBottomWidth = "1px";
graph.style.overflow = "hidden";
//Iterating through each bar
var position = 50;
var width = 75;
for (i = 0; i < data.length; i += 1) {
var spendData = data[i];
var bar = document.createElement("div");
//set a unique id for each of the bars
bar.id = data[i].category;
//Styling for bar
bar.style.position = "absolute";
bar.style.left = position + "px";
bar.style.width = width + "px";
bar.style.backgroundColor = spendData.color;
bar.style.height = (spendData.amount) / 5 + "px";
bar.style.bottom = "0px";
bar.innerHTML = "$" + spendData.amount;
bar.style.fontSize = "11px";
bar.style.color = "Azure";
bar.style.fontWeight = "800";
bar.style.fontFamily = "Arial, Helvetica, sans-serif";
bar.style.textAlign = "center";
bar.style.padding = "1em";
//Appending to the graph
graph.appendChild(bar);
//Set bar width
position += (width * 2);
}
return graph;
}
window.onload = function() {
var data = [{
category: "Food and Dining",
amount: "2005.00",
color: "CadetBlue"
},
{
category: "Auto and Transport",
amount: "1471.31",
color: "CornflowerBlue"
},
{
category: "Shopping",
amount: "892.86",
color: "DarkCyan"
},
{
category: "Bills and Utilities",
amount: "531.60",
color: "DarkSeaGreen"
},
{
category: "Mortgage",
amount: "1646.00",
color: "LightSeaGreen"
},
{
category: "Entertainment",
amount: "179.52",
color: "YellowGreen"
}
];
document.getElementById("resetGraph").addEventListener("click", function() {
for (i = 0; i < data.length; i++) {
var bar = document.getElementById(data[i].category);
if (bar) {
bar.animate({
"height": "0px",
"padding": "0px"
}, 2000);
}
}
});
var graph = barGraph(data);
//document.div.appendChild(graph);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="labels"></div>
<button id="resetGraph">Reset graph</button>
<script src="js/spending-graph.js"></script>
Dom's animate() function will return an AnimationPlaybackEvent object. And we can use onFinish method to reset the height and width of the dom element or can hide it.
Can you please add following lines to your code after bar.animate() function.
.onfinish=function(e){
e.currentTarget.effect.target.style.visibility ="hidden"
};
like below snippet.
bar.animate({
"height": "0px",
"padding": "0px"
}, 2000).onfinish=function(e){
e.currentTarget.effect.target.style.visibility ="hidden"
};
Updated
Interesting question! AFAICT the problem is that you've mixed up jQuery's .animate() with the native Javascript .animate().
Your question is tagged jQuery-animate, you mention it explicitly, and the format of the parameter you are passing to .animate() is exactly what jQuery expects.
But your animate code is running against an HTML DOM element, not a jQuery element:
// bar here is an HTML DOM Element, not a jQuery object:
var bar = document.getElementById(data[i].category);
// That means this will run JS .animate, not jQuery's:
bar.animate( ... );
If you simply change that to run against a jQuery object, it works (almost) as expected:
var bar = $('#' + data[i].category);
bar.animate( ... );
I say almost because there is another problem:
bar.id = data[i].category;
This creates HTML IDs from your plain English categories, which include whitespace, like "Food and Dining". According to the spec:
id's value must not contain whitespace (spaces, tabs etc.).
And at least when trying to use IDs with spaces as jQuery selectors, this matters, and it does not work. So instead let's just use the array index, which is also guaranteed to be unique, with a prefix so we know what we're referring to:
bar.id = 'bar-' + i;
Here's a working snippet with those 2 changes.
Note: the last document.div.appendChild(graph); was throwing an error - maybe this was a debugging attempt, it isn't necessary and I've commented it out here.
function barGraph(data) {
//Create graph
var graph = document.createElement("div");
graph.id = "barGraph";
//inserting bar graph before previous 'label' div
const target = document.querySelector('#labels');
target.parentNode.insertBefore(graph, labels);
//Styling for graph
graph.style.position = "relative";
graph.style.marginTop = "20px";
graph.style.height = "500px";
graph.style.backgroundColor = "Gainsboro";
graph.style.borderBottomStyle = "solid";
graph.style.borderBottomWidth = "1px";
graph.style.overflow = "hidden";
//Iterating through each bar
var position = 50;
var width = 75;
for (i = 0; i < data.length; i += 1) {
var spendData = data[i];
var bar = document.createElement("div");
//set a unique id for each of the bars
// UPDATED - category includes spaces, just use array index
// bar.id = data[i].category;
bar.id = 'bar-' + i;
//Styling for bar
bar.style.position = "absolute";
bar.style.left = position + "px";
bar.style.width = width + "px";
bar.style.backgroundColor = spendData.color;
bar.style.height = (spendData.amount) / 5 + "px";
bar.style.bottom = "0px";
bar.innerHTML = "$" + spendData.amount;
bar.style.fontSize = "11px";
bar.style.color = "Azure";
bar.style.fontWeight = "800";
bar.style.fontFamily = "Arial, Helvetica, sans-serif";
bar.style.textAlign = "center";
bar.style.padding = "1em";
//Appending to the graph
graph.appendChild(bar);
//Set bar width
position += (width * 2);
}
return graph;
}
window.onload = function() {
var data = [{
category: "Food and Dining",
amount: "2005.00",
color: "CadetBlue"
},
{
category: "Auto and Transport",
amount: "1471.31",
color: "CornflowerBlue"
},
{
category: "Shopping",
amount: "892.86",
color: "DarkCyan"
},
{
category: "Bills and Utilities",
amount: "531.60",
color: "DarkSeaGreen"
},
{
category: "Mortgage",
amount: "1646.00",
color: "LightSeaGreen"
},
{
category: "Entertainment",
amount: "179.52",
color: "YellowGreen"
}
];
document.getElementById("resetGraph").addEventListener("click", function() {
for (i = 0; i < data.length; i++) {
// UPDATED: 1. use new format ID without spaces
// UPDATED: 2. use jQuery selector/animation
// UPDATED: 3. use bar.length to test if selector matched anything
var bar = $('#bar-' + i);
if (bar.length) {
bar.animate({
"height": "0px",
"padding": "0px"
}, 2000);
}
}
});
var graph = barGraph(data);
//document.div.appendChild(graph);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="labels"></div>
<button id="resetGraph">Reset graph</button>
So what is happening in your original code? I am not sure. It is the native Javascript .animate() that is running, not jQuery's. The first parameter of the Javascipt .animate() method should be:
Either an array of keyframe objects, or a keyframe object whose properties are arrays of values to iterate over.
Your code is passing an object, not an array, so .animate() will expect the latter, "a keyframe object". The Keyframe Formats spec gives a little more detail and some examples for what "a keyframe object" looks like:
element.animate({
opacity: [ 0, 1 ], // [ from, to ]
color: [ "#fff", "#000" ] // [ from, to ]
}, 2000);
Your object does not match this format though - each attribute is just a string, not an array of start/stop values. The Keyframe docs also describe Implicit to/from keyframes:
In newer browser versions, you are able to set a beginning or end state for an animation only (i.e. a single keyframe), and the browser will infer the other end of the animation if it is able to.
My guess is this is what is happening, somehow? The browser is inferring an implicit end frame of the start values?
I tried to update your code to use the right Keyframe format, so you can use the native .animate() and skip jQuery all together, but it does not work - the bars reset to their original height after the animation, just like in your original code, I don't know why:
document.getElementById("resetGraph").addEventListener("click", function() {
var bar, startHeight;
for (i = 0; i < data.length; i++) {
bar = document.getElementById('bar-' + i);
if (bar) {
startHeight = window.getComputedStyle(bar).height;
bar.animate({
height: [startHeight, '0px'],
padding: ['1em', '0']
}, 2000);
}
}
});
I have a little game I play around with to learn Javascript better.
The player gets to choose
So i'm doing a little dice game in javascript/jquery. I get some users (In this case players) from a REST API that i get with AJAX Like this:
var APICaller = (function () {
let endpoint = "https://jsonplaceholder.typicode.com/";
function api_call(method, url, data, callback) {
$.ajax({
url: url,
method: method,
data: data,
success: callback
});
}
function get_users(callback) {
let method = "GET";
let url = endpoint + "users";
let data = {};
api_call(method, url, data, callback);
}
return {
get_users: get_users,
};
})();
The person playing the game can choose a player from the user list and then press the play button.
When the play button is pressed the dice should roll 3 numbers for each player and display all the numbers at the side of each player. And then the dice value list should change after a time and only the total amount of the three dice values should be in that list, and also the user list should be in points order with the highest total points on the top.
I have manage to solve all of those problems but I just need guidance of how to make the player I choose to have a green background color in the final score board.
This is how my code looks like:
var players = [];
var currentPlayer;
function add_scoreboard() {
$("#my-list").css({
display: 'none'
});
$("#my-list2").css({
display: 'block'
});
// currentPlayer.style.background("green");
let elements = []
let container = document.querySelector('#main_gameDiv')
//Add each row to the array
container.querySelectorAll('.list-li2').forEach(el => elements.push(el))
//Clear the container
container.innerHTML = ''
//Sort the array from highest to lowest
elements.sort((a, b) => b.querySelector('.score').textContent - a.querySelector('.score').textContent)
//Put the elements back into the container
elements.forEach(e => container.appendChild(e))
if(elements.firstchild.data == currentPlayer.firstchild.data){
$(this).css({background: 'green'});
}
console.log(elements);
}
var EventHandlers = (function () {
function init() {
APICaller.get_users(on_get_users_success);
function on_get_users_success(response) {
//For each user in the API
$.each(response, function (i, user) {
$("#my-list").append('<li class="list-li"><a class="list-a">' + user.name + '</a><span class="score"></span></li>');
$("#my-list2").append('<li class="list-li2">' + user.name + '<span class="score"></span></li>');
var playerObject = {
id: user.id,
name: user.name,
score: 0
};
//Add all objects to the array
players.push(playerObject);
});
$("#my-list2").css({
display: 'none'
});
//change information
$("#info-txt").text("Välj en spelare!");
}
// On klick on a user make klicked user your own player.
$("#my-list").on('click', '.list-a', function () {
currentPlayer = this;
$("#info-txt").text("Tryck på spela knappen för att börja spelet!");
$("#currentPlayer-div").animate({
height: '300px',
opacity: '1'
});
$("#currentPlayer-h3").text(this.text);
});
// On klick of the play button
$("#startGame-button").click(function () {
$("#info-txt").text("Vänta 5 sekunder tills scoreboarden visas :)");
setTimeout(function () {
add_scoreboard();
}, 5000);
$("#my-list2").css({
display: 'none'
});
console.log(players);//Show players in console just for extra info
$(".score").animate({
opacity: '1'
});
$("#currentPlayer-div").animate({
height: '150px'
});
$("#startGame-button").animate({
opacity: '0'
});
$("#dice_value").animate({
opacity: '1'
});
$("#my-list li").each(function (index) {
var numbers = [];
var v1 = Math.floor(Math.random() * 6) + 1;
var v2 = Math.floor(Math.random() * 6) + 1;
var v3 = Math.floor(Math.random() * 6) + 1;
//Add the numbers to the array
numbers.push(v1, v2, v3);
var totalScore = numbers.reduce(function (a, b) {
return a + b;
}, 0); //Count the sum of the array
//Set the players points to the sum of the array
players[index].score = totalScore;
//Find every list item of type span and set HTML to the content of the array
$(this).find(".score").html(numbers.toString());
});
$("#my-list2 li").each(function (index) {
var numbers = [];
var v1 = Math.floor(Math.random() * 6) + 1;
var v2 = Math.floor(Math.random() * 6) + 1;
var v3 = Math.floor(Math.random() * 6) + 1;
//Add the numbers to the array
numbers.push(v1, v2, v3);
var totalScore = numbers.reduce(function (a, b) {
return a + b;
}, 0); //Count the sum of the array
//Set the players points to the sum of the array
players[index].score = totalScore;
//Find every list item of type span and set HTML to the content of the array
$(this).find(".score").html(totalScore.toString());
});
});
}
return {
init: init,
}
})();
$(document).ready(function () {
EventHandlers.init();
});
This is where i choose the player:
// On klick on a user make klicked user your own player.
$("#my-list").on('click', '.list-a', function () {
currentPlayer = this;
$("#info-txt").text("Tryck på spela knappen för att börja spelet!");
$("#currentPlayer-div").animate({
height: '300px',
opacity: '1'
});
$("#currentPlayer-h3").text(this.text);
});
And this is where I try to set the color on that:
function add_scoreboard() {
$("#my-list").css({
display: 'none'
});
$("#my-list2").css({
display: 'block'
});
// currentPlayer.style.background("green");
let elements = []
let container = document.querySelector('#main_gameDiv')
//Add each row to the array
container.querySelectorAll('.list-li2').forEach(el => elements.push(el))
//Clear the container
container.innerHTML = ''
//Sort the array from highest to lowest
elements.sort((a, b) => b.querySelector('.score').textContent - a.querySelector('.score').textContent)
//Put the elements back into the container
elements.forEach(e => container.appendChild(e))
if(elements.firstchild.data == currentPlayer.firstchild.data){
$(this).css({background: 'green'});
}
console.log(elements);
}
I think it is if(elements.firstchild.data == currentPlayer.firstchild.data){ $(this).css({background: 'green'}); } and i know there is a problem because it is not changing background color.
Hope that describes it enough.
Thanks in advance!
Since elements is an array it doesn't have a property firstchild so that is why you get Uncaught TypeError: Cannot read property 'data' of undefined. It seems like what you want is to include that code in your elements.forEach function.
For example:
//Put the elements back into the container
elements.forEach(e => {
container.appendChild(e);
if (e.firstchild.data == currentPlayer.firstchild.data) {
$(e).css({
background: 'green'
});
}
});
I'm working on trying to create a random image generator that will show a random image in Javascript. I've been able to make it show a random image via the Javascript math and using random variables. But sadly I'm still yet to be eligible to make my code repeat itself.
I know its probably very simplistic but as you know, we all start from somewhere. I've tried my best to compact my code and I have looked at other stackoverflow recourses but im still in no luck.
A quick overview of what happens, you are meant to be able to press a button and then, a selected random image is replaced by the current one.
What I want: to be able to press a button and then it will proceed to cycle through the random images 'x' times.
My code:
function imgRandom() {
var myImages1 = new Array();
myImages1[1] = "images/Random/Icon1.png";
myImages1[2] = "images/Random/Icon2.png";
myImages1[3] = "images/Random/Icon3.png";
myImages1[4] = "images/Random/Icon4.png";
myImages1[5] = "images/Random/Icon5.png";
myImages1[6] = "images/Random/Icon6.png";
myImages1[7] = "images/Random/Icon7.png";
myImages1[8] = "images/Random/Icon8.png";
myImages1[9] = "images/Random/Icon9.png";
myImages1[10] = "images/Random/Icon10.png";
myImages1[11] = "images/Random/Icon11.png";
myImages1[12] = "images/Random/Icon12.png";
myImages1[13] = "images/Random/Icon13.png";
myImages1[14] = "images/Random/Icon14.png";
myImages1[15] = "images/Random/Icon15.png";
myImages1[16] = "images/Random/Icon16.png";
myImages1[17] = "images/Random/Icon17.png";
myImages1[18] = "images/Random/Icon18.png";
myImages1[19] = "images/Random/Icon19.png";
myImages1[20] = "images/Random/Icon20.png";
myImages1[21] = "images/Random/Icon21.png";
myImages1[22] = "images/Random/Icon22.png";
myImages1[23] = "images/Random/Icon23.png";
var rnd = Math.floor(Math.random() * myImages1.length);
if (rnd == 0) {
rnd = 1;
}
document.getElementById("gen-img").src = myImages1[rnd];
}
<center>
<p>
<img id="gen-img" class="character-image" src="images/QuestionMark.png" style="width:180px;height:310px;">
</p>
<p>
<input type="button" class="button" value="Choose" onclick="setTimeout(imgRandom, 3000);" />
</p>
</center>
I hope this isn't too confusing, i'll be active for a long time if you're able to help! Thanks,
David.
I refactored your code a bit with an possible approach Here's the fiddle: https://jsfiddle.net/mrlew/d2py2jvb/
I commented with some explanations.
/* some flags you can set */
var timesTocycle = 10;
var totalImagesToCreate = 23;
var timeBetweenCycle = 3000;
/* global variables */
var allMyImages = [];
var timesCycled = 0;
/*
function to create your images path.
Called once when you load your page.
*/
function createMyImages(total) {
for (var i=0; i<total;i++) {
var imageNumber = i+1;
var path = getImagePath(imageNumber);
allMyImages.push(path);
}
}
/* separated your path getter */
function getImagePath(imageNumber) {
return "images/Random/Icon" + imageNumber + ".png";
}
/* this is the function called when you press the button and when one cycle ends */
function triggerRandomImage() {
if (timesCycled >= timesTocycle) return;
setTimeout(displayRandomImage, timeBetweenCycle);
}
/* random integer javascript function */
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
/* function called on setTimeout */
function displayRandomImage() {
var rnd = getRandomInt(0,allMyImages.length-1);
var imageToDisplayPath = allMyImages[rnd];
document.getElementById("gen-img").src = imageToDisplayPath;
timesCycled++;
triggerRandomImage();
/* debug info */
document.getElementById('info').innerText = "(showing: " + imageToDisplayPath + ", cycle: " + timesCycled + ", max: " + timesTocycle + ")";
}
/* call this function to populate the allMyImages array */
createMyImages(totalImagesToCreate);
I believe what you want is for loop. Let me demonstrate with your code:
var count = 10; //number of times to run the for loop
for (i = 0; i < count; i++){
var rnd = Math.floor(Math.random() * myImages1.length);
if (rnd == 0) {
rnd = 1;
}
document.getElementById("gen-img").src = myImages1[rnd];
}
The above code would run the randomizing bit 10 times (= 10 images). Now, I have not tested it yet, but I believe that the images would flash by really quickly. Also, unrelated to the question you may want to read about Javascript arrays.
I am attempting to write my own website, however I had an idea to have an Array of background colors that the site would change to at random (but not repeating the same color back to back) every time the page is loaded / refreshed. I remember doing something very similar to this when I was in school but I just can't quite remember how it was done.
This is what I have so far, I have been fiddling with this for about a day and just can't quite figure out what I am missing.
Any assistance would be greatly appreciated.
<html>
<head>
<script type="text/javascript">
<!--
var color = new Array();
color[0] = "#CC99FF";
color[1] = "#FF99CC";
color[2] = "#FF9999";
color[3] = "#FFCC99";
color[4] = "#FFFF99";
color[5] = "#CCFF99";
color[6] = "#99FF99";
color[7] = "#99FFCC";
color[8] = "#66FFFF";
color[9] = "#66CCFF";
function changeColor()
{
var randomColor = Math.floor(Math.random() * color.length);
document.body.style.backgroundColor = color[randomColor];
}
--!>
</script>
</head>
<body onload="changeColor()">
</body>
</html>
I noticed that your question had a second part, which is to not repeat the same color twice. Since you are doing this on a reload, it becomes a little trickier since you cannot just store the last color in a simple variable.
For this, I decided to utilized localStorage. I leveraged some of the other answers as well that mentioned you need to use the style property on the body element.
Here is a Fiddle of the solution and the code is below:
As mentioned, you need to use the style property to set the background color:
document.getElementsByTagName("body")[0].style.backgroundColor=color[randomColor];
Then, you need to keep looking for an index that wasn't used in the last run:
First, I grab the currently stored index, or -1 if it doesn't exist.
var lastColorIndex = localStorage.getItem('lastColorIndex') || -1;
Then set do the loop while the two indices aren't equal or if random color is -1 (this is for on the initial page load). Note that we are using == for a 'truthy' check since localStorage will return a string and Math.random() returns a number;
while(lastColorIndex == randomColor || randomColor === -1)
Finally, set the randomColor value into local storage.
localStorage.setItem('lastColorIndex',randomColor);
All together now:
function changeColor()
{
var lastColorIndex = localStorage.getItem('lastColorIndex') || -1;
var randomColor = -1;
while(lastColorIndex == randomColor || randomColor === -1) {
randomColor = Math.floor(Math.random() * color.length);
console.log('LastIndex: ' + lastColorIndex + ',RandomColor: ' + randomColor);
};
localStorage.setItem('lastColorIndex',randomColor);
//console.log(randomColor);
console.log(color[randomColor]);
document.getElementsByTagName("body")[0].style.backgroundColor=color[randomColor];
};
you must access to you body style :
function changeColor() {
var randomColor = Math.floor(Math.random() * color.length);
document.body.style.backgroundColor = color[randomColor];
}
you can change the background color like that
function changeColor()
{
var randomColor = Math.floor(Math.random() * color.length);
document.body.style.background = color[randomColor];
}
You are not accessing the background color property correctly.Use it this way.
function changeColor()
{
var randomColor = Math.floor(Math.random() * color.length);
document.body.style.backgroundColor = color[randomColor]; //THIS IS IMP
}
Have a look at this fiddle (click 'run' several times to simulate reload) :
http://jsfiddle.net/4j61r6go/
function changeColor()
{
var randomColor = Math.floor(Math.random() * color.length);
console.log(color[randomColor]);
document.getElementsByTagName("body")[0].style.backgroundColor=color[randomColor];
};
you should call 'changeColor' in windowor document 'onload'.
I have found a code in a theme hope this will help you
$('.animated-bg').each(function(){
var $this = $(this),
colors = ['#ec008c', '#00bcc3', '#5fb26a', '#fc7331'];
setInterval(function(){
var color = colors.shift();
colors.push(color);
$this.animate({backgroundColor: color}, 2000);
},4000);
});
So far I am tring to make functions for placing ships on board and I have some problems with function for checking is some field available. My basic idea is to have one method which will be called on button click:
$("#dodaj1x1").click(function(){
var raspolozivo=parseInt($("#raspolozivo1x1").text());
if(raspolozivo>0){
generisi1x1();//call for function that generate random field
var novoRaspolozivo= raspolozivo-1;
$("#raspolozivo1x1").html(novoRaspolozivo);
}
else{
alert("Rasporedjeni svi raspolozivi brodovi ovog tipa!");
}
});
and it will call function to generate random field:
function generisi1x1(){
var minR = 0;
var maxR = 9;
var minK = 0;
var maxK = 9;
randRed=Math.floor(Math.random() * (maxR - minR + 1)) + minR;
randKol=Math.floor(Math.random() * (maxK - minK + 1)) + minK;
proveri1x1(randRed,randKol);//call to function to check is field available
}
than function generisi1x1() calls function that checks is that field available:
function proveri1x1(randRed,randKol){
for(i=randRed-1;i<randRed+2;i++){
for(j=randKol-1;j<randKol+2;j++){
if($(".red"+i+".kolona"+j+"").hasClass('deoBroda')){
alert("red:"+" "+i+" kolona:"+j);
generisi1x1();
}
else { postavi1x1(randRed,randKol);}
}
}
}
And my problem is that sometimes this work great(at least it looks that work great,maybe pure luck), and sometimes it generate only 3 ships 1x1(there should be 4) , sometimes it show me message about problem and generate 5 ships(4 on right places, 1 on bad) etc.
Printscreen of bad case: Added ship 1x1 on position 5,3 right next to ship 4x1
Here is live demo of entire code: Live demo
So far I made available to insert ships 4x1 and 1x1, and doing check only for 1x1, plan is to do the same for all ships, any help would be great.
You will find it easier to understand if proveri1x1() performs the checks and returns true or false, and generisi1x1() performs the postavi1x1() action;
function generisi1x1() {
var minR = 0, maxR = 9, minK = 0, maxK = 9;
randRed = Math.floor(Math.random() * (maxR - minR + 1)) + minR;
randKol = Math.floor(Math.random() * (maxK - minK + 1)) + minK;
if(proveri1x1(randRed, randKol)) { //call to function to check is field available
postavi1x1(randRed,randKol);//set
} else {
generisi1x1();//try again
}
}
function proveri1x1(randRed, randKol) {
for(var i=randRed-1; i<randRed+2; i++) {
for(var j=randKol-1; j<randKol+2; j++) {
if($(".red" + i + ".kolona" + j).hasClass('deoBroda')) {
return false;
}
}
}
return true;//<<<< note the position of this return statement
}