Check out a free preview of the full Svelte course:
The "Animations & Actions" Lesson is part of the full, Svelte course featured in this preview video. Here's what you'd learn in this lesson:

Rich demonstrates adding animations for animating element position within the page.

Get Unlimited Access Now

Transcript from the "Animations & Actions" Lesson

[00:00:00]
>> We need to talk about animations, which is similar to transitions. But instead of relating to elements that are entering or leaving the DOM, animations apply to things inside each block when the number of items in each block, or the contents of each block, changes. So this is set up as it was at the end of the last chapter.

[00:00:21] If I total that, it's gonna move over. But we wanna add something that called a FLIP animation. FLIP stands for first, last, invert, play. And it's a technique that you can use to smoothly animate element from its old location to its new location by doing some measurements and applying a CSS transition.

[00:00:47] It essentially reverses the movement and then lets it undo itself so that the DOM ends up in its final state. Import { flip } from 'svelte/animate'. And then we're gonna find the the label where we added those send and receive transitions before. Down here, I'm gonna add, animate:flip.

[00:01:20] And we'll do the same thing on the other label. And now if I toggle this, Right, some boxes are gonna move over to the other side of the screen, but the other four items will, hopefully, gracefully move into their new location. And there we go. Just like with transitions, we can add a duration parameter, So that everything is a little bit snappier.

[00:02:17] And the duration parameter can also be a function that receives, as its argument, the number of pixels that the element has to move. So that an element that has to move further will take longer to do so than a element that only has to move a few pixels.

[00:02:32] And again, all of this stuff is being done with CSS animation, so it won't get blocked by the main thread. So, earlier, we talked about component lifecycle, unmount, beforeUpdate, afterUpdate, and onDestroy. But we also have a way of dealing with element lifecycle, and we call those actions. Actions are essentially element-level lifecycle functions.

[00:02:56] And they're really useful for things like interacting with third party libraries, lazy loading images, doing tool tips or adding custom event handlers. In this app here, we want to make this orange box pannable. And on the box, we have a bunch of event handlers for events that don't exist.

[00:03:15] panstar, panmove and panend, right? These are not native DOM elements. So we need to dispatch those somehow. And the way that we're gonna do it is by importing this pannable action. And then we're gonna make this element a pannable element, by which I mean that it will dispatch these panstart, panmove, panend events by adding use the pannable action.

[00:03:55] Now, nothing happens yet because we haven't implemented the pannable function, but we can do that. I'm just gonna copy and paste this whole thing in because you don't want to sit here and watch me type it Let's walk through it. So we're creating some local state inside the action.

[00:04:13] And then we're creating a few different event handlers, a mousedown handler, a mousemove handler, and a mouseup handler. Then we're adding the mousedown handler, which in turn is responsible for adding the mousemove and the mouseup handlers. And then at the end of the action, we return this object that has a destroy function, which does any cleanup that's necessary once the element gets removed from the DOM.

[00:04:36] And so now, hopefully, fingers crossed, as I drag this around, the element is now pannable. And because it's just a function, this is something that you can import into any component, and you can use it in multiple different places. So you can imagine building a library of actions that you need to use frequently in your application.

[00:04:58] Don't use this implementation of pannable, because this is really for demo purposes only. If we were doing it for real, then you would need to also handle touch events. And this only handles mouse events at the moment. Just like with other directives, we can add parameters to actions.

[00:05:19] So this is a longpress action that's been applied to this button. use:longpress means that when we hold the trackpad down on the button for a long period of time, a longpress event will get fired. And that's implemented like this, what we want to do is make it possible to customize the duration of the longpress.

[00:05:46] So that, Your application, if you want a longpress to be considered after 300 milliseconds, then you can do that using the same action as someone who wants a longpress to be considered only after 1500 milliseconds. And we can do that by allowing the action function to take the second argument, duration, and using that inside our setTimeout.

[00:06:13] At the moment, it's hard coded to 500, which means that, We get the event after 500 milliseconds of holding the mouse down. Change that to duration, and then now it will only fire after 2000 milliseconds. I've done it wrong. I haven't actually passed in the duration from the action.

[00:06:41] I need to add that here. So now when I press this, It'll make you wait for 2000 milliseconds. Now if I turn this all the way down to 100 milliseconds, It still takes 2000 milliseconds because the action doesn't know that that value has changed. But we can add an update method to our action that receives the new value, And merges it with our local state.

[00:07:24] So now, 2000 milliseconds, If I take this down to 200 milliseconds, It fires almost immediately.