Introduction to Tweening in Svelte
In this video, I want to animate these poll bars right here as the values change. We're not really transitioning the bars in and out of the page; we're just animating them from one value to another. So we're not going to use transitions for this like we did in the last video when we transition a poll in and out of the page.
Instead, we're going to use something known as tweens or tweened stores. Now, tweening is the process of generating frames for our movements. Now Svelte has a tween store built-in that we can use, and that generates a series of values which can be used for each frame between a starting and an ending point so that we get a smooth transition of values rather than a quick jump from A to B.
A Simple Tweened Store Demonstration
Okay, so I've prepared a quick demo of this before we move on to these bars, and that is in the App component right here. So first of all, I've imported tweened from svelte/motion. And tweened is a bit like a store, like writable. We pass in the initial value right here which I have set to zero, and we can store that in this thing right here, value.
Now down here, I've got a button and inside that button what we output is this value. Remember this is kind of how we subscribed automatically to a store. We placed the dollar sign before the store itself. That's kind of what we're doing here, right? We're just placing the dollar sign before the tween store right here, value, so that should output the value of value.
Right now what I'm doing is also attaching a click event to this button and inside this click event, we're firing a function which takes the value and then we use a method on it called set and we're replacing whatever is currently the value as 1, so 0 to 1. Now in a store, that would just replace 0 with 1 straightaway like this with a click. Now in our case, we're using a tween store so it transitions from 0 to 1. So we get a range of different numbers over time transitioning as the value and that value is over time being output inside the button. So let's take a look at this in action. So let's see it. Currently it's zero because that is the beginning value. If we click on this though, you'll see it transition to one. It doesn't go straight to one, it transitions.
So that's essentially what we want to do with these two values. Say we have a width of 28% on one of these bars and we click it and it goes to a width of something like 35%. Instead of it just jumping to that new value straight away and we get this kind of jump effect in the bars, I would like it to transition between those two values from 28 to 35, or from 0 to 100 dependent on what the votes are, right? So that it slides up the width because the width value is constantly changing that percentage. So let's do that.
Implementing Tweened Stores for Poll Percentages
First of all, let's delete these things right here, these tween things and this button and let's apply the same kind of thing inside the PollDetails component right here. So what I'm going to do first of all is I'm going to import tweened from that same thing. So let me do that at the top from svelte/motion. So we've imported that first of all.
Then down here underneath these reactive values, I'm going to do another comment and that says 'tweened percentages', right? So the percentages are the things that we wanted to tween that we want to change over time because ultimately the width is dependent on that. So if this is changing smoothly over time, then we'll get a slide effect rather than jumping from one width percent to the next.
So down here the first thing I'm going to do is create a new const called tweenedA. So this is going to be the percentA tween and I'm going to set that equal to tweened and it's going to begin at 0. Right, now the second thing I want to do is say const tweenedB and set that equal to tweened and then that starts at 0 as well.
So now I want to create some more reactive values and when the percentage changes right here of A or B that's when I want to update the tweened value of tweenedA, right? So let me now say dollar sign colon tweenedA and we need to say .set() and we're going to update the value in this tween store and that's going to be percentA. So remember this reactive value is going to update on this reactive statement, rather, is going to run when this thing right here that it depends on changes. So whenever percentA changes we're going to run this statement which sets tweenedA from zero to begin with to its current percentage.
Now when we first begin when we first load these things over here it's going to go from zero to begin with with the percentage it starts with and it's going to tween from those values, right? But then the new value of tweenedA right here is going to be something else, maybe 25%. So then when we click on it, it's going to tween from that to the new percent. So these automatically work out. I hope that's making sense. So I want to do the same thing now for B. So tweenedB.set(percentB). So whatever percentB changes up here then we're going to re-tween this thing right here from whatever the starting point is to the new percentage and so forth.
And then finally what I'm going to do for now is also do another reactive statement which is going to console.log($tweenedA) and $tweenedB. So we need the dollar sign first of all to get the value that automatically subscribes, remember? tweenedA which is this thing and then tweenedB, so $tweenedB like so. So now whenever these two values change we're logging them to the console so we should see their progression. So now let me go over here and let me just get rid of those to begin with. And I'm going to click on this and you'll see now the percent has tweened from 37.25 all the way to this value right here, 40 and 60, right? And that's A and B. So the percentage changes for both because if we up the vote of one of them, the percent of the other goes down. So now we've animated to 42 and 57 and now it should be animating to 44 and 55, right? Not animating but tweening the values, the percentage values.
Applying Tweened Values to the UI
So now we have access to these tweened values, we can output those as the width right here instead of the actual percent because now these are going to be constantly changing when we go from A to B. They'll be smoother. So I'm gonna comment this line out because we don't want to log those to the console every time, but now I'm gonna change this to $tweenedA and this one to $tweenedB. Save it and come over here.
And now if we refresh to begin with, we can see they go from zero to their current percentages and if we click on these and vote, now they animate between to their new positions, which is much better. If we add a new poll over here and click that, and in fact we'll add a new one, 'Do you like Mario?'. Who doesn't? 'Hell yeah' and 'Not for me'. Add a poll and now if we click on one of these then you're gonna see... oops, that didn't tween. Hmm.
Fixing the "NaN" Bug for New Polls
And that's because there is a slight problem. So let me just try this again. Add a new poll and let me go from here from zero to the new value. Now it didn't tween. And that's because when we first create a poll, the poll votes A is going to be zero, right? And the total votes is going to be zero. So when we're trying to work out the percents, this is going to give us not a number because we're trying to divide 100 by zero then times it by zero. So this is an invalid number.
So what we should do is place a double pipe here, a logical OR, and if this then is undefined or rather not a number, then it's gonna apply this value to percentA instead. So zero there as well. And now for new polls we're going to tween from zero to whatever the new value is when we click on it instead of from some kind of undefined or not a number, right? So let me save that now and try that again. So add a new poll, this hopefully should work. And now if we click on this, yep, now it transitions. Alright, it animates between the two now. Awesome.
Conclusion and What's Next
So that is tweening. Have a play around with it and I'm sure you'll grasp it in no time. And that my friends is pretty much it. So in the next video, we'll have one more test of this application and I'll also talk about what other tutorials on Svelte are coming up in the future.