Check out a free preview of the full CSS Animations and Transitions course

The "Pointer Events" Lesson is part of the full, CSS Animations and Transitions course featured in this preview video. Here's what you'd learn in this lesson:

David explains that, unlike state or layout animations, reactive animations are based on continuous input. An example would be an element following the mouse. The pointermove event can be used to capture the position of any pointer device. CSS custom properties can make the pointers position available in CSS.

Preview
Close

Transcript from the "Pointer Events" Lesson

[00:00:00]
>> Our last lesson is going to be on reactive animations. So, what's the difference between all of the animations that we've done and reactive animations? So, the biggest difference between these two which they might feel like completely different things is that the animations that we were talking about with transitions and keyframes and state based animations and layout animation, all of those, you could think of as pretty much hands off from any external input.

[00:00:35]
So you're basically saying when I change this date, this animation is gonna happen. I don't care how it happens, it's sort of like a fire and forget. It's going to happen, it has a start, it has a stop and there's your animation. So, same thing with layouts and all of those things.

[00:00:52]
So, reactive animations are different because they are dependent on continuous input. So for example, when you're moving your mouse or when you're on your phone and you're doing, one of the most common animations, especially on dribble is the Tinder Swipe. So, you're swiping either right or left and you could see the card rotating and moving as you're moving your hand, and there's also secondary animations to that such as the green checkmark appearing, the red checkmark appearing.

[00:01:25]
And so you have opacity, you have transitions, sorry you have transforms, you have rotation, there's a lot of things going on and it's all based on the position of your finger, or just the pointer technically. And so reactive animations are about that, it's about reading continuous input and reacting to that in real time.

[00:01:50]
So, we're gonna be talking about how to do reactive animations in here. All right, so with this I'm actually going to jump straight to the exercise. Let me get rid of this. And so, this is the reactive animations exercise. So we have our little ball here again, and you know what?

[00:02:17]
Let me just go ahead and make that a little bit bigger. Okay, so we have our circle here, let's make it 10vmin. And so, in terms of reactive animation, here is our initial goal, we want this ball to follow our mouse. So it seems like a simple task.

[00:02:41]
How exactly should we do that? So, of course this is going to require some JavaScripts. Unfortunately, there isn't a straightforward way. I see that there isn't any real way to do this with pure CSS alone. Okay, so we have the circle element and what we want to do is we want to listen for events so that we could grab the cursor position and somehow change the position of the circle so that it is moving with the mouse.

[00:03:14]
[COUGH] Okay, so, first we're going to add an event listener on the body. And I'm gonna call this pointer move. By the way, you might have used mouse move, mouse down, mouse up. I personally really like using pointer because a pointer device can be your mouse, it could be a stylus, it could be your finger, it's a lot more versatile than just a mouse.

[00:03:39]
So, I do recommend using pointer events whenever you can. Okay, so first things first, let's console.log this event and see what we get when we're moving our pointer. So I'm gonna go to the console and you can see over here, we have a bunch of pointer events and there's a few things inside of it.

[00:04:04]
Actually, there's a lot of things inside of it. Because it is a pointer, we have things like the altitude angle, which doesn't really make sense to me because I'm pretty sure my mouse is right there, it's not hovering over the screen or something like that. But we have these two things, client X and client y.

[00:04:23]
These are going to be the properties you want. So, this is the x and y position of the pointer relative to, well, the client, so the the viewports. And so, at this moment in time, the x position was over here, sort of, at 838 pixels, the y position was at 394 pixels.

[00:04:46]
Okay, so what do we do with this information? Well, first let's grab it. So const (clientX), ( client Y), let's grab that from the events, and just to show you again, we're gonna log (client X and client Y). So now you could see that this is changing as we're moving the mouse.

[00:05:12]
So remember from previous lessons we could use CSS variables to basically communicate between the JavaScript and the CSS worlds. So, let's go ahead and do that. (circlel.style.setProperty). And I'm going to set X to my clientX and I'm gonna set Y to my clientY. Now, in the styles we're not doing anything with that yet, but I just want to make sure that we do have those in CSS, so I'm actually gonna add some styling over here.

[00:05:52]
And you don't have to do this, it's just for debugging purposes basically. The contents of this, I'm gonna get my, but let's just get the entire style attribute and just get that in there, position: absolute, bottom: 100%, left: 0, margin bottom: 0.25rem, color: white, font-family: monospace and background: black, padding: 0.5 rem.

[00:06:28]
Don't worry about this at all, you're gonna see why I'm doing it. So, actually it's completely off screen. So I'm just going to say top:100% and left:0. Okay, so [COUGH] Now you could see the reason that I did this was because I'm showing you that we're getting that double dash x and double dash y.

[00:06:51]
We're getting both of those custom properties in CSS. So, this is of course being read just from the style tag. And so now we could actually do something with these values. So, I'm also gonna give it a white-space: no wrap because it's looking weird. Okay, cool, so we have that over there.

[00:07:17]
So, of course you might be thinking, can I just use left or top? Again, try to avoid that, that's going to cause a layouts trigger. So instead we wants to transform it. And so we're going to translate. And by the way, this is gonna seem broken, but there's a reason why it's broken.

[00:07:40]
But we're gonna give it var x and var y And so this should move, but it's not moving. Can anyone here guess why this circle is not moving? I mean, it's getting the values. So, Why isn't it moving? So, the reason is because the x and y variables are unitless, there's no unit, there's no pixel or rem or whatever, so CSS doesn't know, okay, I should move by 130?

[00:08:18]
130 what? Feet, inches, CSS has no idea. So we need to convert these two pixels somehow, and there's two ways of doing it. One way is the easy way and one way, in my opinion is the better more CSS way. So, we could take each of these, this is the easy way, and we could convert these to those pixel values by adding px over here.

[00:08:46]
All right, so by doing this, now we have a circle that's following our pointer, which is great. But one potential problem of this is that now it becomes a lot harder to use those raw values because they're converted to pixel values. And so if you wanted to use them for things other than just moving the position as is, it becomes a little bit more difficult, at least in my experience.

[00:09:19]
So instead, if we get the raw values over, we could define our own custom variables. So, we could, I'm gonna put this at the top, x px and this is calc(var x) * 1 px. And so, now we're giving a unit to the unitless value. [COUGH] And so for y px, oops, that should be pixel, that's gonna be that.

[00:09:51]
And so, now we could just add px to each of these and it should work. Okay, so now we have a circle following us around, it's working pretty well. And so, what I also wanna do, is do left:-30%, top: -30%. And so that's just gonna get the circle, oops, that's the wrong one.

[00:10:19]
So, [COUGH] basically, we want the circle in the middle. So, we could use calc for that, calc(var x-px -50%) and (calc var y px -50%). So here's our x value and here's our y value. So, all we're doing is we're getting that pixel value and we're moving it 50% to the left and 50% up so that the circle is right in the middle of our cursor.

[00:10:58]
Which it is.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now