Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript jQuery Basics (2014) Creating a Simple Drawing Application Perform: Part 5

romankozak2
romankozak2
5,782 Points

Better understand the function(e) and lastEvent = e.

Can someone break down the function(e) for mousedown?

I'm not understanding the reasoning behind the lastEvent = e along with adding it to the end of the if statement again.

7 Answers

I don't think the mod did a good job telling you why we need it.

So let's think of me moving the mouse from point A to point B, what happens? for every little move of a pixel(or some small unit), the mousemove event gets fired, that means that for a small move of like a centimeter on the screen, the event keeps firing repeatedly soooo many times. That's why, he faces the 'bug' where from the beginning point, there are hundreds of lines drawn to the current mouse location. Why does that happen? We've told the browser to mark the beginning point, and then draw a stroke from the beginning point, to each and every one of those hundreds of little movements between point A and point B. By assigning lastEvent=e, what happens?

ONLY FOR THE FIRST MINISCULE MOVEMENT OF THE MOUSE, i.e the first time that the mousemove() function is trigerred, the lastEvent value is the position where the mouse was first clicked. Now, before the mousemove() function is fired again, the lastEvent changes to the new position of the mouse on moving it, then a millisecond after that, when the mousemove() is fired again, the lastEvent position is now the new position of the mouse after it has moved by a pixel or so. So basically, let's say there are 100 points between A and B. The function mousemove() will be called 100 times. And each time it is called, the line we are drawing will increase a little in length. But unlike before, the beginning of the line won't be from the initial co-ordinates of the mouse click, because we are constantly assigning a new location to the lastEvent, so basically the "original position" of the mouse can be imagined as if it's tailing our mouse movement, and it keeps following our mouse with every event.

Kevin Faust
Kevin Faust
15,353 Points

//*moved to answer

Great answer Aviral!!

pawkan kenluecha
pawkan kenluecha
26,303 Points

I like this reply. It's very clear. For someone that still hasn't understood this, this is easier version.

TL;DR: imagine that mousemove() is loop event. It occurs every time you move the mouse.

1.
Call mousedown() // this calls only 1 time.
: lastEvent = e ---> assigns the position when mouse is down to lastEvent. 
 End this event.

2.
Call mousemove() // this keeps calling every time you move a mouse(it means every pixel).
 : moveTo(lastEvent.offsetX,lastEvent.offsetY) ---> assigns the position from mousedown event.
 : lineTo(e.offsetX,e.offsetY) ---> draws line from the mousedown position to the mousemove position.

The rule is every time you move a mouse it calls mousemove() event. 
If you don't adjust the position of the function, it will call from the position of mousedown event every time. 

: lastEvent = e ---> This adjusts the position to the last position of mousemove() 
before mousemove() has been called again.

  This should be easier to understand if you assume that mousemove() is called for every pixel. 


-----------  x
|  0   [---][---][--][-] : There are 3 lines overlarpsed in this case.
|  1    [][][][] 
|       0 1 2 3
Y


The mouse moves by 1 pixel : starts from ---> moveTo(0,0) ---> lineTo(1,0) 
The mouse moves by another pixel : starts from ---> moveTo(0,0) ---> lineTo(2,0) 
The mouse moves by another pixel : starts from ---> moveTo(0,0) ---> lineTo(3,0) 


-----------  x
|  0   [-][-][-][-] : No lines overlarpse because they adjust the origin every time the mouse moves.
|  1    [ ][ ][ ][ ] 
|        0  1   2  3
Y


The mouse moves by 1 pixel : starts from ---> moveTo(0,0) ---> lineTo(1,0) ---> lastEvent = e (1,0).
The mouse moves by another pixel : starts from ---> moveTo(1,0) ---> lineTo(2,0) ---> lastEvent = e (2,0).
The mouse moves by another pixel : starts from ---> moveTo(2,0) ---> lineTo(3,0) ---> lastEvent = e (3,0).

The format is really messy, so I put it in the block code.

The 'e' in the function is the event itself. So when the user clicks a mousebutton the event data gets passed in the e variable.

I hope this helps.

No problem. I was initially confused a lot when I saw it first so soon as I figured out what's happening I knew that many others would probably like having an easy explanation. I don't usually complain about treehouse courses but this part really needed to be explained better. Like the whole canvas part was just not explained well, the instructor assumed everyone would know what's going on...

Yes, Aviral, thanks for the more detailed explanation! So basically, as default the line is drawn from the original mouse down point, but by setting "lastEvent = e" the line begins from the new position as opposed to the very first position.

yes this instrcutor is bad

Kirsty Pollock
Kirsty Pollock
14,261 Points

I did the drawing stuff by myself, without looking at the vid, so I did it with named functions, and no "last event" and maybe my code might be easier to understand...

e is the event, of course, and is NOT declared anywhere, it is just a function argument ( to fit the required callback pattern for the mouse events).

...

function canvas_mousedown(e)
{
    //Start drawing at the mouse position passed in the event
    context.beginPath();
    context.moveTo(e.offsetX, e.offsetY);
    mouseIsDown = true;
};

function canvas_mousemove(e)
{
    //Draw to current mouse position passed in the event, only if mouse is down
    if (mouseIsDown)
    {
      context.lineTo(e.offsetX, e.offsetY);
      context.strokeStyle = currColour;
      context.stroke();
    }

};
function canvas_mouseup(e)
{
    //Set flag that will stop drawing until we mousedown again
   mouseIsDown = false;
};

...

// attach event handlers to canvas  mouse events
canvas
  .mousedown(canvas_mousedown)
  .mousemove(canvas_mousemove)
  .mouseup(canvas_mouseup)
  .mouseleave(canvas_mouseup);
romankozak2
romankozak2
5,782 Points

Got it. Thanks!

So why is the lastEvent = e reentered in the if statement for the function in this particular lesson?

romankozak2
romankozak2
5,782 Points

Right, but why is lastEvent given the value of e again in the if statement of the function for mousedown. What purpose does that serve? It was already given the value of e once in the function prior to the if statement. When he added it to the end of the if statement, it fixed the issue he was having with the drawing of the lines.

The data is collected in the variable and from the variable he has access to the coordinates of were the event occured so that he can use that information to create the lines of color within the canvas.

Rifqi Fahmi
Rifqi Fahmi
23,164 Points

here to make you clear. The e is a variable inside that function. So to acces the "e" data outside the function you need to store it to the global variable which is lastEvent. Thats why he can acces it again in .mousemove :D