I have an Array like this:
var colors = {
1: '#FFFF00',
2: '#FF0000',
3: '#80FF00',
4: '#00FFFF',
5: '#FF00FF'
};
And Javascript like this:
var color = Math.floor(Math.random()*5)+1;
if(color == document.getElementById('awards').style.borderColor) {
var color = Math.floor(Math.random()*5)+1;
}
else {
document.getElementById('awards').style.borderColor = color;
}
But my Javascript isn't working.
You are generating an index, but not subscripting the array.
jsFiddle.
Also, to nitpick, {} creates an object with properties, technically not an Array (though an Array is an object). [] is the literal notation for an Array in JavaScript.
Update
Here is maybe how I'd have written it, if that helps...
var getRandomColor = function() {
var colors = [
'#FFFF00',
'#FF0000',
'#80FF00',
'#00FFFF',
'#FF00FF'
];
return colors[Math.floor(Math.random() * colors.length) + 1];
}
var color = getRandomColor(),
element = document.getElementById('awards'),
borderColor = element.style.borderColor;
if (color == borderColor) {
color = getRandomColor();
}
else {
element.style.borderColor = color;
}
jsFiddle.
You are not really getting the random color, just getting the random number in a range, you'll need to change your code to this:
var color = colors[(Math.floor(Math.random() * 5) + 1).toString()];
if(color == document.getElementById('awards').style.borderColor) {
var color = colors[(Math.floor(Math.random() * 5) + 1).toString()];
}
else {
document.getElementById('awards').style.borderColor = color;
}
If you want to write dynamic CSS and write some code and logic inside, I recommend to take a look at http://www.dotlesscss.org/
I know it will take time to learn, but I proffered to mention about it, may be it help someone.
Related
the title changes color randomly when clicked but it repeates the same color often (I don't want it to repeat the same color in the array twice in a row). I tried to fix this with an if statement but im not sure why it didn't work.
var title = document.querySelector(".title");
function changeColor() {
let newArray = ["DarkSalmon", "LightSalmon", "Crimson", "Red",
"DeepPink", "YellowGreen", "GhostWhite"
];
let random = Math.floor(Math.random() *
Math.floor(newArray.length - 1));
console.log(random);
if (title.style.color !== newArray[random]) {
title.style.color = newArray[random];
}
}
title.addEventListener("click", changeColor);
<h1 class='title'>Berserk</h1>
If don't want colors to get repeated in a row, you could just add an else statement to your if statement.
I found the error! It's in the capitalization of your color names... Change them to all lowercase and it will magically
var title = document.querySelector(".title");
function changeColor() {
let newArray = ["darksalmon", "lightsalmon", "crimson", "red", "deeppink", "yellowgreen", "ghostwhite"];
let random = Math.floor(Math.random() * Math.floor(newArray.length - 1));
if (title.style.color != newArray[random]) {
title.style.color = newArray[random];
console.log(title.style.color);
} else {
changeColor();
}
}
title.addEventListener("click", changeColor);
<h1 class='title'>Berserk</h1>
This will let each color be selected exactly once. Once all colors have been used, the list is refreshed so all colors can be randomly selected again, and so on.
// Identifies header element & defines initial colors array and colors array
const header = document.getElementsByClassName("title")[0];
const initialColors = ["DarkSalmon", "LightSalmon", "Crimson", "Red", "DeepPink", "YellowGreen"];
let colors = [];
// Calls `changeColor` when the header is clicked
header.addEventListener("click", changeColor);
// Defines the `changeColor` function
function changeColor(){
// Remembers the most recent color (formatted as lower-case)
let previousColor = header.style.color.toLowerCase();
// Makes all colors available whenever no colors are left (including on first click)
if(colors.length === 0){
// Copies the `initialColors` array, and returns the copy
// (See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)
colors = initialColors.slice();
}
// Cuts a random color out of the colors array
let newColor = removeRandFrom(colors);
// If removed color happens to match previous color, forces an additional change
// (Can only ever happen immediately after the `colors` array has been replenished)
if(newColor === previousColor){
newColor = removeRandFrom(colors);
}
// Sets text color to whichever color was just randomly removed
header.style.color = newColor;
}
// Defines the `removeRandFrom` helper function
function removeRandFrom(arr){
// Gets a psuedo-random number
const index = Math.floor(Math.random() * arr.length);
// Removes and returns the element at the randomly selected index
// (See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)
return arr.splice(index, 1);
}
<h1 class='title'>Berserk</h1>
References:
MDN - slice
MDN - splice
The problem is that when the color would repeat and your if statement prevents that from happening, nothing else happens, either. So the effect is the same as a repeating color.
Instead of the if statement, you could use a ẁhile loop to randomly select new colors until you have one that is different from the current.
let random;
do {
random = Math.floor(Math.random() * Math.floor(newArray.length - 1));
} while (title.style.color === newArray[random]);
title.style.color = newArray[random];
I am creating spots on the canvas that change colors randomly. How do i access the last spot in the array and return the color? the color of the L should change to the color of the most recent spot added in order to know I am doing it right.
function lastColor() {
var lastColor = color(255);
var result = spots.map(a => a.color); {
}
return lastColor;
}
function drawLastColor() {
fill(lastColor());
textSize(50);
text("L", 10, 50);
}
var colorArray = [...lots of colors]
var lastColor = colorArray[colorArray.length - 1]
This question already has answers here:
Extract list of supported HTML or X11 colour names and their RGB values using javascript
(2 answers)
Closed last year.
Is there a way to programmatically generate a list of all named CSS colors supported by the browser via JavaScript? (.e.g. Red, Green, AliceBlue etc.)
Note: I'm not asking for a pre-compiled list, I'm looking for something more akin to document.body.style, which returns an object with all css properties supported by the browser.
I guess the closed you can get is starting from a pre-compiled color name list and check if the browser supports the color. You can assign the color with
div.stlye.backgroundColor = '';
div.style.backgroundColor = potentialColor;
and retrieve the actual color information with
var actualColorString = window.getComputedStyle(div).background;
If the assigned color is not valid (or black), the color string starts with
rgba(0, 0, 0, 0)
Otherwise it is a known css color name.
Here is some jsfiddle to demonstrate the color check:
https://jsfiddle.net/tc8f5pgy/4/
I used this method to create a Color enum for my project:
https://github.com/stefaneidelloth/treezjs/blob/master/src/components/color/color.js
And here is part of the code as a backup for the jsfiddle:
<div id='color-element'></div>
//source of color names: https://simple.wikipedia.org/wiki/List_of_colors
const colorNames = [
'Amaranth',
//...
];
//another source of color names: https://gist.github.com/bobspace/2712980
const cssColorNames = [
"AliceBlue",
"AntiqueWhite",
//...
];
//another source of color names: https://chir.ag/projects/ntc/ntc.js
var extendedColors = [
["000000", "Black"],
["000080", "Navy Blue"],
//...
];
function camelize(str) { //source: https://stackoverflow.com
/questions/2970525/converting-any-string-into-camel-case
var camelString= str.replace(/(?:^\w|[A-Z]|\b\w)/g, function(word, index) {
return index === 0 ? word.toLowerCase() : word.toUpperCase();
}).replace(/\s+/g, '');
return camelString.replace(/\//g,'').replace(/-/g,'').replace(/'/g,'');
}
function rgba2hex(orig) { //source: https://stackoverflow.com/questions/49974145/how-to-convert-rgba-to-hex-color-code-using-javascript
var a, isPercent,
rgb = orig.replace(/\s/g, '').match(/^rgba?\((\d+),(\d+),(\d+),?([^,\s)]+)?/i),
alpha = (rgb && rgb[4] || "").trim(),
hex = rgb ?
(rgb[1] | 1 << 8).toString(16).slice(1) +
(rgb[2] | 1 << 8).toString(16).slice(1) +
(rgb[3] | 1 << 8).toString(16).slice(1) : orig;
if (alpha !== "") {
a = alpha;
} else {
a = 01;
}
// multiply before convert to HEX
a = ((a * 255) | 1 << 8).toString(16).slice(1)
hex = hex + a;
return hex;
}
function handleActualColor(name, rgbaColorString){
var hexColorString = rgba2hex(rgbaColorString);
var output = "Color." + name + " = new Color('"+ name +"','#"+ hexColorString + "');"
console.log(output);
}
var potentialColorSet = new Set();
for(var colorName of colorNames){
potentialColorSet.add(camelize(colorName));
}
for(var colorName of cssColorNames){
potentialColorSet.add(camelize(colorName));
}
for(var entry of extendedColors){
var colorName = entry[1];
potentialColorSet.add(camelize(colorName));
}
var potentialColors = Array.from(potentialColorSet).sort();
var div = document.getElementById('color-element');
for(var potentialColor of potentialColors){
div.style.backgroundColor = '';
div.style.backgroundColor = potentialColor;
var actualColorString = window.getComputedStyle(div).background;
var endIndex = actualColorString.indexOf(')');
var rgbaColorString = actualColorString.substring(0, endIndex+1);
if(rgbaColorString !== 'rgba(0, 0, 0, 0)'){
handleActualColor(potentialColor, rgbaColorString);
if(potentialColor == 'screaminGreen'){
throw new Error('foo');
}
}
if(potentialColor.toLowerCase() === 'black'){
handleActualColor(potentialColor, rgbaColorString);
}
}
I came up with this list of colors you might use for TEXT or Backgrounds
Just call them by names i.e: <div class="black_bg silver_text"></div>
.black_text{color:#000000;}.black_bg{background-color:#000000;}
.silver_text{color:#c0c0c0;}.silver_bg{background-color:#c0c0c0;}
.gray_text{color:#808080;}.gray_bg{background-color:#808080;}
.white_text{color:#ffffff;}.white_bg{background-color:#ffffff;}
.maroon_text{color:#800000;}.maroon_bg{background-color:#800000;}
.red_text{color:#ff0000;}.red_bg{background-color:#ff0000;}
.purple_text{color:#800080;}.purple_bg{background-color:#800080;}
.fuchsia_text{color:#ff00ff;}.fuchsia_bg{background-color:#ff00ff;}
.green_text{color:#008000;}.green_bg{background-color:#008000;}
.lime_text{color:#00ff00;}.lime_bg{background-color:#00ff00;}
.olive_text{color:#808000;}.olive_bg{background-color:#808000;}
.yellow_text{color:#ffff00;}.yellow_bg{background-color:#ffff00;}
.navy_text{color:#000080;}.navy_bg{background-color:#000080;}
.blue_text{color:#0000ff;}.blue_bg{background-color:#0000ff;}
.teal_text{color:#008080;}.teal_bg{background-color:#008080;}
.aqua_text{color:#00ffff;}.aqua_bg{background-color:#00ffff;}
.orange_text{color:#ffa500;}.orange_bg{background-color:#ffa500;}
.aliceblue_text{color:#f0f8ff;}.aliceblue_bg{background-color:#f0f8ff;}
.antiquewhite_text{color:#faebd7;}.antiquewhite_bg{background-color:#faebd7;}
.aquamarine_text{color:#7fffd4;}.aquamarine_bg{background-color:#7fffd4;}
.azure_text{color:#f0ffff;}.azure_bg{background-color:#f0ffff;}
.beige_text{color:#f5f5dc;}.beige_bg{background-color:#f5f5dc;}
.bisque_text{color:#ffe4c4;}.bisque_bg{background-color:#ffe4c4;}
.blanchedalmond_text{color:#ffebcd;}.blanchedalmond_bg{background-color:#ffebcd;}
.blueviolet_text{color:#8a2be2;}.blueviolet_bg{background-color:#8a2be2;}
.brown_text{color:#a52a2a;}.brown_bg{background-color:#a52a2a;}
.burlywood_text{color:#deb887;}.burlywood_bg{background-color:#deb887;}
.cadetblue_text{color:#5f9ea0;}.cadetblue_bg{background-color:#5f9ea0;}
.chartreuse_text{color:#7fff00;}.chartreuse_bg{background-color:#7fff00;}
.chocolate_text{color:#d2691e;}.chocolate_bg{background-color:#d2691e;}
.coral_text{color:#ff7f50;}.coral_bg{background-color:#ff7f50;}
.cornflowerblue_text{color:#6495ed;}.cornflowerblue_bg{background-color:#6495ed;}
.cornsilk_text{color:#fff8dc;}.cornsilk_bg{background-color:#fff8dc;}
.crimson_text{color:#dc143c;}.crimson_bg{background-color:#dc143c;}
.darkblue_text{color:#00008b;}.darkblue_bg{background-color:#00008b;}
.darkcyan_text{color:#008b8b;}.darkcyan_bg{background-color:#008b8b;}
.darkgoldenrod_text{color:#b8860b;}.darkgoldenrod_bg{background-color:#b8860b;}
.darkgray_text{color:#a9a9a9;}.darkgray_bg{background-color:#a9a9a9;}
.darkgreen_text{color:#006400;}.darkgreen_bg{background-color:#006400;}
.darkgrey_text{color:#a9a9a9;}.darkgrey_bg{background-color:#a9a9a9;}
.darkkhaki_text{color:#bdb76b;}.darkkhaki_bg{background-color:#bdb76b;}
.darkmagenta_text{color:#8b008b;}.darkmagenta_bg{background-color:#8b008b;}
.darkolivegreen_text{color:#556b2f;}.darkolivegreen_bg{background-color:#556b2f;}
.darkorange_text{color:#ff8c00;}.darkorange_bg{background-color:#ff8c00;}
.darkorchid_text{color:#9932cc;}.darkorchid_bg{background-color:#9932cc;}
.darkred_text{color:#8b0000;}.darkred_bg{background-color:#8b0000;}
.darksalmon_text{color:#e9967a;}.darksalmon_bg{background-color:#e9967a;}
.darkseagreen_text{color:#8fbc8f;}.darkseagreen_bg{background-color:#8fbc8f;}
.darkslateblue_text{color:#483d8b;}.darkslateblue_bg{background-color:#483d8b;}
.darkslategray_text{color:#2f4f4f;}.darkslategray_bg{background-color:#2f4f4f;}
.darkslategrey_text{color:#2f4f4f;}.darkslategrey_bg{background-color:#2f4f4f;}
.darkturquoise_text{color:#00ced1;}.darkturquoise_bg{background-color:#00ced1;}
.darkviolet_text{color:#9400d3;}.darkviolet_bg{background-color:#9400d3;}
.deeppink_text{color:#ff1493;}.deeppink_bg{background-color:#ff1493;}
.deepskyblue_text{color:#00bfff;}.deepskyblue_bg{background-color:#00bfff;}
.dimgray_text{color:#696969;}.dimgray_bg{background-color:#696969;}
.dimgrey_text{color:#696969;}.dimgrey_bg{background-color:#696969;}
.dodgerblue_text{color:#1e90ff;}.dodgerblue_bg{background-color:#1e90ff;}
.firebrick_text{color:#b22222;}.firebrick_bg{background-color:#b22222;}
.floralwhite_text{color:#fffaf0;}.floralwhite_bg{background-color:#fffaf0;}
.forestgreen_text{color:#228b22;}.forestgreen_bg{background-color:#228b22;}
.gainsboro_text{color:#dcdcdc;}.gainsboro_bg{background-color:#dcdcdc;}
.ghostwhite_text{color:#f8f8ff;}.ghostwhite_bg{background-color:#f8f8ff;}
.gold_text{color:#ffd700;}.gold_bg{background-color:#ffd700;}
.goldenrod_text{color:#daa520;}.goldenrod_bg{background-color:#daa520;}
.greenyellow_text{color:#adff2f;}.greenyellow_bg{background-color:#adff2f;}
.grey_text{color:#808080;}.grey_bg{background-color:#808080;}
.honeydew_text{color:#f0fff0;}.honeydew_bg{background-color:#f0fff0;}
.hotpink_text{color:#ff69b4;}.hotpink_bg{background-color:#ff69b4;}
.indianred_text{color:#cd5c5c;}.indianred_bg{background-color:#cd5c5c;}
.indigo_text{color:#4b0082;}.indigo_bg{background-color:#4b0082;}
.ivory_text{color:#fffff0;}.ivory_bg{background-color:#fffff0;}
.khaki_text{color:#f0e68c;}.khaki_bg{background-color:#f0e68c;}
.lavender_text{color:#e6e6fa;}.lavender_bg{background-color:#e6e6fa;}
.lavenderblush_text{color:#fff0f5;}.lavenderblush_bg{background-color:#fff0f5;}
.lawngreen_text{color:#7cfc00;}.lawngreen_bg{background-color:#7cfc00;}
.lemonchiffon_text{color:#fffacd;}.lemonchiffon_bg{background-color:#fffacd;}
.lightblue_text{color:#add8e6;}.lightblue_bg{background-color:#add8e6;}
.lightcoral_text{color:#f08080;}.lightcoral_bg{background-color:#f08080;}
.lightcyan_text{color:#e0ffff;}.lightcyan_bg{background-color:#e0ffff;}
I have the following implementation, it works and functional. I am checking if fname properties are same in the following javascript object, then I assign the same color for these paired objects.
Here is one javascript object sample:
{"value": 10,"series": 1,"category": "LG","fname": "","valueColor": ""},
However, I would like to use more distinguished colors, rather than very similar color, for example in the given fiddle, colors are almost all in green spectrum. Also I do not want to give any color value where value property equals to 0
Here is the core implementation
function colorSpectrum(N) {
var colorMap = [], inc = 50, start = 1000;
for (i = start; i < start+N*inc; i+=inc) {
var num = ((4095 * i) >>> 0).toString(16);
while (num.length < 3) {
num = "0" + num;
}
colorMap.push("#" + num);
}
return colorMap;
}
function process(data){
var map = {}, colorMap = colorSpectrum(data.length);
data.forEach(function(item, index){
if(!map.hasOwnProperty(item.fname)){
map[item.fname] = colorMap[index];
}
data[index].valueColor = map[item.fname];
});
return data;
}
FIDDLE
Try picking random colors
function colorSpectrum(N) {
var colorMap = [];
for (i = 0; i < N; i+=1) {
var color = getRndColor()
colorMap.push("#"+color);
}
return colorMap;
}
function getRndColor() {
var n = Math.floor(Math.random()*255*255*255);
var hex = Number(n).toString(16);
while(hex.length < 6) {
hex = "0"+hex;
}
return hex;
}
If you want a full range of colors from black to white, you need to change this part:
var colorMap = [], inc = 50, start = 1000;
for (i = start; i < start+N*inc; i+=inc) {
You see, the loop starts from 1000, which is the color #3e8, already green. The scale should go from 0 to 4095 (for 3-character values like #007, #abc, etc...), with having the increment based on the amount of data.
However, I'd suggest getting at least a little bit of the control by having all RGB components generated separately instead of the full HEX value right away.
I have a grid in my page that I want to populate via javascript with 200 elements. The actual code that populate the .grid element is the following:
$(function () {
var $gd = $(".grid");
var blocks="";
for(i=0; i < 200; i++){
blocks += '<div class="block"></div>';
}
$gd.append(blocks);
});
What I'm trying to do now is assign to each element created a random picked color from a list. Lets say red, blue, yellow, green (unexpected eh?). I'd like the values to be the most random possible, and also to avoid the same color to be picked again twice consequentially (just to be clear, it's ok something like red-blue-red-green-blue and so on, NOT red-red-green-yellow).
Maybe this can help in the randomize process, Fisher–Yates Shuffle, but I don't how to implement the non-twice adjacent rule stated above (if it is possible to apply at all).
What would be the best way to achieve this result? I'm also wondering if I could apply a gradient to each .block instead of a flat hex color; I guess the better route for this would be to assign a random class to each element mapped in CSS for the gradient and so on..
If the above script can be optimized performance-wise, I apreciate any suggestions!
Additional info:
I'm using jQuery
The grid is composed with 20 elements per row, for 10 rows
The colors should be 4, but can be raised to 5-7 adding some neutral grey tones if it can help
Here is a pen to experiment with http://codepen.io/Gruber/pen/lDxBw/
Bonus feature request: as stated above I'd like to avoide duplicate adjacent colors. Is it possible to avoid this also "above and below"? I guess its very hard if not impossible to totally avoid this, but well if anyone can find a solution it would be awesome!
Something like this, where the "nope" marked element is prevented, while the "yep" diagonal marked are allowed:
$(function () {
var colors = ["red","blue","green","yellow"];
var $gd = $(".grid");
var previousColor;
var blocks="";
for(i=0; i < 200; i++){
var color = "";
while(color === previousColor) {
color= colors [Math.floor(Math.random()*colors .length)];
}
blocks += '<div class="block" style="color:' + color + '"></div>';
previousColor = color;
}
$gd.append(blocks);
});
First, I'd use classes for the colors:
CSS:
.red { background-color: red; }
.blue { background-color: blue; }
.green { background-color: green; }
.yellow { background-color: yellow; }
And then here's the javascript:
$(document).ready(function() {
var colors = ["red","blue","green","yellow"];
var $gd = $(".grid");
var previousColor;
var previousRow;
var rowSize = 10;
while(rowSize--) previousRow.push("none");
var blocks = "";
for(i=0; i < 200; i++){
var color = colors [Math.floor(Math.random()*colors .length)];
while((color == previousColor) || (color == previousRow[i%rowSize])) {
color = colors [Math.floor(Math.random()*colors .length)];
}
blocks += '<div class="block ' + color + '"></div>';
previousColor = color;
previousRow[i%rowSize] = color;
}
$gd.append(blocks);
});
I started off with something similar to MikeB's code but added a row element so we know what is above your current block.
The first thing I'd like to introduce is a filtered indexing function.
Given an array:
var options = ['red', 'green', 'blue', 'purple', 'yellow']; // never less than 3!
And a filter:
function filterFunc(val) {
var taken = { 'red': 1, 'blue': 1 };
return taken[val] ? 0 : 1;
}
We can take the nth item from the values permitted (==1) by the filter (not a quick way to do it, but until there is a performance constraint...):
// filteredIndex returns nth (0-index) element satisfying filterFunc
// returns undefined if insufficient options
function filteredIndex(options, filterFunc, n) {
var i=-1, j=0;
for(;j<options.length && i<n; ++j) {
i += filterFunc(options[j]);
if(i==n)
break;
}
return options[j];
}
So now we can pick up a value with index 2 in the filtered list. If we don't have enough options to do so, we should get undefined.
If you are populating the colours from, say, the top left corner, you can use as few as 3 colours, as you are only constrained by the cells above and to the left.
To pick randomly, we need to set up the filter. We can do that from a list of known values thus:
function genFilterFunc(takenValues) {
var takenLookup = {};
for(var i=0; i < takenValues.length; ++i) {
takenLookup[takenValues[i]] = 1;
}
var filterFunc = function(val) {
return takenLookup[val] ? 0 : 1;
};
return filterFunc;
}
We can choose a random colour, then, for a cell in a grid[rows][cols]:
function randomColourNotUpOrLeft(grid, row, col, options, ignoreColour) {
var takenlist = [];
if(row > 0 && grid[row-1][col] != ignoreColour) {
takenlist.push(grid[row-1][col]);
}
if(col > 0 && grid[row][col-1] != ignoreColour) {
takenlist.push(grid[row][col-1]);
}
var filt = genFilterFunc(takenlist);
var randomIndex = Math.floor(Math.random()*(options.length-takenlist.length));
var randomColour = filteredIndex(options, filt, randomIndex);
return randomColour;
}
Note here that the random index used depends on how many colours have been filtered out; if there are 4 left we can have 0-3, but if only 2 are left it must be 0-1, etc. When the adjacent cells are the same colour and/or we are near the boundary, there is less constraint about which colour is chosen. Finally fill in a grid:
function fillGridSpeckled(grid, options, nullColour) {
for(var row=0; row<grid.length; ++row) {
for(var col=0; col<grid[row].length; ++col) {
grid[row][col] = randomColourNotUpOrLeft(grid,row,col,options,nullColour);
}
}
}
I've put it all in this jsbin, along with a few bits to demo the code working.