Etch-a-sketch

https://codepen.io/Laing91/pen/oNQLroe?editors=1111 Currently I'm trying to create a mouseover (or hover..)? that changes the color of each div. So far I have a bunch of divs (gridItem) with the class .grid-item assigned to them. It's been awhile since I've used the DOM in vanilla JS and I've gotten myself mightily confused. The way I read my code, I've created the squares using the DOM to build a bunch of divs(gridItem) with the class of grid-item, and I've appended them into gridContainer. I've then created a mouseOver function that selects gridItem and changes the color of it to red, followed by the DOM again to again, select gridItem and initiate mouseover, followed by the function mouseOver.
Callum
CodePen
oNQLroe
...
38 Replies
Chris Bolson
Chris Bolson12mo ago
You are almost there, you are just trying to detect the mouse over in the wrong place. This needs to be done for each div once they have been “drawn” (added to the dom) I have made a copy of your code and made a couple of changes to get it working (only tested on mobile) https://codepen.io/cbolson/pen/xxQOovP
CDL
CDL12mo ago
Damn I was so close, that's agonizing LOL Thanks a bunch Chris, I'll enhance this a bit more, appreciate it
Chris Bolson
Chris Bolson12mo ago
Just a suggestion - using a css grid might be a better option than flex.
CDL
CDL12mo ago
100%. I only did it through flexbox as it was a requirement given to me. Grid makes much more sense for something that is a... grid... 😅
Chris Bolson
Chris Bolson12mo ago
😀
vince
vince12mo ago
I thought this would be a fun challenge, took me a little bit but here's what I came up with after seeing your solutions: https://codepen.io/vince1444/pen/XWyKvxq?editors=1111
CDL
CDL12mo ago
That’s cool! I want to advance on this much more, this was just the beginning. I’m debating between leaving it in the corner and centering it. Either way I’ll add dynamic resizing, reset button and some other bits. I also think having it on a mouse click hold/release would be better then just mouse over, then I’m not starting the second I hover over it
Chris Bolson
Chris Bolson12mo ago
I know you have already explained why you aren't using grid but I just wanted to take my copy a little bit further and convert it to grid and slightly altered the hover functionality to toggle a class https://codepen.io/cbolson/pen/BaGzXoX
CDL
CDL12mo ago
I do want to move it to grid and I probably will, I think it's much smoother. I like your idea. After work i plan on setting up a reset, then having it only color in squares when I'm holding down left click, to avoid you filling it in as soon as you start hovering 😄
Chris Bolson
Chris Bolson12mo ago
I have updated my latest pen to calculate the number of cols and rows to show directly from the HTML so these numbers (16 x 16 in you demo) doesn't need to be hard-coded in the JS
CDL
CDL12mo ago
Would that make it easier to dynamically adjust the number of columns/rows? example, I want to add a few buttons to change the grid size.. 16x16, 8x8, 4x4 etc..I was going to just chuck the initial JS code into a function and attach it to a button, and repeat that for the other buttons.
Chris Bolson
Chris Bolson12mo ago
I don't thibk that it would make the JS any easier as what you suggest is simple enough. In fact it might even complicate it 🤔 .
The issue might be if you move over to CSS grid-template-columns as they will need to "know" how many columns to show. Of course this could also be adjusted via JS.... I really just did it as proof of concept to avoid having to define the number of columns and rows as hard-coded values in the JavaScript file.
CDL
CDL12mo ago
Fair enough, thanks 🙂
Chris Bolson
Chris Bolson12mo ago
(just updated mine to calculate the number of columns and rows via data attributes rather than css custom properties)
vince
vince12mo ago
Oh nice! I need to use data-attributes more I think you can improve a bit on the optimization: You have an event listener on every single gridItem. Can't you just put a single event listener on the gridContainer and use event delegation for that? That's what I did in my demo and seems to work fine Not sure the performance implications but I'd imagine it's a bit more performant that way
Chris Bolson
Chris Bolson12mo ago
I don’t think that the performance would change much as with your method the code has to go through the dom to get the class name. With mine it doesn’t need to re-read the dom as it already has the element when it is created. It also allows you to have other data which might be needed, again without having to re-read the dom to get it.
vince
vince12mo ago
Ah I see 🙂
Chris Bolson
Chris Bolson12mo ago
I may we’ll be wrong. I’ll look into it later if I get a chance.
vince
vince12mo ago
Don't worry about it I don't think it really matters all too much 😂 I appreciate you
peter.ogilvie
peter.ogilvie12mo ago
I love this!
CDL
CDL12mo ago
Mentor had a quick go at doing it with a global variable state, instead of relying on the DOM. I'm too newbie to know which one is more preferred, however I like how incredibly easy he made it to change the board size, and even the color! https://codepen.io/Laing91/pen/oNQLroe?editors=1111
Chris Bolson
Chris Bolson12mo ago
I like how they are using an array to store the grid data. However I'm not convinced by the need, and, more importantly, the amount of times that the grid is re-rendered. Every time you mouseover a single cell the whole grid is re-rendered multiple times. I haven't been able to work out exactly how many as it seems to vary. It also rerenders on mouseout which is strange
CDL
CDL12mo ago
Yea I can see that. The entire thing was more of him just showing me a different way to store state, as opposed to the way I was doing it
Chris Bolson
Chris Bolson12mo ago
I have forked it and added a slight delay on the rendering so that you can easily see the re-rendering occurring https://codepen.io/cbolson/pen/rNQMrgL Your way was fine. There is no need to re-render the whole grid just to change the color of a single cell.
CDL
CDL12mo ago
Good to know 😄 I just need to add some more features and tweak the GUI and then i think I can move onto my next task (Calculator)
Chris Bolson
Chris Bolson12mo ago
by the way, I also added buttons to choose the size of the grid - in my version I kept the grid size (dimensions) itself the same and ajsust the size of the cells within. This of course would depend on the specific needs.
CDL
CDL12mo ago
I think that's maybe similar to this one that my friend made? (I really like it, but he spent a lot of time doing it) https://victorhe33.github.io/etch-a-sketch/ most of the features on that link are what I originally wanted on mine haha
Chris Bolson
Chris Bolson12mo ago
That's nice!. Yes, similar to mine (though clearly with more functionality). They used flex rather than grid which doesn't convince me (though if that may have also been a requirement). A small detail is that they could have avoided a couple of loops in the makeGrid function where they are adding the eventlisteners but other than that I like it!
CDL
CDL12mo ago
Grid makes more sense, flexbox was a requirement from odin project 😛
Chris Bolson
Chris Bolson12mo ago
(you know I am now going to have to add more functions to my version now.... 😆 ) I don't know how strict they are (or even if the odin project has any sort of revision and feedback) but I would do it with grid anyway and explain my reasoning. Maybe it was written before grid became an option.
CDL
CDL12mo ago
nah it was updated recently I believe, not sure why they chose grid though. Looking at the entire course, there actually isn't any mention of grid, just flexbox, so maybe it's just not a preference of theres. I'm happy to re-jig mine to grid though once I've finished it
Chris Bolson
Chris Bolson12mo ago
Added the "eraser" option In your friends version they also have a small issue with uneven numbers (above 10) for the grid size. It leaves an empty column on the right - just something to watch out for if you add that option to your version.
CDL
CDL12mo ago
cool thanks. i'll check out your version later as I want to add resizing without changing the size of the box, just the divs then I think if i centre it, make it look nicer, add the eraser option, i think that's enough for now 😄
Chris Bolson
Chris Bolson12mo ago
Added color picker (this required changing the way the cells were colored as I had been using a class which was toggled on and off) Added "reset" button
CDL
CDL12mo ago
https://callum-laing.github.io/etch-a-sketch/ style update today. Tomorrow we'll add some sizing buttons
Chris Bolson
Chris Bolson12mo ago
It's looking good! This is one of those projects that keeps on giving... I have swapped out my grid size buttons for a range selector, similar to the one in your friends version). Much simpler to use and, as it's name implies, gives more range.
CDL
CDL12mo ago
Yea, it's quite addicting lol. I do need to add a few more features and move onto my next project in the course, I'll more than likely come back to this when I've learned some more and make it more fun! I enjoyed making it alot Surprised at how much CSS I remembered too considering I haven't used it in maybe 6 months
vince
vince12mo ago
Css is one of those languages where once you pick it up you don't really lose it 🙂