Search code examples
sveltesvelte-3

Tweened component prop


I have this CircularProgressBar.svelte component and I want to animate when the percentage changes. This is how CircularProgressBar.svelte is defined:

<script>
    import { onMount } from "svelte";

    /**
     * @type string
     */
    export let percentage

    // ...other props...

    // Make sure that it doesn't get created again
    onMount(() => {
        console.log("I was created!");
    });
</script>

<!-- some html -->

<style>
/* some gradients */
</style>

And that's how I use it:

{#each pump_data as pump, i (pump.id)}
    <tr class={i % 2 === 1 ? 'bg-gray-100' : ''} animate:flip>
        <td class="text-center">{pump.id}</td>
        <td class="text-center">
            <CircularProgressBar percentage={pump.percentage} /> {pump.display_time}
        </td>
        <td class="text-center">{pump.medication}</td>
        <td class="text-center">{pump.type}</td>
    </tr>
{/each}

What I want to do is, when percentage changes from 66 to 67 for example, to use something from svelte/motion like tweened. I've verified that the components doesn't get created again but, instead, only that value changes (or, at least, i think)

Is there a way to do something like onPropValueChange() or something like that?


Solution

  • You don't need anything like that. Just create a reactive statement.

    const animatedPercentage = tweened(...);
    
    $: animatedPercentage.set(
      percentage,
      { duration: 500, easing: ... },
    );
    

    Animation properties can also be set as part of the defaults if they are static, then you can also use $store instead:

    $: $animatedPercentage = percentage;
    

    Incidentally I created something like this before.