element to the value of the corresponding item in the array.
As a result, we have a horizontal bar chart displaying 10 bars with randomly generated widths.
To make things more engaging, we will update the values of the bar chart at fixed intervals:"," import { onMount } from 'svelte';"," onMount(() => {"," const intervalId = setInterval(() => {"," data = generateData(10);"," }, 1000);"," return () => clearInterval(intervalId);"," We initiate an interval of 1 second using setInterval as soon as the component is mounted. On"," each interval, we update the data by regenerating it with generateData(10)."," With this new code addition, you’ll observe that the horizontal bars alter their width during each"," interval. The width of the horizontal bars adjusts suddenly, creating a jarring visual effect."," Now, let’s utilize the tweened store to make the bars grow or shrink smoothly every time the"," data changes:"," 1. First, let’s import the tweened store from svelte/motion. We’ll then wrap the data array
with the tweened store. As shown in the previous section, we can pass an array of numbers
to the tweened function to create a tweened store. This store will smoothly transition each
number in the array independently when updated:
import { tweened } from 'svelte/motion';
const data = tweened(generateData(10));
\f Examples – creating an animated graph with the tweened and spring stores 197"," 2. Now, since data is a Svelte store, we need to update its value using the $data variable instead
when making changes:
$data = generateData(10);"," 3. Similarly, when we want to iterate through the store value of data in the {#each} block, we
need to use the $data variable as well:
{#each $data as value}","Putting all these changes together, you will now observe that the horizontal bars grow and shrink
smoothly, greatly improving the visual appeal and user experience of the bar chart.
As you can see, creating a smoothly animating chart using the tweened store is quite straightforward.
Before we move on to the next section, we encourage you to try this on your own: replace the tweened
function with spring and observe the changes in the animation.","Exercise – creating an animating line graph","Now that you’ve seen how to create an animating bar chart, it’s time for you to have a shot at creating","an animating line graph.","You can use the d3-shape library (https://github.com/d3/d3-shape), which offers a","convenient line method that generates an SVG path based on an array of items. Here is an example","of using the line method:"," const pathGenerator = line().x((d, i) => i).y((d) => d);"," const path = pathGenerator(data);","In the preceding code snippet, we utilize the line method to create a pathGenerator function,
which generates an SVG path by mapping the array’s values to the y coordinates. You can create a line
graph by using the returned SVG path with the
element in an SVG.
Once you’ve completed your implementation, feel free to compare your results with our example
at https://github.com/PacktPublishing/Real-World-Svelte/tree/main/
Chapter12/02-line-chart. Good luck and have fun experimenting with your animated
line graph!
After familiarizing ourselves with using the tweened and spring stores with numbers, arrays, and
objects, it is now time for us to incorporate non-numeric values. This will be achieved through the
creation of custom tweened interpolators, which we will explore in the next section.
\f198 Stores and Animations"," Creating custom tweened interpolators"," Sometimes, you may want to transition between non-numeric values, such as colors. Fortunately, this"," doesn’t prevent us from using the tweened store. The tweened function offers an option to define"," custom interpolation between two values."," In this section, we’ll explore how to create a custom interpolation to smoothly transition between"," two colors."," But what is interpolation?"," When transitioning between two values, interpolating means generating intermediate values between"," the values, to create a smooth transition."," For example, consider a tweened store initialized at 0, and we set it to 100. The tweened store"," generates intermediate values between 0 and 100, such as 20, 40, 60, and so on, while updating the"," store value with these intermediate values. As a result, during the transition from 0 to 100, the store"," value smoothly changes, providing a visually appealing progression from 0 to 100."," This process of generating intermediate values is known as interpolation."," The default tweened store is capable of interpolating between two numbers, two arrays of numbers,"," and two objects with numeric property values. However, it doesn’t know how to interpolate between"," two colors. In such cases, we can pass a custom interpolation function when creating a tweened store."," The function signature of the tweened store interpolation looks like this:"," function interpolate(a, b) {
return function (t) {
// calculate the intermediate value between 'a' and 'b' based on
't'
};
}"," In this function, a and b represent the starting and ending values, while t is a value between 0 and
1 indicating the progress of the transition. The interpolate function should return another
function that calculates and returns the intermediate value based on t, the progress of the transition.
For example, an interpolate function that interpolates between two numbers linearly looks like this:"," function interpolate(a, b) {
return function (t) {
return a + t * (b – a);
};
}
\f Creating custom tweened interpolators 199","The interpolate function returns another function that takes a progress value, t, and calculates
a linear interpolation between a and b based on the t value. When t is 0, the function returns a,
and when t is 1, it returns b. For values of t between 0 and 1, the result is proportionally between a
and b.To create an interpolation function for colors, we could break the colors down into individual
red, green, and blue (RGB) components and interpolate each of the components separately. After
interpolating each component, we could then recombine them to form the intermediate color.
Alternatively, we could use a library that has already implemented such interpolation. A good example
of such a library is d3-interpolate (https://github.com/d3/d3-interpolate). By
using a well-tested library such as d3-interpolate, we can save time and ensure that our color
interpolation is accurate and efficient.
Here’s an example using d3-interpolate:"," import { interpolateRgb } from 'd3-interpolate';"," function interpolate(a, b) {"," const interpolateColor = interpolateRgb(a, b);"," return function (t) {"," return interpolateColor(t);","In the preceding code snippet, we import the interpolateRgb function from d3-interpolate,
which returns an interpolator function for the colors a and b. We then create our custom interpolate
function, interpolateColor, which returns a function that calculates the intermediate color
based on the progress, t.
To use our custom interpolate function when creating a tweened store, we can pass the
interpolate function in the second argument:"," tweened(color, { interpolate: interpolate });","And that’s it; you can now create a tweened store for colors that can smoothly transition between them.
You can find a code example of using color interpolation on GitHub at https://github.com/
PacktPublishing/Real-World-Svelte/tree/main/Chapter12/04-interpolation.
By now, you’ve learned how to use a tweened store to create animated graphs and how to transition
between non-numeric values using a custom interpolate function.
Let’s explore more examples using the tweened and spring stores to create fluid user interfaces.
\f200 Stores and Animations"," Examples – creating an animated image preview"," In this example, we’ll create an image preview feature that allows users to view a larger, more detailed"," version of a thumbnail image when they click on it, enhancing the user’s visual experience and allowing"," them to inspect images more closely."," While building this feature, you’ll see how we can utilize the spring store to create a more fluid"," and natural user experience, making the transitions between images and their larger previews feel"," smooth and engaging."," To begin, let’s create a list of images that will be displayed on our page:","
{#each images as image, index}
{/each}
"," In this example, we create an array of images containing the paths to our image files. We use the
{#each} block to loop through the images and create a element containing an
![]()
element for each image.
In the preceding snippet, the