Home > front end >  JavaScript: stop a function when another one is active
JavaScript: stop a function when another one is active

Time:09-19

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}`;
  }
});
  • Related