When it comes to building whimsical interfaces, React is a surprisingly capable ally. In this talk, I'll show you how I use React to orchestrate complex interactions by digging into some examples from my blog.
AI Generated Video Summary
The speaker discusses the whimsical and detailed work of Stripe, particularly their interactive and dynamic pages. They explain the use of React for building whimsical details and tracking mouse position. The speaker introduces React Spring for smooth animation and React3 Fiber for creating a 3D egg model. They also mention the use of Framer Motion and React server components for animating CSS properties.
1. Introduction to Stripe's Whimsical Potential
The speaker discusses the whimsical and detailed work of Stripe, particularly their interactive and dynamic pages. The speaker compares the Stripe product's login page to the rest of the pages, highlighting the absence of whimsical flourishes. It is revealed that the dashboard uses React, while the landing pages do not. The speaker explains the reasoning behind using React for a data-driven and full-stack application.
So, I should warn you, the first two minutes are going to be unavoidably bright. The rest of the slides will be dark, but brace yourselves. I'm a big fan of the work that Stripe does. I find it's really whimsical and detailed. I remember when this mesh gradient came out and it was a big deal. But all their pages are really interactive, dynamic. You have this 3D globe that you first might think is a video, but then it changes as you scroll, so it really shows that it's a 3D model. Very, very cool stuff.
When you actually log in to the Stripe product, though, it's a bit like stepping through a door into a different universe. There's no mesh gradients. There's no floating globes. That's not necessarily a bad thing. Like, you know, it's a business to business SaaS product. You don't necessarily need a bunch of whimsical flourishes. But my point is that just looking between the two, right? It's very clear that it's a different product built by a different team, using different tools.
2. Building Whimsical Details with React
The speaker shares their use of React to build whimsical details, such as a cursor-tracked heart and playful Like button. They explain the inspiration behind these details and discuss the concept of their blog as a personal playground. The speaker also introduces the idea of building an egg shape and focusing on cursor tracking for head rotation and eye translation.
And I want to share how I've been using React to build some pretty playful, whimsical details. I also realized I don't have a water, so I'm going to steal one of these while we let my very fun title screen play out.
So, for those who don't know, I have a blog. I blog at JoshWComo.com and when I built this blog, I sort of figured that this was going to be my playground. So I was going to indulge all of the whimsical ideas that I had. So if there was like a playful idea I wanted to do, I was going to do it. This, I was sort of inspired by those, like iron shavings you get with a magnet and you move the magnet and the iron shavings ripple around. It's exactly the sort of like kind of pointless, but fun little detail that I say yes to when it's my blog because it's my own little playground and I can do whatever I want.
One of the little details, and I'm gonna zoom this way, way in. Oh, this part's also, let me, hold on, dark mode. This little fella down over here, there's a bunch of little details to it. It tracks your cursor, so the heart itself rotates depending on your cursor position. A little bit more subtle, the eyes move independently and I don't know how clear that is, but small thing. If you come near the Like button, but then move away, if you don't engage with it, he gets a little bit sad. Because, you know, he's a Like button, Like buttons like to be clicked, but he doesn't stay sad very long, I decided to make him very cheerful. And, of course, you can click on it. I wonder if I have sound, let me see. That's fine, it makes a little glug noise, you can imagine that. And if you keep clicking it all the way, eventually, you get to the top and you get a little pop of confetti. A little Easter egg that people don't know. You can right-click to remove Likes. You can have fun with that.
So, this is essentially what I want to talk about. There we are. We're going to build this, we're going to build an egg. I chose an egg because it's a slightly simpler shape. And we're going to focus on the cursor tracking, so the head rotation and the eye translation. Now, even before we get to React, right, what are the things that we have to know to build this sort of interaction? Well, I need to know where in the viewport the cursor is. And the way we typically do this is by measuring the distance from the top left corner in pixels. So as you move more to the right, your x-value gets higher.
3. Determining Rotation Angle with Bounding Box
To determine the rotation angle of an element, you need to know its position in the viewport and the mouse position. By using the getBoundingClientRect method, you can obtain the bounding box of the element, including its width, height, and position relative to the viewport. With this information, you can pass it to a calculate rotation function to obtain the rotation angle in degrees.
As you move down from the top, your y-value gets higher. I also need to know this. I need to know the bounding box. Such like, a weird angle to look at. You need to know where in the viewport the element is, right? Because right now it's in the center, but you don't want to assume that. And if you have those two pieces of information, you can do the math to figure it out.
Now, I was, you know, it's always a bit of a debate. I want to show you exactly what this function does. But our time together is limited. And I don't necessarily think that getting into trigonometry is the best use of that time. So I'm going to treat this as a black box. I give it those two pieces of information and it spits out the angle that it needs to rotate at.
4. Optimizing Performance and Introducing React
I'm going to share a slide with a link to the code. The code runs dozens of times per second, which is slow for getting a bounding box. To improve performance, the code is moved to only run when the mouse moves. However, the bounding box still needs to be recalculated when the user scrolls. Event listeners and a resize observer are used, but there's still work to be done, such as cleaning up event listeners and debouncing calculations. React can help solve these problems.
But now is a good time to mention, actually, I'm going to be sharing a slide at the end with a link to all of this code. So if you are curious, if you want to see exactly how this works, you will be able to do that.
Finally, we get that rotation value, and we apply it as a CSS transform, setting an inline style, essentially. So what do we think about this? Like, does this work? Well, it works as a prototype. It works as an MVP. But there's often, like, quite a lot of distance between, like, it works on my machine in localhost and it's production ready.
For one thing, all of this code runs a lot, like dozens and dozens of times a second. And the problem with that is that getting a client req, getting a bounding box, is kind of slow. We think about it, right? This box doesn't really change as the user moves their mouse. Certainly, it does. Actually, it changes very slightly because of the rotation. But the center doesn't change. And so, like, if we want this to be performant, do we really have to be recalculating that box dozens and dozens of times a second?
So what I'm going to do is I'm going to grab these two lines and I'm going to move them up above the event handler, so now it only does this work when I move the mouse. But this doesn't really work super well either. For example, we do need to recalculate the bounding box when the user scrolls because right now, when the user's at the top of the page, this is the distance, but as they scroll, that distance changes. So, and you see what I'm saying, right? There's this journey between the working prototype and the production-ready version.
In addition to everything I already had, I also have to add event listeners to the scroll event, I'm also using resize observer. This will tell me not only… Actually, I don't think it does tell you if the window resizes. It tells you if the element resizes or if one of its ancestors has a change in CSS that causes it to resize. So, this is better, but there's still a bunch of stuff missing. For one thing, I should be cleaning up these event listeners, right? It's one thing to start that work, we also want to stop it. Like if the user navigates away from this page, we shouldn't still be tracking the mouse position. And maybe we want to debounce this so we're not calculating it on every scroll event, because that too fires really, really rapidly.
So, let's talk about how React can solve some of these problems. And we have it now running in React. Because this is a React conference, I'm going to assume that you're all somewhat familiar with the fundamentals of React. Even if you're not, I think this will make sense. We're going to keep things pretty high level. So, like, right away, we see something kind of cool. Const mouse position is equal to useMousePosition.
5. Tracking Mouse Position with Custom Hook
The speaker introduces a custom hook that tracks the user's mouse position and stores it as a state variable. They express their excitement about the simplicity and functionality of the hook, which provides real-time updates of the mouse position and includes automatic cleanup and tear-down. The hook's implementation showcases the power and convenience of using hooks in React.
I have this custom hook which does what we just talked about. It tracks the user's mouse position. It stores it as a state variable. Which means this component re-renders whenever the mouse position changes. And I've also snuck in the cleanup work. And even though I've been using hooks for like three or four years now, this still just seems so cool to me. It's one line of code that tells me not only what the mouse position is initially, but what it is at every moment in time as the user moves the mouse. And it also sort of magically bundles in the cleanup and tear-down work.
6. Reusability and Animation in React
Similarly, I have this line to get the bounding box. And this too has a bunch of stuff that we sort of alluded to. Like, I am actually doing my cleanup now. I'm also doing some debouncing so that it doesn't fire more than it has to. Because we're doing the cleanup work now, if this component gets unmounted and remounted, we're going to remove the event listener, disconnect the resize observer. And that means we avoid the memory leak of, like, stacking all of these event listeners every time the component re-renders.
Now, this works pretty well. It does occur to me, though, and I don't know how obvious this is, if I move very quickly. It's not super smooth. And that's because I'm not actually animating here. I'm not doing any sort of CSS transition or anything like that. It's a one-to-one mapping of the user's mouse position to the rotation of the egg and the translation of the eyes. If I want it to be, like, smoother when we do this kind of jerky motion, well, maybe we can use a CSS transition. Let's try that. I'll say transition equal to transform. I don't know, 500 milliseconds. Let's try that. I'm also going to comment out the eye transform, because I'm only going to worry about the head rotation. Actually, before I do that, I should finish showing how this code works. I drew this as an SVG in Figma, and then I copied the SVG. There are tools you can plug in your SVG code, and it gives you JSX. Honestly, it's pretty much the same, but you have to, like, this has to be, this is what it would be in an SVG, and you have to camel case it. So it's really cool, actually, that SVGs can be used in React like this. But that's a whole other point.
7. Smooth Motion with React Spring
The CSS transitions don't handle interrupts gracefully, causing frozen motion. To solve this, the speaker introduces React Spring, a library that smoothly interpolates CSS values using Spring physics. By using the animated helper, the SVG transform can be wrapped in an animated SVG component, providing smooth and organic motion. This solution requires minimal code changes.
I have the CSS transition now transformed in 500 milliseconds, and if I move in a very specific way, it looks okay. But if I keep moving, it's frozen in time. You might think maybe that's because this is the wrong value. Let's do 50 milliseconds instead. And this is even worse somehow. It's not good. And the reason for that is the CSS transitions don't handle interrupts, particularly gracefully. And so what's happening here is I'm re-rendering this code over and over whenever the user moves the mouse, and we keep starting and cancelling these CSS transitions. So I'm going to get rid of that. I'm going to bring back the Itransform, and I'm going to use a library. I'm going to use React Spring. So I'm going to import use Spring from React Spring. I'm also going to fix the typo. There we go. And I need this animated tool that I will explain shortly. What I'm going to do is I'm going to pass the CSS that I want to apply in this SVG transform into this function, and if the value goes from being like minus 10 degrees in one frame to plus 10 degrees in the next frame, it's going to smoothly interpolate and essentially give me a bunch of intermediate values. And it's going to do it using the beauty and magic of Spring physics. So the way that works, I'm going to call use Spring. I'm going to pass that object, and I'll do the same thing for the iTransform. And when I do that, it does not work at all. And the reason for that is that I've gone from taking a plain CSS set of a key and a value, this used to be a string, but use Spring produces a complicated interpolation object, and our humble SVG DOM node doesn't know how to deal with that. So that's where this animated helper comes in. I have to swap out this SVG for an animated SVG. And by the way, this doesn't actually change the DOM node. Either way, we're still going to get an SVG rendered in the DOM. What this does is it wraps it in a component that returns that underlying tag. But it also knows how to unpack those Spring values, and now, check it out, no matter how quickly I move the mouse, the motion is smooth, and it's just so, like, fluid and organic and delightful. I think. It is fun. I think the thing that's really cool about this is that think about how much code I had to change there.
8. Creating a 3D Egg Model with React3 Fiber
I took an existing object, wrapped it in useString, and appended characters to an SVG. With custom hooks, the complicated work is handled automatically, including cleanup and teardown. React's centralized process allows us to hook into rendering and unmounting. I had the idea to create a 3D model of an egg using Blender. Updating the code to render a 3D egg is not as difficult as it seems. The React3 Fiber library serves as a React renderer for 3D primitives, allowing for cursor tracking and movement in 3D space.
I took this object I already had, I wrapped it in useString, I took this SVG I already had, and I appended a few characters to the start of it. And like we saw with my custom hooks over here, all this stuff, all this complicated stuff happens under the hood. This takes care of the cleanup work, it takes care of the teardown work, and I get it for free. I don't even have to write this complicated-ish code to start with, I can just use this library, and it comes with all that stuff bundled in.
So this was where I was initially planning on ending the talk, but I had an idea. I thought, wouldn't it be cool if I could create like a 3D model of an egg in Blender? How much work would it be to update this code to render a 3D egg rather than the admittedly kind of crude two-dimensional SVG that I created? And the answer is that it's maybe not as much trouble as you might think. Hopefully the Wifi cooperates. Yeah, there we go. So it looks pretty similar. I can do the same sort of cursor tracking, but now it's a 3D model so I can move it in 3D space. It is very fun.
The way that this works is using a library called React3 Fiber. And if you're not familiar, it is essentially a React renderer for 3JS primitives. So like we have React DOM that renders divs and spans and inputs. Like we have React Native that renders whatever the primitives are in mobile. I don't know, I'm not a mobile developer. This is a renderer for 3D primitives. And so if we look, actually let's start here. With what I'm actually rendering, I have my 3D model stuff. I have a camera. I have orbit controls which is what allows me to do this. I have a light which we're going to talk about more in a second. And I have an environment. But check out how much of the code stayed the same. I'm using the exact same custom hook for getting the mouse position. The exact same custom hook for getting a bounding box.
9. Animating in a Different Environment
I'm using useSpring to animate the same thing. So much of this stays the same, even though we're rendering something in a completely different environment. The point light is animated, allowing for movement and creating different effects. All the stuff I'm doing here leverages the ecosystem and the long-running centralized processor. It's like a conductor in a symphony, making it all possible. React is a handy tool for this. If you'd like to see the code or join my newsletter, visit joshwcomo.com/summit.
I'm even using the same library. I'm using useSpring to animate the same thing. So my frantic cursor doesn't get super abrupt. So it's amazing to me that so much of this stays the same, even though we're rendering something in a completely different environment.
Now, I mentioned I wanted to talk more about some stuff down here. If I zoom way in, there we are. I imagine this looks pretty cool on the planetarium. You can kind of see that there's some texture being reflected in the eyes. That's coming from this environment.
If I get rid of it, and I'll zoom back out, we have this point light, which is, as it sounds, it's a light that is a point that emanates out in all directions, and I'm making it animated, which means if I scroll up over here, I can animate where the light is, which I just think is the coolest thing in the world. Like, if we wanted to, we could move the light underneath, and now it's like spooky story time, which is cool. Yeah, I think that's all I wanted to say about that. Making sure I'm not forgetting anything is always the challenge. So I think this kind of goes a little bit further to explain what I'm saying.
All the stuff that I'm doing here is leveraging this ecosystem, but it's made possible by the fact that I have this long-running centralized processor. It's a little bit like if you go to the symphony, all these individual musicians that are all playing their instrument, but you have this conductor, which is the one making it all possible. This is a little bit of a nod to Rachel's React head or React person. I forget what exactly, but yeah. So I do think it is a really handy tool for that reason. That's my talk. If you'd like to see any of the code that I mentioned, you can go to joshwcomo.com slash summit. I also have a newsletter you can join, and I'll be sending something a little bit interesting to that newsletter group in a few days related to the courses that I have. Thanks so much. Thank you. Thanks a lot, Josh. First of all, thanks. It was a lot of fun to see. It was my pleasure. Yeah, and as I mentioned to you before, I'm just going to talk over the time while I'm waiting for this stuff to load. I used to work in advertising and did a lot of this animation stuff back in 2013.
10. Fun with Open Source and Animation Packages
If a lot of people would get this assignment, they would be like, nope. Can't do it, right? And it's a lot of fun. I would advise all of you to just try and figure out, like, it is possible. And especially today, there's a lot of stuff that you can use that's open source. Any opinions on framer motion versus react spring or other animation packages? React spring is essentially like a fancy number generator. Like you give it two values, and it will give you all of the intermediate values, sort of like I showed over there, which means it's great in situations where you need a ton of control or you want to use a raw value in a very specific way. Framer motion on the other hand is absolute magic. It's a much higher level tool, and in part what it allows you to do is animate any sort of CSS value.
If a lot of people would get this assignment, they would be like, nope. Can't do it, right? And it's a lot of fun. I would advise all of you to just try and figure out, like, it is possible. And especially today, there's a lot of stuff that you can use that's open source.
And yeah, there's a lot of animation stuff you can do. If you're building a dashboard for Stripe, maybe it doesn't make that much sense. But if you have time, maybe you have a hackathon week. A lot of fun to do, right? I mean, that's like I mentioned, the philosophy with my blog is it's just a place where if I have some ridiculous idea that I would never be able to get approval from my manager to do it at work. Well, I have my blog. That's where I can indulge that kind of impulse. I can tether you from my computer. No, I got it now, yeah.
So what are some... No, this is still an old question. Old question. There's still a lot of old questions. Sorry, well prepared. Well prepared. This was Josh Goldberg, the other MC's responsibility. On behalf of all Joshes, I resent that. Yeah, sorry. Yeah, I thought I should clarify which Josh we were talking about. Any opinions on framer motion versus react spring or other animation packages? Yeah, this is a great question. So, to give a very brief summary of both of these tools, because they do similar things, which is animate using Spring physics, but they work in different ways. React spring is essentially like a fancy number generator. Like you give it two values, and it will give you all of the intermediate values, sort of like I showed over there, which means it's great in situations where you need a ton of control or you want to use a raw value in a very specific way. It also seems to handle interrupts even a little bit better than framer motion, although that's almost certainly because I'm using framer motion incorrectly. Framer motion on the other hand is absolute magic. It's a much higher level tool, and in part what it allows you to do is animate any sort of CSS value. Like for example, if you have flex box, and you have an element that starts being justified at the start, and you set justify content flex end, and it moves to the other side, if you throw a CSS transition on that, it won't work.
11. Animating with Framer Motion and React Spring
Framer Motion allows for animating any CSS property by figuring out two positions and smoothly animating between them. It is a high-level tool that is more powerful than React Spring. However, React Spring is still useful for smoothly animating specific CSS values. The choice between the two depends on the project's requirements. If performance is not a major concern, React server components can be used for internal tools.
That's not an animatable property. But with framer motion, it does work. The way that it works is it figures out the two different positions, and it sort of moves it to the end position immediately but then teleports it back to the original position and smoothly animates. It sounds confusing when I describe it, but essentially it allows you to animate pretty much anything, like based on any CSS property. And it's not even that it's like the library took specific action to support flex box, because if it did, then it might make you worry it won't support like CSS grid or anything else. It works on a much different principle, which is just whenever this thing moves in the page for any reason, figure out the two positions and animate between them.
So it's absolute magic, it's incredibly useful, but it's a very high-level tool. It's kind of unfortunate, because both Framer Motion and React Spring are kind of large, like they're both in the 20 to 40 kilobyte range, so it feels a little bit silly to have both of them. But in a world with React Server Components and with streaming server-side rendering, that's less of a concern to me, because you can get all the UI there right away. And even if the animation takes a little bit longer to load, that's fine, usually. So they're both really powerful. I'd say, in general, Framer Motion is, like, if I was going to pick one, it would be Framer Motion, just because it's so much more powerful. Like, it can do things React Spring can't do, and the reverse isn't necessarily true. But React Spring is still really nice in cases where you just have, like I showed here. I just want to have these two values, the CSSTransformRotate, and I want it to smoothly animate from this value. It works really well for that.
Yeah, and don't shoot me when I say this, but it also really depends, you mentioned that it can become too big to use in both, but it depends on what you're building. If you're working in advertising, the websites I built all have preloaders. Like, people were waiting for 30 seconds, 40 seconds to see my animations. I actually, the first thing I built at this advertising agency had a preloader for the preloader because the preloader animation was so big. But it was amazing. It was super fun to build. Totally. And I was going to say this during the panel, you know, because there was that question in the panel around, if you're building an internal dashboard for the company, is it worth using React server components? And I do think it is. But I think that question is phrased from the perspective of, does the performance matter in the same way that it does for an e-commerce site where you have a second to get everything ready? Otherwise, the person is going to click the back button and go to the next search result. You're searching for to buy a new futon. You don't necessarily need this particular result. That's like the biggest example of where performance really matters in terms of the time to first paint, to interact with all the different measurements that you have. And so yeah, exactly. If you're building something, an internal tool, it's actually not as important that it loads super quickly because it's not like you're visiting your Stripe dashboard.
React Server Components and Libraries
It's not loading quickly enough. I'm going to go sign up with a different merchant. There's a lot of other reasons that React server components are cool. The giant 3D egg will take your soul. Do you miss ActionScript? How do you find these libraries? Whether you choose React Spring or Frame or Motion, they're both super powerful tools. Have you ever used GSAP within a React application? I haven't.
It's not loading quickly enough. I'm going to go sign up with a different merchant. It doesn't really have the same impetus. But there's a lot of other reasons that React server components are cool. So I don't want to use that as a reason not to use RSC.
So the next question, I'm not sure if it's a question or more of a statement, but... Oh, those are the best questions. Yeah. The statement is the giant 3D egg will take your soul. So just so you know, people are scared. This is the best question ever.
Do you miss ActionScript? So I did some Flash animations. I never did any Flash scripting. So I never used ActionScript. I think I was missing out though. You did. Go to and learn was a nice resource. Oh man, I missed those days. All right.
How do you find these libraries? I mean, I do think, and this sort of gets to what I was saying in the talk, it is just so, so powerful that because they're hooked into React, you can do so much in such a small amount of code. I do think we're a little bit spoiled when it comes to, like, our ecosystem. Like I mentioned, there's plenty of good tools. Svelte has a bunch of other stuff built in, which is really cool. GSAP is a great library as well. But really, I have no complaints. I think that, whether you choose React Spring or Frame or Motion, they're both super powerful tools. And you can do a lot with those tools. I guess you really have to go deep down this rabbit hole to get to the point where the tools that we have aren't able to do what you want to do.
Have you ever used GSAP within a React application? I haven't. It's been on my to-do list for a long time.
Building Whimsical Animations in Dashboards
The speaker discusses the use of tools and the React ecosystem for building whimsical animations. They mention the possibility of using GSAP and the need for cleanup using useEffect. The speaker suggests starting with charting libraries for building whimsical animations in dashboards, highlighting the communication value of animations and their ability to convey information more effectively than text.
But like I say, the tools that I have are already totally proficient. So I haven't felt the urgency to see what else is out there. Yeah, I would assume you can just use a ref, and then pass that along to GSAP and it should work. I don't know GSAP enough to know. But how does a cleanup work? You might have to throw a use effect in there to make sure that you stop the animation if the component unmounts mid-animation. Maybe. I don't know. Which is just what's so nice about the React ecosystem is that it's all hooked in.
I click the lock button. All right, we ask this one. We have time for one more question. And that's an old question. All the questions. Right, it's all old questions. I don't have time to filter them. But so if there's anyone here and says, I'm building dashboards normally, but I want to build some whimsical animation in there. Where can they start? Yeah, and it's funny because I used the Stripe dashboard as an example. Like, there isn't much whimsy there, but there could be. Like, you wouldn't want the same things. One opportunity is in, like, charting and graphing. Like, if you have any sort of graph, it's not even really functional at this point, right? Having a transition between updating a graph is useful because it gives you the context. This is something actually Rachel Neighbors has talked about a lot. Animation has a bunch of different purposes. One of those purposes can be whimsy, like just superfluous fun things. But there's a ton of communication value, right? Certain animations help you understand things because in reality things don't teleport the way that things often do on the web. You have this smooth interpolation that gives you the context to follow something. A lot of times, like, an animation can do the same work as a paragraph of text to explain something. And it does it way better because text is, you have to unpack that in your mind. The animation, you can just see it. So, yeah, I think if you're building a dashboard, charting libraries is a great way to start finding places where the transition from one thing to another can be smooth by motion. It's a good place to start. Yeah. All right. Sounds like a plan. So, everyone, let's get started with some whimsical animations after we've given Josh a warm round of applause. Thank you.