Reputation: 91
I have a set of grid boxes
that when i switch color pallet
to a particular color, on mouse hover
it should change to that color and when i click the rgb button
the random color should override the color pallet that was first initialized.
But rbg button is displaying null
because its outside of drawGrid()
function
So the issue I am having is how to make both work at a different interval, whenever rbg button
is clicked it should override the color pallet
and vice versa.
function drawGrid(container, col, row) {
const box = document.createElement('div');
box.className = 'box';
box.id = `box${col}${row}`;
// Wehn color pallet is clicked mouseenter radom colors and it should ignore rbg button
const bgColor = document.querySelector('#bg-color');
box.addEventListener('mouseenter', () => {
box.style.backgroundColor = bgColor.value;
});
container.appendChild(box);
return (box);
}
function createBox(container) {
const grid = document.createElement('div');
grid.className = 'grid';
for(let i = 0; i < 6; i++) {
for(let j = 0; j < 5; j++) {
drawGrid(grid, i, j);
}
}
container.appendChild(grid);
}
function startupGrid() {
const game = document.querySelector('#game');
createBox(game)
}
startupGrid()
// Wehn rbg button is clicked mouseenter random colors and it should ignore color pallet
const rgb = document.querySelector('#rgb');
rgb.addEventListener('mouseenter', () => {
let r = Math.floor(Math.random() * 256);
let g = Math.floor(Math.random() * 256);
let b = Math.floor(Math.random() * 256);
let switchToRgb = `rgb ${r},${g},${b}`;
box.style.backgroundColor = switchToRgb;
})
body {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.main {
display: flex;
justify-content: center;
align-items: center;
place-items: center;
gap: 2rem;
margin: 5rem;
}
.controls {
display: grid;
gap: 1rem;
}
button {
padding: 5px 15px;
}
#game {
display: grid;
place-items: center;
}
.box {
width: 40px;
height: 30px;
border: 1px solid;
}
.grid {
display: grid;
grid-template-columns: repeat(6, auto);
grid-template-rows: repeat(5, auto);
box-sizing: border-box;
gap: 1px;
background: rgb(255, 255, 255)
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Grid</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="main">
<div class="controls">
<input type="color" id="bg-color">
<button id="rgb">RBG</button>
</div>
<div id="game"></div>
</div>
<script src="script.js"></script>
</body>
</html>
whereas if i add box
to the addEventlistener inside drawGrid()
function instead or rgb
it works, but then the color pallet
will stop working.
box.addEventListener('mouseenter', () => {
let r = Math.floor(Math.random() * 256);
let g = Math.floor(Math.random() * 256);
let b = Math.floor(Math.random() * 256);
let switchToRgb = `rgb ${r},${g},${b}`;
box.style.backgroundColor = switchToRgb;
})
Upvotes: 2
Views: 77
Reputation: 13059
The first issue is the format of the color string you want to set the input as, it needs to be the right format #RRGGBB
Input color value docs
let switchToRgb = `#${r.toString(16)}${g.toString(16)}${b.toString(16)}`;
See update below about properly creating this colour string
this will create the string in the right format by converting each decimal value to hexadecimal and formatting the string with a leading #
.
That's right box
doesn't exist at that point, you will have to get it inside the event listener. You should also set the input's value as this will change the rendered colours in the grid.
document.getElementById('bg-color').value = switchToRgb;
It strikes me as a bit weird that you're using mouseenter
event on a button. Why don't you use click
like most people, this will prevent accidental changes to the colour - FIXED
UPDATE - OP wants to use either a random colour each time the background color is set or use the value from color picker
You will need to keep track of whether to use a random color or use the color picked value.
let useRandomColor = false;
We'll default this to false but update it when either a specific colour is picked or the random colour button is clicked.
document.getElementById('rgb')
.addEventListener('click', () => {
useRandomColor = true;
});
const colorPicker = document.getElementById('bg-color');
colorPicker.addEventListener('change', () => {
useRandomColor = false;
});
Then we just need to use this value to figure out whether the picked colour is used or whether to use a random value
We also need to make sure we do this for each box
// get all the boxes
const boxes = document.querySelectorAll('.box');
for (let box of boxes) {
// add an event listener to each box
box.addEventListener('mouseenter', (e) => {
// set default value as the current value of the colour picker
let color = colorPicker.value;
// Override this with a random colour if needed
if (useRandomColor){
let r = Math.floor(Math.random() * 256);
let g = Math.floor(Math.random() * 256);
let b = Math.floor(Math.random() * 256);
color = `#${r.toString(16).padStart(2, '0'}${g.toString(16)}${b.toString(16)}`;
}
// Set the background colour of the hovered box
e.target.style.backgroundColor = color;
});
};
UPDATE - Use padded hex values
As @enhzflep pointed out, the colour value needs to be exactly either 3 or 6 hex digits, so we need to ensure the generated colour has exactly 6 hex digits.
const getColourString = (r, g, b) => {
return '#' + [r, g, b].map(x => x.toString(16).padStart(2, '0')).join('');
};
This will take our rgb colour components and make sure the value is the correct format.
We will then use this in setting the box background colour
e.target.style.backgroundColor = color;
let useRandomColor = false;
function drawGrid(container, col, row) {
const box = document.createElement('div');
box.className = 'box';
box.id = `box${col}${row}`;
container.appendChild(box);
return (box);
}
function createBox(container) {
const grid = document.createElement('div');
grid.className = 'grid';
for(let i = 0; i < 6; i++) {
for(let j = 0; j < 5; j++) {
drawGrid(grid, i, j);
}
}
container.appendChild(grid);
}
function startupGrid() {
const game = document.querySelector('#game');
createBox(game)
}
startupGrid()
// When rgb button is clicked mouseenter random colors and it should ignore color pallet
document.getElementById('rgb')
.addEventListener('click', () => {
useRandomColor = true;
});
const colorPicker = document.getElementById('bg-color');
colorPicker.addEventListener('change', () => {
useRandomColor = false;
})
// Wehn color pallet is clicked mouseenter radom colors and it should ignore rbg button
const boxes = document.querySelectorAll('.box');
for (let box of boxes) {
box.addEventListener('mouseenter', (e) => {
let color = colorPicker.value;
if (useRandomColor){
let r = Math.floor(Math.random() * 256);
let g = Math.floor(Math.random() * 256);
let b = Math.floor(Math.random() * 256);
color = getColourString(r, g, b);
}
e.target.style.backgroundColor = color;
});
};
const getColourString = (r, g, b) => {
return '#' + [r, g, b].map(x => x.toString(16).padStart(2, '0')).join('');
};
body {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.main {
display: flex;
justify-content: center;
align-items: center;
place-items: center;
gap: 2rem;
margin: 5rem;
}
.controls {
display: grid;
gap: 1rem;
}
button {
padding: 5px 15px;
}
#game {
display: grid;
place-items: center;
}
.box {
width: 40px;
height: 30px;
border: 1px solid;
}
.grid {
display: grid;
grid-template-columns: repeat(6, auto);
grid-template-rows: repeat(5, auto);
box-sizing: border-box;
gap: 1px;
background: rgb(255, 255, 255)
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Grid</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="main">
<div class="controls">
<input type="color" id="bg-color">
<button id="rgb">Random Colour</button>
</div>
<div id="game"></div>
</div>
<script src="script.js"></script>
</body>
</html>
Upvotes: 2