Search code examples
storesvelte-3tween

Tweening Paths With Svelte, D3, and Svelte Motion


I have a question regarding svelte animation and tweening paths. Here is a repl with the code https://svelte.dev/repl/b2509f1cfff54ee5856db44997f6fe53?version=3.53.1

I have

<script>
    import { draw } from "svelte/transition";
    import { tweened } from 'svelte/motion'
    import { interpolateString, interpolateLab, interpolateTransformCss } from 'd3-interpolate';
    import * as easings from 'svelte/easing';
    import * as d3 from "d3";
    import {path1} from './paths.js';
    import {path2} from './paths.js';
    import {path3} from './paths.js';
    import {path4} from './paths.js';
    
    let paths_1 = [
        {id: "google", path: path1},
        {id: "(direct)", path: path2}
    ]
    let paths_2 = [
        {id: "google", path: path3},
        {id: "(direct)", path: path4}
    ]
    let width = 800;
  let height = 400;
    
    let selected_path = paths_1;
    function select(path) {
        selected_path = path;
    }
    
    // animated copy of points
    let animated_path = tweened(null, {
        interpolate: interpolateString,
        duration: 1000,
        easing: easings.cubicOut
    })
    
    $: animated_path.set(selected_path);
</script>


<button on:click|preventDefault={() => select(paths_1)}>
    Path1
</button>
<button on:click|preventDefault={() => select(paths_2)}>
    Path2
</button>

<svg {width} {height}>
{#each $animated_path as {id, path}}
    <path 
            stroke="black"
      d={path}
      />
{/each}
</svg>

<style>
    path {
        fill: none;
    }
</style>

But the paths are just disappearing and then the other ones are popping in again instead of making a nice transition.

I made it work with one path transitioning in this repl: https://svelte.dev/repl/560b12831bea443a84b861ce756b3a98?version=3.53.1

and looked up how to do the tweening from this one: https://svelte.dev/repl/b4c485ee69484fd8a63b8dc07c3b20a2?version=3.4.1


Solution

  • Try to use the interpolator from flubber

    import { interpolate } from "flubber"
    // animated copy of points
        let animated_path = tweened(null, {
            interpolate: interpolate ,
            duration: 1000,
            easing: easings.cubicOut
        })