Rin and Len
Rin and Len

Reputation: 517

How to use Svelte transitions with a click function instead of inline?

I want a simple animation/transition in Svelte. Basically, you click a button, a "ghost of the button" or the button itself rises up and fades into the ether, then returns to its original position if it was the button itself that animated.

<script>
    import { fade, fly } from 'svelte/transition';
    import { cubicOut } from 'svelte/easing';
    import { tweened } from 'svelte/motion';

    export let onAdd;
    export let onSubtract;

    let coords = tweened({ x: 990, y: 900 }, { duration: 500, easing: cubicOut });

    let handleClick = (e, handler) => {
        console.log('e is for egg: ', e);
        coords.set({ x: e.clientX, y: e.clientY });
        handler();
    }

</script>

<div class="plus-minus-btns">
    <button
        class="btn btn-circle"
        on:click={(e) => handleClick(e, onSubtract)}

        >
        <svg
            xmlns="http://www.w3.org/2000/svg"
            class="h-6 w-6"         
            viewBox="0 0 24 24"
            stroke="currentColor"
            role="presentation"
            use:fly={{ x: 1300, y: 1500, duration: 2000 }}
            use:fade={{ duration: 5000 }}
        >
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 12H4" />
        </svg>
    </button>  
[ all the same code for an ADD button]  
</div>   

AI helped me come up with this gibberish, but only after I had tried A LOT by myself. I don't think I need either cubicOut or tweened, just fade and fly.

My issue is, I don't want to repeat the SVGs with duplicate animated ones. I want to click the button and have the "ghost" or even the button itself animate (either is fine at this stage).

The documentation I am struggling with. it has all HTML elements in [#if condition] but I want the button to always be visible.

I tried making a copy of the button/SVG and layering it beneath this one, which sort of worked, but the positioning is hard to get right on flex, and it results in a lot of duplicate code (the entire button & svg etc).

So basically this but from a click!

<script>
    import { fade, fly } from 'svelte/transition';

    /**
     * @type {OnAddHandler}
     * @type {OnSubtractHandler}
     */
    export let onAdd;
    export let onSubtract;

</script>

<div class="plus-minus-btns">
    <button
        class="btn btn-circle"
        on:click={onSubtract}
        in:fly={{ y: 200, duration: 2000 }} 
        out:fade
        >
        <svg etc etc

Yes I am having one of those days were I can't think clearly through the problem, need to drink more water.

Upvotes: 0

Views: 513

Answers (1)

brunnerh
brunnerh

Reputation: 185553

Svelte transitions are for incoming/outgoing elements that are added/removed by #if or #each.

If you just want to animate between different states, I would recommend conditionally adding a class and using a standard CSS transition.

Upvotes: 0

Related Questions