someone
someone

Reputation: 703

how to reset color grid?

I am creating a simple etch-a-sketch game. currently on hover it colors in black. I am trying to use a button to reset the colors back to white. However, i can't get the button to function with an event listener, if i add an alert it displays the alert but nothing else. Please guide me and supply a documentation that I can reference as I want to learn and fixing it without explaining will be counterproductive at this point.

Thank you !

const containerGrid = document.getElementById("mainGrid");

function makeGrid(col) {
  for (let i = 0; i < col * col; i++) {
    const gridAdd = document.createElement("div");
    gridAdd.classList.add("box");
    gridAdd.textContent = "";

    containerGrid.appendChild(gridAdd);
  }
}

makeGrid(16); // make grid 16*16

const btnClear = document.getElementById("clear");
//mouseover event black - need to link to button (well done :)
const boxes = document.querySelectorAll('.box').forEach(item => {
  item.addEventListener('mouseover', event => {
    item.style.backgroundColor = "black";
  })
});

btnClear.addEventListener("click", () => {
  boxes.style.backgroundColor = "white";
});

const changeGrid = document.getElementById(".sizechange");


/*clearBtn.forEach.addEventListener("click", function () {
clearBtn.style.color ="white";
});
*/


/*const randomBtn = document.getElementById("randomgen").addEventListener('click',(e) => {
    console.log(this.classname)    
    console.log(e.currentTarget === this)
    }) */
//change color
#mainGrid {
  display: grid;
  justify-content: center;
  align-items: center;
  grid-template-columns: repeat(16, 1fr);
  grid-template-rows: auto;
  margin-left: 150px;
  width: 200px;
}

.box {
  color: black;
  border: 3px solid;
  height: 10px;
  width: 10px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Etch-a-Sketch</title>
  <link type="text/css" rel="stylesheet" href="styles.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>

<body>
  <div id="colorContainer">
    <input type="radio" id="blackchoice" value="color" name="black" class="defaultbtn">
    <label for="defaultcolor">black</label>
    <input type="radio" id="randomgen" class="hey">
    <label for="randomchoice">random</label>
  </div>

  <div id="changeGrid">
    <button id="clear">clear</button>
  </div>

  <div id="mainGrid"></div>

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

</html>

Upvotes: 1

Views: 561

Answers (2)

Roko C. Buljan
Roko C. Buljan

Reputation: 206151

  • Simplify your CSS
  • Use a SELECT element for your colors
  • Define the gridTemplateColumns in JS, not in CSS.
  • Use simpler functions
  • Use global variables to store the current grid size and color
  • Don't forget to clear your grid before changing the size
  • Assign the mouseenter Event on each cell on creation!
  • Add a boolean variable isPenDown for a better user experience!

const NewEL = (sel, prop) => Object.assign(document.createElement(sel), prop);

const EL_grid = document.querySelector("#grid");
const EL_clear = document.querySelector("#clear");

const EL_color = document.querySelector("[name=color]");
const EL_size = document.querySelector("[name=size]");

let size = parseInt(EL_size.value, 10);
let color = "black";
let isPenDown = false;

function makeGrid() {
  EL_grid.innerHTML = ""; // Clear current grid!
  for (let i = 0; i < size ** 2; i++) {
    EL_grid.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
    EL_grid.append(NewEL("div", {
      className: "box",
      onmousedown()  { isPenDown = true; paint(this); },
      onmouseup()    { isPenDown = false; },
      onmouseenter() { if (isPenDown) paint(this); },
    }));
  }
};

function paint(EL) {
  EL.style.backgroundColor = color;  
}

EL_clear.addEventListener("click", () => {
  const tmp_color = color; // Remember current color
  color = "transparent";   // Temporarily set it to transparent
  EL_grid.querySelectorAll(".box").forEach(paint); // Paint all cells as transparent
  color = tmp_color;       //* Reset as it was before.
});

EL_color.addEventListener("change", () => {
  color = EL_color.value;
  if (color === "random") color = `hsl(${~~(Math.random() * 360)}, 80%, 50%)`;
});

EL_size.addEventListener("change", () => {
  size = parseInt(EL_size.value, 10);
  makeGrid();
});

// INIT!
makeGrid();
#grid {
  display: inline-grid;
  margin: 10px 0;
}

#grid .box {
  border: 1px solid;
  height: 10px;
  width: 10px;
  margin: 0;
  user-select: none;
}
<div>
  <label>
    Size:
    <input type="number" name="size" value="16">
  </label>
  
  <label>
    Color:
    <select name="color">
      <option value="black">black</option>
      <option value="white">white</option>
      <option value="red">red</option>
      <option value="yellow">yellow</option>
      <option value="orange">orange</option>
      <option value="fuchsia">fuchsia</option>
      <option value="transparent">CLEAR (transparent)</option>
      <option value="random">RANDOM COLOR</option>
    </select>
  </label>
  
  <button id="clear">Clear canvas</button>
</div>


<div id="grid"></div>

Upvotes: 0

A Haworth
A Haworth

Reputation: 36512

A couple of related problems:

The variable boxes is undefined. It looks as though it was required to be the set elements with class box. When it is being defined this is indeed done, but then made undefined by the forEach attached to it. Separate out these two things and boxes will become the collection of all elements with class box.

Then when the clear is clicked you need to step through each of these boxes making their background color white, so again use a forEach.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Etch-a-Sketch</title>
  <link type="text/css" rel="stylesheet" href="styles.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <style>
    #mainGrid {
      display: grid;
      justify-content: center;
      align-items: center;
      grid-template-columns: repeat(16, 1fr);
      grid-template-rows: auto;
      margin-left: 150px;
      width: 200px;
    }
    
    .box {
      color: black;
      border: 3px solid;
      height: 10px;
      width: 10px;
    }
  </style>
</head>

<body>
  <div id="colorContainer">
    <input type="radio" id="blackchoice" value="color" name="black" class="defaultbtn">
    <label for="defaultcolor">black</label>
    <input type="radio" id="randomgen" class="hey">
    <label for="randomchoice">random</label>

  </div>

  <div id="changeGrid">
    <button id="clear">clear</button>

  </div>


  <div id="mainGrid"></div>

  <script src="app.js"></script>
  <script>
    const containerGrid = document.getElementById("mainGrid");

    function makeGrid(col) {
      for (let i = 0; i < col * col; i++) {
        const gridAdd = document.createElement("div");
        gridAdd.classList.add("box");
        gridAdd.textContent = "";

        containerGrid.appendChild(gridAdd);
      }
    }

    makeGrid(16); // make grid 16*16


    const btnClear = document.getElementById("clear");
    //mouseover event black - need to link to button (well done :)
    const boxes = document.querySelectorAll('.box');
    boxes.forEach(box => {
      box.addEventListener('mouseover', event => {
        box.style.backgroundColor = "black";
      })
    });




    btnClear.addEventListener("click", () => {
      boxes.forEach(box => {
        box.style.backgroundColor = "white";
      });
    });





    const changeGrid = document.getElementById(".sizechange");




    /*clearBtn.forEach.addEventListener("click", function () {
    clearBtn.style.color ="white";
    });
    */


    /*const randomBtn = document.getElementById("randomgen").addEventListener('click',(e) => {
        console.log(this.classname)    
        console.log(e.currentTarget === this)
        }) */
    //change color
  </script>
</body>

</html>

Upvotes: 3

Related Questions