0

I am working on the etch-a-sketch project with The Odin Project and there's one thing I can't figure out. In the original project the grid elements will start to change colors once I hover over them but what I want to do is to only start the hovering function after I press the left mouse button.

Here is a working example of what I want to achieve.

const container = document.getElementById('container');
const reset = document.getElementById('reset');
const eraser = document.querySelector('#eraser');
const pencil = document.querySelector('#pencil');
const rainbow = document.querySelector('#rainbow');
const pickColor = document.querySelector('#color');
const shading = document.querySelector('#shading')
const gridSize = document.querySelector('#range');
let gridValue = document.querySelector('.grid-size');
let mode = '';

gridValue.textContent = `50x50`; // display default size of the grid


// create grid
function createGrid(size) {
  size = gridSize.value;
  container.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
  container.style.gridTemplateRows = `repeat(${size}, 1fr)`;
  for (let i = 0; i < size * size; i++) {
    const grid = document.createElement('div');
    grid.setAttribute('id', 'grid');
    container.appendChild(grid);
    grid.addEventListener('mouseover', changeColor);
  }
}
createGrid();


// change grid size depending on the user's choice
gridSize.addEventListener('input', function (e) {
  let currentSize = e.target.value;
  gridValue.textContent = `${currentSize}x${currentSize}`;
  resetGrid();
});


// change color
function changeColor(e) {
  if (mode === 'pencil') {
    e.target.classList.add('black');
    e.target.classList.remove('white');
    e.target.style.backgroundColor = null;
    e.target.style.opacity = null;
  } else if (mode === 'rainbow') {
    const green = Math.floor(Math.random() * 250);
    const blue = Math.floor(Math.random() * 250);
    const red = Math.floor(Math.random() * 250);
    e.target.style.backgroundColor = `rgb(${red}, ${green}, ${blue})`;
    e.target.style.opacity = null;
  } else if (mode === 'erase') {
    e.target.classList.add('white');
    e.target.style.backgroundColor = null;
    e.target.style.opacity = null;
  } else if (mode === 'pickColor') {
    e.target.style.backgroundColor = pickColor.value;
    e.target.style.opacity = null;
  } else if (mode === 'shading') {
    e.target.classList.remove('white');
    e.target.classList.add('black');
    e.target.style.opacity = Number(e.target.style.opacity) + 0.2;
  } else {
    e.target.classList.add('black')
  }
}


// reset grid
reset.addEventListener('click', () => resetGrid());
function resetGrid() {
  container.innerHTML = '';
  createGrid();
}


// erase
eraser.addEventListener('click', () => eraseMode());
function eraseMode() {
  mode = 'erase';
}


// pencil
pencil.addEventListener('click', () => pencilMode());
function pencilMode() {
  mode = 'pencil';
}


// rainbow 
rainbow.addEventListener('click', () => rainbowMode());
function rainbowMode() {
  mode = 'rainbow';
}


// pick a color
pickColor.addEventListener('click', () => pickColorMode());
function pickColorMode() {
  mode = 'pickColor';
}

// shading
shading.addEventListener('click', () => shadeMode());
function shadeMode() {
  mode = 'shading';
}
@import url('https://fonts.googleapis.com/css2?family=Inconsolata:wght@700;800&display=swap');

body {
  text-align: center;
  background-color: #4d56bd;
  font-family: 'Inconsolata', monospace;
  color: white;
}

h1 {
  font-weight: 800;
  font-size: 40px;
  text-shadow: 3px 3px #1d1b1e;
  color: #f4ce45
}

#container {
  width: 600px;
  height: 600px;
  border: 3px solid #1d1b1e;
  display: grid;
  margin: 20px auto;
  background-color: white;
  box-shadow: 5px 5px #303030;
}

#grid {
  border: none;
}

.black {
  background-color: black;
}

.white {
  background-color: white;
}

.button {
  font-family: inherit;
  padding: 10px;
  font-size: 1em;
  background-color: #303030;
  box-shadow: 2px 2px #1d1b1e;
  color: white;
  margin: 0 5px;
}

#reset {
  background-color: #f4ce45;
  color: black;
}

.button:hover,
#reset:hover {
  cursor: pointer;
  background-color: #e7455a;
}

.ownColor {
  margin: 10px;
}

.pickColor:hover {
  cursor: auto;
  background-color: #303030;
}

#color {
  cursor: pointer;
}

.slider {
  -webkit-appearance: none;
  width: 30%;
  height: 10px;
  border-radius: 5px;
  background: #1d1b1e;
  margin: 10px;
}

.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #f4ce45;
  cursor: pointer;
}

.slider::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #f4ce45;
  cursor: pointer;
}

.grid-size {
  font-size: 1.5rem;
  margin-top: 20px;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="styles.css">
  <title>Etch-a-Sketch</title>
</head>

<body>
  <h1>ETCH A SKETCH</h1>
  <button id="reset" class="button">Reset</button>
  <button id="pencil" class="button">Pencil</button>
  <button id="eraser" class="button">Eraser</button>
  <button id="rainbow" class="button">Rainbow</button>
  <button id="shading" class="button">Shading</button>
  <div class="ownColor">
    <button class="button pickColor">Choose your own color:
      <input type="color" id="color"></button>
  </div>
  <div class="grid-size"></div>
  <input type="range" id="range" min="5" max="100" class="slider">
  <div id="container"></div>

</body>
<script src="script.js"></script>

</html>
fallenech
  • 3
  • 1
  • Does this answer your question? [Javascript check Mouse clicked inside the Circle or Polygon](https://stackoverflow.com/questions/2212604/javascript-check-mouse-clicked-inside-the-circle-or-polygon) – ethry Jun 25 '22 at 21:15

1 Answers1

1

Well basically you can achieve this with a variable isMouseDown.

let isMouseDown;
document.addEventListener('mousedown', () => isMouseDown = true);
document.addEventListener('mouseup', () => isMouseDown = false);

then, use it where you need, for example:

// change color
function changeColor(e) {
  if(!isMouseDown) return;

  // ... rest of the code
}
ינון רחמים
  • 566
  • 1
  • 5
  • 12