I am creating a color picker type tool using a table. I want to apply a color to each cell in 16 by 16 table. I am having trouble with cycling through colors probably because I'm not sure how to go about it. How should I do this?
Hexagonal
You can use this BaseConverter. Make a loops that writes decimal numbers in 0-255 range with given interval, converts them to hexagonal and create a string containing hex number of three colors with a "#" before them (rgb).
It will work the same way as snippet below but you need to convert numbers additionaly: "rgb(" + (i * interval) + ", " + (j * interval) + ", " + (k * interval) + ")" will be changed to "#" + bin2hex(i * interval) + bin2hex(j * interval) + bin2hex(k * interval).
Decimal with an example
Otherwise just use the other format of CSS Colors which is rgb(red, green, blue) which takes decimal numbers as arguments.
/* Please keep in mind that this function is just an example.
You can modify it to create different palette schemes. */
var tot = 800; /* total amount of blocks */
var num = Math.pow(tot, 1/3); /* amount of blocks in one axis */
var interval = parseInt(255 / num); /* color diff step */
var cont = document.getElementById("container");
var tmp = 0;
for (i = 0; i < num; i++) {
for (j = 0; j < num; j++) {
for (k = 0; k < num; k++) {
/* creates block, add styled class and set color */
var block = document.createElement("div");
block.className = "foo";
block.style.backgroundColor = "rgb(" + (i * interval) + ", " + (j * interval) + ", " + (k * interval) + ")";
cont.appendChild(block);
/* i - red, j - green, k - blue */
tmp++;
}
}
}
.foo {
width: 20px;
height: 20px;
float: left;
}
<!-- It will be populated with JS -->
<div id="container"></div>
If I get the idea of your question wrong then sorry. That's how I would understand "cycle".
The problem you might encounter is that rgb() takes three arguments and you want to create two dimensional array with it. Try looking for rgb palette in google graphics to get the idea how RGB palette may look like and then change the code from above.
Related
This code is done in HTML javascript.
The following functions (placero() and runro()) are called in that order. placero() seems to initialize the xs and ys of the object list correctly, but by the time the first line of runro() is called, all of the xs and ys have become NaN.
The goal of the code was to make a program that creates rooms and connects them with corridors. Previous steps have inititalized the rooms and corridor layout, but the job of placero() is to place each room somewhere random on the map.
the code is as follows:
runm does all the initial setting code(such as the room member initialization) and does all the other work before placero(). I have been clicking the buttons in the intended order(sequentially), so that shouldnt be the problem.
var roomes = new Array(0);
function randIntBetween(min, max) { // min and max included
return Math.floor(Math.random() * (max - min + 1) + min);
}
//before any function calls, rooms is initialized as follows(well after the input has been entered, in most cases):
roomMax = document.getElementById("inp1").value; //this is the inputted number of rooms being made
for (var k = 0; k < roomMax; k++) {
var obj = {
ind: k,
x: -1,
y: -1,
neighb: Array(0)
}
roomes.push(obj);
}
//then some work is done, placing the indexes of other rooms in the neighbors array in each room.
//none of the in-between code edits x or y.
function placero() {
for (var kis = 0; kis < roomes.length; kis++) {
var x = randIntBetween(5, mapX - 5); //get a random x and y for room position
var y = randIntBetween(5, 5);
roomes[kis].x = x;
roomes[kis].y = y;
}
console.log(roomes); //prints a correct array
}
function runro() {
console.log(roomes); //prints an incorrect array
var iterCount = 2;
//this code aims to place rooms closer to their neighbors, by averaging a rooms position with that of its neighbors and moving it half the way in that direction.
for (var ki = 0; ki < iterCount; ki++) { //for each iteration in which the rooms are moved,
for (var kt = 0; kt < roomes.length; kt++) { //for each room
var coun = NeighbCount(roomes[kt]); //get number of neighbors(will be used for averageing)
console.log(coun);
var sumx = 0;
var sumy = 0;
for (var km = 0; km < coun; km++) { //for each neighbor,
sumx = sumx + roomes[roomes[kt].neighb[km]].x; //add its position to the sum position
sumy = sumy + roomes[roomes[kt].neighb[km]].y;
}
sumx = sumx / coun; //then divide by number of neighbors to get new position
sumy = sumy / coun;
console.log(sumx + " " + roomes[kt].x); //troubleshooting
console.log(sumy + " " + roomes[kt].y);
roomes[kt].x = sumx / 2 + roomes[kt].x / 2; //setting new positions
roomes[kt].y = sumy / 2 + roomes[kt].y / 2;
}
}
}
<div>
<input type="number" id="inp1" name="inp1"><br>
</div>
<button onclick="runm()">Make room map</button>
<button onclick="placero()">place rooms</button>
<button onclick="runro()">Make rooms</button>
You're probably getting the error because roomMax is of string type and not number type. To solve this, make the following modifications to your code:
roomMax = parseInt(document.getElementById("inp1").value);
The value from an input will always be a string. The code above changes the type.
Look through your code to see if you have any similar mistakes.
Im trying to make a script that changes the color of my lights using a javascript. So first I want to use the current RGB value to check an array, then if there is a match then select the next in line. But since I dont have all possible combinations I want to find the closest possible match if there is not exact match. This is what I tried so far.
kelvin_table = [
{r:255,g:56,b:0},
{r:255,g:71,b:0},
{r:255,g:83,b:0}
];
var red = 255
var green = 84
var blue = 0
index = kelvin_table.findIndex(x => x.r ===red && x.g ===green && x.b ===blue);
alert(index);
if (index = -1)
{
alert("In de If Statement");
var Redindex = [], i;
for(i = 0; i < kelvin_table.length; i++)
if (kelvin_table[i].r === red)
Redindex.push(i);
alert(Redindex);
var Greenindex = [], i2;
for(i2 = 0; i2 < Redindex.length; i2++)
//alert(Redindex[i2]);
var gi = Redindex[i2];
alert(gi);
if (kelvin_table[gi].g === green)
Greenindex.push(i);
alert(Greenindex);
var Blueindex = [], i3;
for(i3 = 0; i3 < Greenindex.length; i3++)
//alert(Greenindex[i3]);
var bi = Greenindex[i3];
alert(bi);
if (kelvin_table[bi].b === blue)
Blueindex.push(i);
alert(Blueindex);
}
var valueAtIndex1 = kelvin_table[2];
alert(valueAtIndex1.g);
Of course the kelvin_table will be much bigger in the end, but this is my test amount. As you expect with below red, green and blue values I get Index -1. If I have green 83 I get Index 2, so that part works.
But now I added an If statement for when index = -1. My approach so far has been trying to narrow the index by first searching for Red values, then Green values within the results from Red and then search the Blue results in the filtered list from Blue. Eventually I hope this will only give me 1 option.
I was thinking that if there is no match, like in the example below would be Blue, then try to search value -1, then +1, -2, +2...until there is a matching value. I'm just not really sure how to approach this.
And perhaps someone has a far better way of finding the closest match.
Thanks in advance
The problem is that you didn't type '{' or '}' to the for of green and blue.
But I don't understand what the point of the code inside the if, its the same as:
kelvin_table.findIndex(x => x.r ===red && x.g ===green && x.b ===blue);
If you try to find the closest color you can use this code with closestIndex({r:red,g:green,b:blue}, kelvin_table)
function colorDistance(c0, c1) {
var dr = c1.r - c0.r;
var dg = c1.g - c0.g;
var db = c1.b - c0.b;
return Math.sqrt(dr * dr + dg * dg + db * db);
}
function closestIndex(color, kelvin_table) {
var minIndex = -1;
var minDistance = Infinity;
for (var i = 0; i < kelvin_table.length; i++) {
var distance = colorDistance(color, kelvin_table[i]);
if (distance <= minDistance) {
minIndex = i;
minDistance = distance;
}
}
return minIndex;
}
note: I use here a lazy version of colorDistance
I have to create a 20 column bar-chart. The bar on the very right gets updated every second with a random number which gives the bar its height. After one second the value gets transferred to its neighbour on the left and so on. To connect the values from the array to css, I created this piece of code. On the left (barchart) is connected to the div via querySelectorAll and then indexed with [i], on the right i take the corresponding value from the array. Since I need to do 20 bars, it would make sense to use a for loop, but I don't really know how to create it... Any ideas?
const arr = [];
let number = "";
function timer() {
setInterval(function () {
number = Math.floor((Math.random() * 100) + 1);
const barchart = document.querySelectorAll(".bar");
barchart[4].style.height = number + "%";
barchart[3].style.height = arr[4] + "%";
barchart[2].style.height = arr[3] + "%";
barchart[1].style.height = arr[2] + "%";
barchart[0].style.height = arr[1] + "%";
arr.push(number);
if (arr.length > 5) {
arr.shift();
}
console.log(arr);
}, 1000);
}
How to shorten this into a loop?
barchart[4].style.height = number + "%";
barchart[3].style.height = arr[4] + "%";
barchart[2].style.height = arr[3] + "%";
barchart[1].style.height = arr[2] + "%";
barchart[0].style.height = arr[1] + "%";
Looking at what you have so far the first time the code runs arr is only initialized with no elements at all and you are attempting to reach out of bound indices which returns undefined
Moreover, you should not use initialize an array as a const if you are planning on changing the values it stores.
Now for the problem at hand:
Considering the bar on the far right is positioned at the last index of barchart and that arr contains the corresponding bar's heights:
//give the bar on the far right a random height.
barchart[barchart.length-1].style.height = number + "%";
//loop through barcharts array from end to start excluding the last bar.
for(let i=barchart.length-2; i>=0; i--)
{
//give each bar the height of his right neighbour
barchart[i].style.height = arr[i+1] + "%";
}
How about just making sure arr has what you want before updating the bar chart, then you can just iterate over it.
Adding the new number and then making sure there are at most 5 numbers allows you to just iterate over all the elements in the array and it will only update the bars for the values it contains - no index out of bounds issues (you just get undefined with JS though.)
NOTE, I replaced querySelectorAll with querySelector as querySelectorAll returns a collection of matched elements rather than a single element.
const arr = [];
let number = "";
function timer() {
setInterval(function() {
number = Math.floor((Math.random() * 100) + 1);
arr.push(number);
// make sure arr max's out at 5 numbers
if (arr.length > 5)
arr.shift();
// update the bar chart(s)
const barchart = document.querySelector(".bar");
for (let i = 0; i < arr.length; i++)
barchart[i].style.height = arr[i] + "%";
console.log(arr);
}, 1000);
}
for(var i = 0;i < 5;i++){
barchart[i].style.height = arr[i+1] + "%";
}
I have a little assignment I can't manage to complete.
*Goal
You have recently been assigned to a new amusement park’s center of analysis and supervision. Your mission is to estimate each day what the earnings will be for each ride that day. You start by looking at the roller coaster.
Rules
You notice that people like the roller coaster so much that as soon as they have finished a ride, they cannot help but go back for another one.
People queue up in front of the attraction
They can either be alone or in a group. When groups are in the queue, they necessarily want to ride together, without being separated.
People never overtake each other in the queue.
When there isn’t enough space in the attraction for the next group in the queue, the ride starts (so it is not always full).
As soon as the ride is finished, the groups that come out, go back into the queue in the same order.*
var limited_number_of_seats_per_ride = 3, //L
limited_number_of_turns_per_ride = 3, //C
limited_number_of_groups_in_queue = 4, //N
number_of_person_per_group = [3,1,1,2]; //P
function earning_per_day(P,L,C,price){
/**
*
* #P {array} number of person per group.
* #L {int} limited number of seats per ride.
* #C {int} limited number of times the ride goes per day.
* #price {int} price per person per ride.
*
* #daily_earning {int} estimated daily earnings.
*/
var daily_earning = 0;
var total_per_ride = 0;
// calculates sum of the earning for each ride per day
for (var j = 0; j < C; j++) {
total_per_ride = 0;
position_i = 0;
// calculates the number of person on each ride
for (var i = position_i; i < P.length; i++){
while((total_per_ride + P[i+1]) < L){
total_per_ride += P[i];
console.log(i + ' total_per_ride = ' + total_per_ride);
}
position_i = i;
console.log('position_i = ' + position_i);
}
daily_earning += total_per_ride;
console.log('daily_earning ' + daily_earning);
}
}
// calling
earning_per_day(number_of_person_per_group, limited_number_of_seats_per_ride, limited_number_of_turns_per_ride, 1);
This is what I have so far. However, I have an idea I can't manage to put in place. Since the rules state that "that people like the roller coaster so much that as soon as they have finished a ride, they cannot help but go back for another one". I want to save the position of the loop at the moment it ends and restart the loop on that exact same position. Avoiding me to push and shift the element to the last positions of the array.
Can someone please give me a hint on how to proceed ?
Thank you very much !
Ryan
I have updated little of your logic.
For continuously looping over P I have used increment index position_i as position_i = (position_i + 1) % P.length;.
There is no need for inner for (var i = position_i; i < P.length; i++){. Just updated while(){...}.
var limited_number_of_seats_per_ride = 3, //L
limited_number_of_turns_per_ride = 3, //C
limited_number_of_groups_in_queue = 4, //N
number_of_person_per_group = [3, 1, 1, 2]; //P
function earning_per_day(P, L, C, price) {
/**
*
* #P {array} number of person per group.
* #L {int} limited number of seats per ride.
* #C {int} limited number of times the ride goes per day.
* #price {int} price per person per ride.
*
* #daily_earning {int} estimated daily earnings.
*/
var daily_earning = 0;
var position_i = 0;
console.log('---daily_earning : ' + daily_earning + '---');
// calculates sum of the earning for each ride per day
for (var j = 0; j < C; j++) {
console.log('---Ride ' + (j + 1) + '---');
var total_per_ride = 0;
// calculates the number of person on each ride
// for (var i = position_i; i < P.length; i++){
while ((total_per_ride + P[position_i]) <= L) {
total_per_ride += P[position_i];
position_i = (position_i + 1) % P.length;
}
console.log('total_per_ride = ' + total_per_ride);
console.log('New Start position_i = ' + position_i);
// }
daily_earning += total_per_ride;
console.log('daily_earning ' + daily_earning);
}
}
// calling
earning_per_day(number_of_person_per_group, limited_number_of_seats_per_ride, limited_number_of_turns_per_ride, 1);
I would like to randomize three arrays for fonts, font size, font weight.
I then need to display the results of the three arrays in a div, with a class name of randomFont.
So each time I use the class randomFont, it will return a random font/size/weight.
Any ideas on how I would go about doing this?
Let's say I have 3 variables in each array.
array 1 (fonts) > font 1, font 2, font 3
array 2 (font weight) > bold, light, 100
array 3 (font-size) > 12px, 24px, 100px
Then I want an an array to randomly choose one from each and display the output in a div>class called randomFont.
How would I do this?
Don't really need jQuery but this should do it, since you didn't supply any example code I've had to make it up but this should get you on your way.
var item = items[Math.floor(Math.random() * items.length)];
do this for each array.
You can see one approach at http://jsfiddle.net/CrossEye/bwsvy/
var fonts = ['Arial', 'Helvetica', 'Georgia', 'Tahoma', 'Verdana'];
var weights = ['normal', 'bold', 'lighter'];
var sizes = ['16px', '20px', '24px', '36px', '40px'];
var choose = function(arr) {
return arr[Math.floor(Math.random() * arr.length)];
};
// ...
var text = choose(sizes) + ' ' + choose(weights) + ' ' + choose(fonts);
output.innerHTML = '<div class="randomFont">' + text + '</div>';
// e.g. '24px bold Tahoma'
It's not clear what you mean by randomizing the arrays. If you have a fixed list of values and you want to rearrange them in place, then you want a shuffle functions, something like this:
var shuffle = function(arr) {
for (var i = arr.length; i--;) {
var j = Math.floor(Math.random() * (i + 1));
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
return arr;
}
That might be a partial answer to what you're looking for, but it's really not clear to me what you're after overall.