Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

autoplay and loop don't seem to work in svelte #246

Open
rjwalters opened this issue Oct 13, 2023 · 6 comments
Open

autoplay and loop don't seem to work in svelte #246

rjwalters opened this issue Oct 13, 2023 · 6 comments
Assignees

Comments

@rjwalters
Copy link

I am trying to migrate from @lottiefiles/lottie-player but I am having trouble getting autoplay to work...

<script lang="ts">
  import { onMount } from 'svelte';
  let lottiePlayerReady = false;
  onMount(async () => {
    await import('@dotlottie/player-component');
    lottiePlayerReady = true;
  });
  let lottieSrc =
    'https://lottie.host/13489d72-9fb8-47e8-94b9-42d1c880647b/zMLtJHw8sJ.json';
</script>

{#if lottiePlayerReady}
  <dotlottie-player
    src={lottieSrc}
    autoplay
    loop
    style="width: 500px"
  ></dotlottie-player>
{/if}

if I include the controls, I am able to play and loop the lottie. A workaround is to trigger play when I receive the ready event:

  onMount(async () => {
    await import('@dotlottie/player-component');
    lottiePlayerReady = true;
    await tick();
    const lottiePlayer = document.querySelector('dotlottie-player');
    lottiePlayer.addEventListener('ready', () => {
      (lottiePlayer as any).play();
    });
  });
@dhruv-m1
Copy link

dhruv-m1 commented Oct 15, 2023

Faced the same issue (using Svelte island on Astro), thanks for the workaround @rjwalters

The problem seems to be with autoplay. (Edit: loop works on an Astro Island using Svelte, but not with Svelte alone)

If anyone else has multiple animations to deal with, you can extract dotlottie-player into a separate svelte component like so:

<script>

    import { onMount } from 'svelte';

    export let play = true;
    export let loop = true;
    export let mode = 'normal';
    export let controls = false;
    export let src;

    let player;
    onMount(async() => {
        player.addEventListener('ready', () => {
            if (play) player.play();
            player.setLooping(loop);
        });
    });
    
    
</script>
    
<dotlottie-player bind:this={player}

    src = {src}
    mode = {mode}
    controls = {controls}
    worker = true
>
</dotlottie-player>

Edit: Just to add this issue was not there in version 1.4.2.

@Djules
Copy link

Djules commented Oct 16, 2023

Hi, I faced the same issues in Vue 3 project, the attributes were handled as prop instead of attribute, although the <dotlottie-player> element was declared as CustomElement.

I don't know Svelte (yet) but I figured this out by "forcing" Vue to use attributes as they are, with .attr modifier, something like:

<dotlottie-player src="/lottie/loader.lottie" :autoplay.attr="true" :loop.attr="true" />

@Djules
Copy link

Djules commented Oct 17, 2023

Maybe some solutions for you in this article.

@theashraf
Copy link
Member

@rjwalters We're investigating this issue. Thank you.

@Djules Regarding the Vue usage, you can find a guide here that might help: https://docs.lottiefiles.com/dotlottie-players/components/player-component/usage/vue

@theashraf theashraf self-assigned this Oct 17, 2023
@GregSharp-app
Copy link

GregSharp-app commented Oct 31, 2023

This fixed it,

<script>
function setAttrLottie(node) {
	node.setAttribute('autoplay', 'true');
	node.setAttribute('loop', 'true');
}
</script>

<dotlottie-player
	use:setAttrLottie
	mode="normal"_
	src="..."
/>

@dhruv-m1
Copy link

dhruv-m1 commented Oct 31, 2023

Yes, @GregSharp-app - that's the current workaround.

If you have multiple animations with different requirements for autoplay and loop, you can use this more generic function:

<script>
  const setLottieConfig = (player, config) => {
    Object.entries(config).forEach(([key, value]) => {
      player.setAttribute(key, value);
    });
  };
</script>
    
  <!-- 

    setting autoplay, loop to false does not work,
    don't include them at all if you want them to be false.
  
  -->

  <dotlottie-player 

    use:setLottieConfig = {{
      autoplay: true,
      loop: true,
      mode: 'normal',
      src: "...",
    }}

  />

This involves DOM manipulation, which might lead to some performance issues if you have a lot of animations.

If you don't want to do DOM manipulation, you can make a component for lottie animations like so:

<script>

    import { onMount } from 'svelte';

    export let play = true;
    export let loop = true;
    export let mode = 'normal';
    export let controls = false;
    export let src;

    let player;
    onMount(async() => {
        player.addEventListener('ready', () => {
            if (play) player.play();
            player.setLooping(loop);
        });
    });
    
    
</script>
    
<dotlottie-player bind:this={player}

    src = {src}
    mode = {mode}
    controls = {controls}
>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants