Home > OS >  How to make my cursor behave like a pen in my sketch webpage project?
How to make my cursor behave like a pen in my sketch webpage project?

Time:02-07

I set up a grid 16x16 which a white background now i want the divs (grid items) to change color every time i press and hold my mouse and move over them, and to stop changing color when i stop the mousedown event, like in paint. in my script:

let gridContainer = document.getElementById('grid-container');
let gridArray = [];
for(let i = 0; i < 256; i  ){
    let div = document.createElement('div');
    div.setAttribute('class', 'grid-item');
    gridContainer.append(div);
    gridArray[i] = div;
}

gridContainer.addEventListener("mousedown", draw)
gridContainer.addEventListener("mouseup",stopDraw)

function draw(){
    gridArray.forEach(item => item.addEventListener("mouseover", () => {
        (item.classList.add('hover')) 
    }));
}

function stopDraw(){
    gridArray.forEach(item => item.removeEventListener("mouseover", () => {
        (item.classList.add('hover')) 
    }));
}

The hover class is used to change the background color to blue.

I tried multiple other approaches but i always end up at the same place, the draw function not working unless i click which runs the function then it doesnt stop, it keeps running even after i leave the mouse.

Im using vanilla JS, I am still learning the basics.

Here is my code for better understanding my problem: https://codepen.io/ahmedmk11/pen/VwrmyGW

EDIT: I just realized that i didnt explain my problem in a clear way, so the draw function works properly, but my problem is that it doesnt stop working, i need in to only work when im pressing and holding only, like a pen.

CodePudding user response:

Using event listeners is a good approach, to keep with this I have changed your code to use an object. Using an object allows the state of the mouse to be temporarily stored. Using the "canDraw()" method we can read from the object to determine if the mouse event is still occurring. It is still occurring if the key "mousedown" is still present.

The events now just add or remove the key from "mouseEvent" object.

let gridContainer = document.getElementById('grid-container');
let gridArray = [];
let mouseEvent = {};
for(let i = 0; i < 256; i  ){
    let div = document.createElement('div');
    div.setAttribute('class', 'grid-item');
    div.addEventListener("mouseover", draw);
    gridContainer.append(div);
    gridArray[i] = div;
}

gridContainer.addEventListener("mousedown", () => mouseEvent.mouseDown = true)
gridContainer.addEventListener("mouseup", () => delete mouseEvent.mouseDown)

function canDraw() {
  return mouseEvent.mouseDown;
}

function draw(e){
    if (canDraw()) {
      e.fromElement.classList.add('hover');
    }
}

CodePudding user response:

Looks like you say that the div's should be paint when the mouse button is pressed, but you never really say that the divs should not be painted when the mouse button is not pressed, this happen in this specifc part:

function draw(){
    gridArray.forEach(item => item.addEventListener("mouseover", () => {
        (item.classList.add('hover')) 
    }));
}

function stopDraw(){
    // right here!
    gridArray.forEach(item => item.removeEventListener("mouseover", () => {
        (item.classList.add('hover')) 
    }));
}

You could change your code to make something like "hey, when my mouse is up and over the divs, I don't want to insert the class that paint them", like this:

function draw(){
    gridArray.forEach(item => item.addEventListener("mouseover", () => {
        item.classList.add('hover'); 
    }));
}

function stopDraw(){
    // now we have a event that removes the class
    gridArray.forEach(item => item.addEventListener("mouseover", () => {
        item.classList.remove('hover');
    }));
}

I also did some refactor (changed let by const when necessary, corrected the layout and moved the use of the functions draw and stopDraw after his declarations), I tried make less changes as I could, the final solution is:

const gridContainer = document.getElementById('grid-container');
let gridArray = [];
for(let i = 0; i < 256; i  = 1){
    const div = document.createElement('div');
    div.setAttribute('class', 'grid-item');
    gridContainer.append(div);
    gridArray.push(div);
}

function draw(){
    gridArray.forEach(item => item.addEventListener("mouseover", () => {
        item.classList.add('hover'); 
    }));
}

function stopDraw(){
    gridArray.forEach(item => item.addEventListener("mouseover", () => {
        item.classList.remove('hover');
    }));
}

gridContainer.addEventListener("mousedown", draw);
gridContainer.addEventListener("mouseup", stopDraw);
  •  Tags:  
  • Related