I'm happy with how it turned out! It was a bumpy ride though... |
The requirements for the project are the following:
- Generate a grid and allow users to choose the number of cells in the grid while conforming to the original grid size.
- Allow users to clear the grid so they can draw something new.
- When the user hovers over the grid, allows them to change the colors of the cells.
- Optional: Allow users the option to select a random mode where each pass through a cell changes to a random RGB valu.
- Optional: Allow users the option to select a shader mode where each pass through a cell adds another 10% of black to it so that after 10 passes is the square completely black.
- My Extra: Allow users to have an eraser tool
- My Extra: Allow users the option to pick their own color using a color picker.
But it wasn't quite working as intended.
When you clicked the shader button, it worked as it should, but the bug was that it became persistent and continued the shader functionality (decreasing in opacity) when you switched to any other mode as well. Clearing the grid or resizing it did not help. Nothing short of ctrl+r made it go away.
Not working as intended at all!
So I spent the next THREE days trying to figure this damn thing out. I almost got it working close to intended when I switched from using opacity to straight up changing the color values themselves (i.e. hex value of #999999 => #111111). However! There were other bugs related to the shader, where when you clicked the shader (it worked), but when you clicked it again it still worked, but now instead of going through 10 passes to get to black, it was 5 passes. If clicked shader again, it was now just 2 passes to get to black. Then 1. Other bits and bobs I tried was using the removeEventListener, forcing refresh (no, no, no), and tons of refactoring.
So with my frustrated grouchy face at home, cue the husband noticing and asking to look at my code. I grumpily told him what was wrong and after a ton of console logs, we figured it out.
I was calling the mouseover eventlistener inside a function. This function was later called from the click eventlistener.
const drawShade = () => {
sketchPad.addEventListener("mouseover", e => {
e.target.style.backgroundColor = "black";
let opacity = Number(e.target.style.opacity);
if (e.target.style.opacity <= 1) {
opacity += 0.1;
e.target.style.opacity = opacity.toFixed(1);
}
});
};
const shade = document.querySelector("#shade");
shade.addEventListener("click", e => drawShade());
Yeah, you're not supposed to do that! Why? Because once you call that function, it's going to have that mouseover eventListener hanging around forever (until refresh). And when you call the function again by clicking on the button again, that evenListener is going to duplicate itself! And so on and so forth.
So this is just another case of my wanting to cram in as many things at once instead of focusing on one functionality at a time.
For something like mouseover that is persistent, that function should only be called once. And you have to work around creating something that manages the various modes.
In the end, I created an actual "mode" value that defines what the mode should be based on the user click. And the drawMode() function, being called only once and is persistent changes the mode based on the user click.
Here's the old code when I thought I was nearly done. Compare that sucker to how different it is from the final code. There was a lot of refactoring done!
Touchy Feely Stuff
Oh boy, was this project a roller coaster ride. Before I started, I was super nervous. You know the whole thing about "if I try, I might fail. If I don't try at all, I can't fail... right?" Yeah, that's why I am always nervous before starting any project. The fear of failure.But I started it (after procrastinating a bit), I got the grid creator to work within minutes using CSS grid, fixed up the CSS to look the way I want it to (I am really pleased with it!). I got most of the functionality to work with ease and pretty minimal googling. Huzzah! I was on cloud 9.
Then that bug reared it's ugly head. Like I said, I suffered through it for 3 days. For comparison, the project took a total of 17 hours... 10 of which was bug fixing. Yeah... And this was the time where I'm thinking "This is the second, the SECOND project on the Odin Project. If I can't do this right, how the heck do I expect to do the rest of the projects which are harder!?" SO. DAMN. FRUSTRATING.
When I understood why it was bugging out and fixed it... it was like those 3 days were erased. Total euphoria and relief. And exhaustion. Hence why I had to take a few days away from it to decompress and let it sink in a bit.
But this is how you learn and become a better developer right? Through hours and hours of frustration and when its solved, you feel like a million bucks. I am OK with that.