 So we're going? Yeah. Are you good? Are we doing that? What's the... Does that help? Should we do it again? Maybe. I can only apologise for the gradient. It looked great on my screen. It sort of looks like toxic sewage. Now I'm seeing it in front of us. Yeah, my bad. Never mind. How rotate zero fixed my transform animation on the screen. So I was in a situation where I had a bunch of stuff on the screen. And I wanted to zoom into one of them. Which one? Pick one. What should we do? What should we zoom into? Oh, the pile of poo, right. Yup, let's do the pile of poo. By the way, this wasn't set up. I just had a hunch. I saw all of those. I'm like, I know which one I'm zooming into. I had an 80% certainty that you would pick the same. Let's zoom into the poo. So the way I did this, was I used JavaScript get bounding client rex to find the poo box. It's funny, isn't it? The poo box and the area that I wanted to fill with poo. So I had those two boxes there. Scaling happens from the middle out. So the first thing I want to do is get those midpoints to be in the same place. So I did a translate. There we go. And then I need to do the scale. I've got the bounding rex. The poo is an eighth of the size of the container on the height there. So I just need to scale it up. Like it bigger. And it finally remembers. There we go. Wish it didn't do that. Anyway, and that was my solution. So I did it with the Web Animation API. But this is how it would look as a CSS keyframes. Yeah, equivalent stuff. Feeling pretty pleased with myself. And then I ran the animation. And it did this. Dun dun dun dun dun dun dun. Woo hoo. And it's like, not really what I wanted. That wasn't it. Because it sort of feels like it zooms in and then swings to the right. Whereas I was kind of wanting more of an even thing. And so I did some digging into how this all works. I found out if I replace none with rotate zero. Yeah. The animation is now exactly what I wanted. Magic. And that sort of blew my mind. And I couldn't decide if that was just if I was like the last person to figure this out or whether that is something that's going to blow people's minds of why that works. Where are you on the scale? Do you know, does that make sense to you as a thing? I'm kind of seeing where it comes from, I think. But by default it doesn't make sense, right? Maybe we have to admit it. Yeah. That's how I felt. I thought like none, rotate zero, they're the same. They're both doing nothing. So why does it drastically change the animation in this way? And to find all of that out we need to explore how transform animations work in general. And eventually I'll get to why the rotate thing worked. So let's say I want to transform this box from here to here. It's also rotated. There's a number of different ways we could do that. One way would be a nice straight line and have it spin round as it's going down that line. But no. We're going to do it fancy. Whee! We're going to do this. So this kind of animation. You can on the web animate things on a path. That is a feature we have. I'm not going to do that. I'm just going to do it with pure transforms. Here's how I'd go about it. By default the rotate is going to happen around the middle of the box. So I need to move that center point essentially. I could use transform origin but I'm just going to do it purely. That would have been my guess. Transform origin straight down there. Exactly. But I'm not going to do that. I'm going to do it with individual transforms. So I'm going to do a translate 450 on the negative off it goes there. But the center point is still where it was. So if I rotate 90 degrees we get that arc but it's in the wrong position now. So do a counter translate and pop it back where it is. Do you read transforms backwards like that? I don't know whether I'm unusual. I always think of them. I don't. I read them from left to right. I think most people do. Really? That's unusual. I always think of it back to front like that. Because the first one if I read that forwards it's going to move down but then the rotate like I found it easier to think of it it's going up there and then it rotates around its new center point and then it goes down. I don't know maybe this is the sort of the problems I had setting up this animation in the first place. But if we run that animation it does this and it's not done a straight line but it's not correct either. You can see it sort of undercuts the curve and almost in some ways as well it feels like it rotates a bit before it even thinks about moving so like run and it moves. Okay to figure this out we need to look at this. This is the primitives and derive transform functions. An exciting bit of the spec which I didn't know until like we mentioned in a previous episode it pointed me at this and I was like oh that's why it behaves like this. Okay so now I guess the rest of the episode I'm going to explain what this all says. You're going to repeat what Rob said to you? No, what Rob said to me was here's a link and then I read the spec and to be fair to him that's all I asked him to do. This is what the browsers do according to the spec. We've got a from value and we've got our to value. It will add them out so they are the same length with kind of null things and then it will convert the format so that they're in the same kind of primitive so in this case it means turning the non into translate y zero we're turning the rotate to the yeah and there we go we've got our zeros and then it interpolates each of the things independently so our 50% mark there is is that. Makes sense. Yeah and when you look at that it starts to become obvious why it was going wrong so we were relying on that 450 value there to set our like center point of the animation down there but that's going to be interpolating from zero down to 450 as well as the rotation so what actually happened in our animation is the center point moved as well and you can see that is what was happening with that animation and that also explains why it appeared to not move at first because it was just going around the center point it is not until the center point it sort of drags it to yeah the final point I guess the solution in this case you want to put the 450 in there and that means they are going to interpolate from one value to the same value they will be there from the start the point will be there from the start and yeah only the rotation exactly that only the rotation is going to change and it's really cool that the spec lets you do this and browsers let you do this because all of these are matrices under the hood but by letting you set up only particular values that are going to change that's actually quite a complicated or a non-linear change in the matrix which is a fun thing to say under the hood that the browser will do for you because if we we are going to take our friend from Don Matrix and if I create a Don Matrix and to string it it gives us the plain matrix version back and if we compare the two matrices and we saw that these two things animated very differently but they kick out the same matrix because in both cases it results in the square not moving yeah because the one translate negates the other translates lift up part so exactly so that mattered for our animation but if it crushes down to a matrix it's that that change is gone and so if we take the matrix from the final point there you can see at the end of the matrix is that the translate calls a next translation and a Y translation and that six point blah blah blah I believe is the cosine of half of pi I believe someone can correct me on that if it's not that whatever I you know we're not here to do matrix maps but if we set that animation up between the two it does this and what you saw there was it's it's just going along the line and that's because we've lost information even though the matrix is equivalent to what we had before we've lost that special thing the browser was doing pairing them up and interpolating the primitives independently of one another so back to our Poozoo here's where we're at it's doing this and this is the transform we've got going on so let's have a look and see how the spec would handle that again it pads the values out same length and then it gets them into the same primitive so one translates zero zero exactly that and from that we can see what the midpoint would be and when I first thought about it like this I was like well that sort of looks fine like those half way points are half way it's kind of looking as I would expect here's the problem bring it up down matrix again so here I've got my point zero zero and if I translate it by negative one negative one and then scale it we're going to end up with a point that's at negative one negative one that's all fine but if we scale it by eight the point is now at negative eight negative eight and this is why I think of the of the transforms in reverse order because you translate it and then scale it so the scaling is applying to the translated value and what this means is towards the start of the animation where the scale is kind of one each time the translate nudges by say a pixel that is going to be a pixel on the screen towards the end of the animation when the scale is eight eight pixels at a time so one nudge on the translate and now it's up to negative 16 so what we've done is kind of baked in an easing you know easing into the animation just by ordering it like this and so that's what we're seeing here it does the zoom and then the trans and that's purely because it's ramping up the translate as the animation goes forward the solution swaps it then around so now it scales and then the translate happens in my head afterwards because I read these things backwards but that makes sense to me so we've scaled up a point from zero zero it stays at zero zero because you know you scale something at zero it doesn't move and then translate by minus one and if we nudge that translate up to a biothixel minus two the result is only nudging by one and that gives you this much more it's not being affected by the scale so in my animation swap those two around but numbers are now wrong because we've scaled it up by eight and that translate is not going to be enough to bring the poo into the center multiply by eight multiply and by eight there we go and I guess this is why how this whole problem came about is I was ordering the transform in a way that was easy for me in terms of maths well the translate did scale whereas in terms of making the animation work properly they needed to be in the other order yes I had to do a bit more maths but this is correct this will give us that animation everything working out now I am wondering what about your rotate zero so let's talk about that put it back where it was rotate zero do you have a theory? no because I knew this was going to happen by the time I did it because I'd read the spec so in total honestly I came up with this hack after the fact and the reason is back to this, pads them out and now what it tries to do is go for each column and get them into the same format and it goes rotate scale these are two completely different things now it will get similar things if you've got a translate x and a translate y it goes translate it can communicate both of those things but rotate and scale they don't have a common format except for the matrix and if it has to fall down to a matrix it does it for the whole rest of the transform so all these will be converted to matrices like this and in a matrix based animation we can see in the second row there the h is there that's a scale and then the translates are at the end there and they got multiplied by 8 they got pre-multiplied by 8 because when you're dealing with the matrices essentially the translates happen last conceptually last and this is the same if you use the individual transform properties if you do a scale and a translate you would have to multiply the translate by the scale if you were thinking in non-scaled terms so yeah as soon as you do that that was what caused it to fall back to matrices cool and I actually got the animation I wanted wow I wouldn't recommend that don't do that in your code because it's a horrible hack it just happens to work if you're fully aware of how that stuff works so I would go for this solution I think do the extra maths do the multiplication yourself but yeah so that was it that was my journey of actually understanding how transform animations work and it turns out now I can actually make them animate how I want them awesome so the transform zero is like yeah let's cut right there