1
var d = document.getElementById('draw');
d.addEventListener('mousedown', function(e) {
   ctx = d.getContext("2d");
   var flag = true;
   ctx.beginPath();
   ctx.lineWidth = "10"
   ctx.strokeStyle = "green";
   ctx.moveTo(e.clientX, e.clientY);

   d.addEventListener('mousemove', function(e) {
       if (flag == true) {
           ctx.lineTo(e.clientX, e.clientY);
           ctx.stroke();
       }
       d.addEventListener('mouseup', function(e) {
           flag = false;
       });
   });
});

I'm doing 30 days javascript challenge and have a problem with respect to the above code. The addEventListener function('mousemove') can recognize ctx object. I thought the function cannot recognize ctx since no arguments have been passed to the function.

If I take the function out of the outer function(mousedown) and then an error occurs.

Any help would be appreciated.

Thanks

Debargha Roy
  • 2,320
  • 1
  • 15
  • 34
Jay
  • 13
  • 2
  • `ctx` is a local variable within the `mousedown` nest. You're also getting the context all over again when the mouse button is pressed which is unnecesary. You have to put everything in the "global" scope prior to the first event listener. – Chloe Dev Jul 22 '20 at 11:15
  • You probably need to know how `Scope` works in JavaScript. This may help: [Scope - MDN](https://developer.mozilla.org/en-US/docs/Glossary/Scope). Further more, the variable `ctx` here follows the rule of `lexical scope`. – Zmen Hu Jul 22 '20 at 11:19
  • @ChloeDev Thanks! Now I started to put everything in the global scope after taking class. – Jay Jul 24 '20 at 04:52
  • @ZmenHu Thanks.. This is what I am trying to find. – Jay Jul 24 '20 at 04:58

1 Answers1

0

You have to define your variables in the same scope that the event listeners are in, your nesting was also a bit messy and I don't know how the code was functioning at all since the event listeners was nested in eachother. You also don't have to redefine the context each time you start a new path, you can use the same context as previously.

You also stroke the paths on-top of eachother without clearing it before. You can fix this on your own by either clearing the canvas before drawing the new stroke or resetting the position of the context cursor to where it is when mouse move is executed.

ctx = d.getContext("2d");

ctx.lineWidth = "10"
ctx.strokeStyle = "green";

var flag = false;

d.addEventListener('mousedown', function(e){
  ctx.beginPath();

  ctx.moveTo(e.clientX, e.clientY);
  
  flag = true;
});

d.addEventListener('mousemove',  function(e){
  if(!flag) return;
  
  ctx.lineTo(e.clientX,e.clientY);
  ctx.stroke();
});
  

d.addEventListener('mouseup',  function(e){
  flag = false;
});
Chloe Dev
  • 271
  • 1
  • 8
  • The event structure is mixing of two typical drag operations. The difference is, that in the "nested construction" mousemove and mouseup events are detached in mouseup handler, whereas in the "flag-based" construction the events are attached only once. – Teemu Jul 22 '20 at 11:33