I am working on a sketchpad and basically I would like to allow the user to switch between hover-draw (hovering over divs will change their color, it's the default mode) and click-draw (you have to actually click the divs to color them).
I added a button which change the value of clickOn/hoverOn and I want the functions to work only if their associated variables are "on".
However when I click the button and hoverOn value becomes false, the hover function still executes and the divs get colored anyway.
Can anyone point me in the right direction?
EDIT: full code:
const container = document.querySelector('.container');
const newSize = document.querySelector('#grid-resize');
const clearBtn = document.querySelector('#clear');
const resetBtn = document.querySelector('#reset');
const randomBtn = document.querySelector('#random-color');
const modeBtn = document.querySelector('#change-mode');
const eraser = document.querySelector('#eraser');
let size = 16;
let hoverOn = true;
let clickOn = false;
let color = '#72A0C1';
newSize.addEventListener('input', changeSize);
clearBtn.addEventListener('click', clearGrid);
resetBtn.addEventListener('click', resetGrid);
modeBtn.addEventListener('click', changeMode);
randomBtn.addEventListener('click', drawRainbow);
eraser.addEventListener('click', () => {
if (color == 'white') {
color = '#72A0C1';
eraser.style.border = 'none';
} else {
color = 'white';
eraser.style.border = '2px dotted #FFC0CB';
}
});
let isMousedown = false;
container.addEventListener('mousedown', ()=>{isMousedown = true;});
container.addEventListener('mouseup', ()=>{isMousedown = false;});
function changeSize() {
const cells = document.querySelectorAll('.cell');
cells.forEach(cell => {
cell.remove();
});
size = newSize.value;
generateDiv(size);
}
function clearGrid() {
const cells = document.querySelectorAll('.cell');
cells.forEach(cell => {
cell.style.backgroundColor = 'white';
});
}
function resetGrid() {
const cells = document.querySelectorAll('.cell');
cells.forEach(cell => {
cell.remove();
});
size = 16;
newSize.value = size;
generateDiv();
}
function changeMode() {
if (hoverOn) {
hoverOn = false;
clickOn = true;
} else if (clickOn) {
clickOn = false;
hoverOn = true;
}
console.log (hoverOn, clickOn)
}
function setHoverMode() {
if (hoverOn == true) {
container.addEventListener('mouseover', function (e) {
e.target.style.background = `${color}`;
});
}
}
function setClickMode() {
if (clickOn == true) {
container.addEventListener('mousemove', (e) => {
if (isMousedown) {
e.target.style.backgroundColor = `${color}`;
}
});
container.addEventListener('mousemove', e => e.preventDefault());
}
}
function generateColor() {
let randomColor = '#';
let characters = 'ABCDEF0123456789';
for(let i=0; i < 6; i ) {
randomColor = characters.charAt(Math.floor(Math.random() * characters.length));
color = randomColor;
}
}
function drawRainbow() {
container.addEventListener('mousemove', ()=>{
generateColor();
});
}
function generateDiv() {
container.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
container.style.gridTemplateRows = `repeat(${size}, 1fr)`;
for (let i = 0; i < size * size; i ) {
let cell = document.createElement('div');
cell.classList.add('cell');
container.appendChild(cell);
}
}
generateDiv(size);
html, body {
margin: 0;
padding: 20px;
width: 100%;
height: 100%;
box-sizing: border-box;
text-align: center;
}
h1 {
margin-top: 0;
}
.content {
display: flex;
justify-content: center;
gap: 5em;
}
.content .settings {
display: flex;
flex-direction: column;
width: 15%;
}
.content .grid-resize {
text-align: start;
margin-bottom: 2em;
}
.content .buttons {
display: flex;
flex-wrap: wrap;
gap: 1.5em;
}
.content .buttons button {
border: none;
box-shadow: 1px 1px rgba(128, 128, 128, 0.41);
border-radius: 15px;
width: 70px;
height: 70px;
}
.content .buttons button:hover {
box-shadow: 2px 2px #176fae;
background-color: #72A0C1;
color: white;
transform: scale(1.2);
}
.content .buttons button:active {
box-shadow: none;
background-color: #72A0C1;
color: white;
transform: scale(1);
}
.content .buttons button .eraser-border {
border: 1px solid black;
}
.container {
display: grid;
width: 400px;
height: 400px;
}
.container .cell {
background-color: white;
border: 1px solid rgba(220, 220, 220, 0.3);
}
<body>
<div >
<h1>Draw something nice!</h1>
<div >
<div >
<div >
<label for="grid-resize">Change the grid size:</label>
<input type="range" id="grid-resize" min="4" max="100">
</div>
<div >
<button id="clear" title="Click here to clear the board">Clear All</button>
<button id="reset" title="Click here to go back to original settings - this will clear the board">Reset</button>
<button id="change-mode" title="Click here to change the mode">Draw Mode</button>
<button id="random-color" >Random Color</button>
<button id="black-shades" >Black Shades</button>
<button id="eraser" ><img src="images/rubber.svg">Eraser</button>
</div>
</div>
<div >
</div>
</div>
</div>
CodePudding user response:
You were close, just move mouseover/mousemove listeners outside of setHoverMode/setClickMode
functions and do your condition checks inside those event listeners like below
container.addEventListener("mouseover", function (e) {
if (hoverOn) {
e.target.style.background = `${color}`;
}
});
container.addEventListener("mousemove", (e) => {
if (clickOn && isMousedown) {
e.target.style.backgroundColor = `${color}`;
}
});