I've got this webpage with a
picture of Winston.
It's getting cold here,
and Winston is getting old,
so he wishes he had a beard.
I could draw the beard myself.
But I think it'd be way cooler if
the user could draw the beard
on Winston themselves,
however they want it to look--
a long beard, some stubble,
whatever they're into.
So how could we do that?
One way is to add an event listener
for the `mouseMove` event on the image,
so that our function would get called
whenever the user moved their mouse
over the face.
Let's set that up, using
what we just learned.
The first step is to find
the element, the image.
[typing]
..."face", since I had that nice ID.
The second step is to define
the callback function.
And we're going to start with a simple one
just to make sure that it worked,
and we'll make it do more later.
[typing]
Okay.
And the final step is to
connect this to this,
to make sure that this gets called
when this gets the `mouseMove` event.
So we'll write
`face.addEventListener("mousemove",`
and then pass it the name
of the function, `onMouseMove`.
Now, pause the talk-through, and try
moving your mouse over the face.
Do you see the message?
Okay, hopefully you saw that
we've got that event working.
But it's not what we want
our event listener to do.
We want it to draw, not to write text.
How can we draw in a webpage?
We could bring in the `` tag
and draw pixels on it, like we do
with ProcessingJS programs here.
But all we're drawing is a beard,
which is really a bunch of black dots.
So we could just create a `` for
each dot, and position that ``
with absolute positioning.
Here, let me show you with
one beard follicle.
So I'll make a `` with class `beard`,
and then I've got some nice CSS
to style that beard,
which I'll just stick in here.
And let's just fix that up.
So you can see our beard is a
black background, it's 5 by 5 pixels,
it's got this 2 pixel border radius
to make it a little bit round,
and it's using absolute
positioning scheme.
Currently, the ``
shows up under the image.
How do we get it to show up
on top of the face?
We're using absolute positioning,
so that means that we should use
the `top` and `left` properties
to say where it should actually
get positioned,
now that it's absolute.
So let's say `top: 80px;`,
and then `left:15px;`.
Beautiful.
Now that we've got that working in HTML,
let's make it work in JavaScript,
so that the user dynamically creates this
`` every time they move their mouse.
We'll go back down to our
JavaScript callback function.
The first thing is to create a ``,
which we can do with our
`document.createElement()` function--
it's going to be a `div`.
Second thing to do is to add that class:
`beard.className = "beard";`.
So we've got this ``,
it's floating off in space.
Final step, append it to the body.
All right, so now we've basically done
in JavaScript what we had done in HTML,
so we can delete this HTML.
Now you should pause the talk-through,
and try clicking Winston.
See what happens.
Did you see the beard follicle show up?
And did you try clicking multiple times?
If you did, you probably noticed that
your second click did nothing--
or at least it appeared to do nothing.
That's because every `` has
the same `top` and `left` properties,
so new ones just pile
on top of the old ones.
We want the `` to show up
wherever the user's mouse is instead.
How do we actually find out
where the user's mouse is?
As it turns out, the browser
records a lot of information
every time any user event happens,
like where it happens.
And the browser gives you
that information every time
it calls your event listener function.
But where, how, can we get this
amazing information?
I'll type one letter, to give you a hint.
That `e` here, is the event
information object.
And the browser sends it as the first
argument whenever it calls
an event listener callback function.
We didn't need it before, so I didn't
bother writing out the arguments list.
But now that we're going to use it,
I'm giving it a name, to make it
easy to reference inside the function.
Remember that in JavaScript, a function
can be called with any number
of arguments, even if the function
doesn't use or refer to any of them.
So we were always getting this
information, we just didn't know it.
Now I'm going to log out `e`:
`console.log(e)`.
Pause the talk-through, click Winston,
and check your console.
You should see the
event object logged out,
and you can skim through
all the properties on it.
There are two event properties in
particular that we're very interested in:
`clientX` and `clientY`.
They record the x and y of the event,
and that's what we're going to use
to position the beard.
Let's set the top of the beard equal to
e.clientY, plus "px", for the units.
And set the left equal to
e.clientX, plus "px" for units.
Now pause and try mousing over.
Draw Winston a beard.
Pretty cool, huh?
I bet you can imagine all sorts of fun
painting apps that you can make,
using clientX and clientY.
And as you saw in the console,
there were a bunch of other properties
on the event object
that you could use as well.
The most useful, I think, are
the keyboard-related ones.
So that you can find out
what keys the user was pressing
when the event happened,
and use that to make a
keyboard-accessible interface,
or a really fun game.
Oh, and one more thing:
you don't have to call this argument `e`.
That's typical, but some developers
call it `evt`, or `event`.
It doesn't matter what you call it,
as long as it's referring to
the first argument that the browser
passes to your function,
and as long as you then
refer to it that way later as well.
If you're having trouble with it,
make sure you use console.log
to help you debug what's going on.
When you're a web developer,
the console is pretty much
your best friend ever-- use it!