Playing a Lottie file on a button click

Hi Folks

With my limited understanding of javascript I managed to load a LottieFile and play it on mouse click done on the Lottie container itself (have a look at the container inner html).

However, I want to play the animation on clicking the 'Play' button below the animation and that's where I'm struggling.

Any help/guidence will be greatly appreciated. Also, suggestions for other workflows are also welcomed!

Project file:
Play_lottie.zip (85.8 KB)

Thanks
Greg

There's a couple slightly different ways to tackle this; I'll present the most "Hype"-centric way to do it.

First, the basic solution you will need is to add an On Click handler to the Play button that executes the code to play the lottie file. In the Inner HTML of your lottie Rectangle, you can see this code within the "click" callback:

  if (animationCompleted) {
    animation.goToAndPlay(0, true);    
    animationCompleted = false;
  }

Second is that this code by itself won't work; variables like "animationCompleted" and "animation" are in a different scope and not defined to be accessed in a Hype event handler. Any basic solution needs to solve for this.

The way I'd tackle it would be:

  1. Move the <script> code in your lottie Rectangle into an On Scene Load handler
  2. Modify the On Scene load code to store variables that need to be accessed in different functions in the hypeDocument.customData field.
  3. Make a the on click function that uses these variables to play the code. (we can even change the lottie animation's own "click" handler to call this so we don't have repeat code).
  4. Remove the remaining inner html "container" div so it is entirely empty, and just set the ID and class directly in Hype's Identity Inspector

Ultimately, the On Scene Load javascript would look like:

	let container = hypeDocument.getElementById("container");
	hypeDocument.customData.animationCompleted = true;
	
	hypeDocument.customData.animation = lottie.loadAnimation({
	  container: container,
	  renderer: 'svg',
	  loop: false,
	  autoplay: false,
	  path: 'https://assets9.lottiefiles.com/packages/lf20_rcuthdnb.json'
	});
	
	hypeDocument.customData.animation.addEventListener("complete", () => {
	  hypeDocument.customData.animationCompleted = true;
	});
	
	container.addEventListener("click", () => {
	  hypeDocument.functions().playLottieFile(hypeDocument, element, event);
	});

(I removed the "DOMLoaded" handler, since it isn't necessary how this is loaded)

And then the On Click handler for the Play button looks like:

	if (hypeDocument.customData.animationCompleted) {
		hypeDocument.customData.animation.goToAndPlay(0, true);    
		hypeDocument.customData.animationCompleted = false;
	}

Here's the file I used to test:
Play_lottie-fixed.hype.zip (81.5 KB)

Hope that helps!

2 Likes

Thanks Jonathan!

I came up with the first solution but I like the second option too.

Thanks for your help

1 Like

Hi Jonathan

Would you happen to know how to bounce the Lottie animation so that it plays back and forth?

There is mode: bounce if you include the animation using the website generated script but I cannot find anything on how to bounce the animation by loading it like we did in the Hype document.

Any pointers will be greatly appreciated.

Since I dod not know where you are referring to ??

Is this effectively what you mean ??

It looks like Lottie has a direction of play.

setDirection(1). normal direction
setDirection(-1). reverse direction

But also looks like there is a bug.

To play in reverse you have to have loop set to true (That's the bug )
Reveres will not work if loop is false. Which defeats any attempt to rchange direction because we are stuck in a loop.

My work around is to add a on loop complete listener on the animation. Stop the animation, set animation completed to true, change the direction and start the animation again.

In the loadLottieFile() we add at the top

hypeDocument.customData.direction = 1

then at the bottom of the loadLottieFile()

hypeDocument.customData.animation.onLoopComplete = function(){ 
				
 		 hypeDocument.customData.animation.stop()
 		 hypeDocument.customData.animationCompleted = true;
 		 
 		 console.log("COMPLETE")
 		   
		  switch(hypeDocument.customData.direction) {
			  case 1:
			   hypeDocument.customData.direction = -1
			    break;
			  case -1:
			    hypeDocument.customData.direction = 1
			    break;
			   
			}

 		 hypeDocument.startTimelineNamed('bounce')
 		 
	}

We also need to set loop to true.

loop: true,

The animation start is just a run javascript action on a timeline named bounce.

The play button also starts this time line.
( you could also just use hypeDocument.functions(). playLottieFile(hypeDocument, element, event)
instead )

The playLottieFile()

becomes

 if (hypeDocument.customData.animationCompleted) {
 	hypeDocument.customData.animation.setDirection(hypeDocument.customData.direction);
  hypeDocument.customData.animation.play();
  hypeDocument.customData.animationCompleted = false;
  


  }

The animation will appear to loop through forward - reverse - forward .... and so on.
If you want it to stop then just add some sort of counter to the loop complete callback function .

Play_lottie-fixed_mhv1.hype.zip (82.2 KB)

2 Likes

Hi Mark

Thanks for all these suggestions.

In the end, I decided to go for a simpler approach as I'm not that good with js. I created a button element and want the Lottie animation to be part of the button with different hover effects. So, I want the animation to start playing forward on mouse over and I want the animation to start playing backward and go back to the beginning on Mouse out.

I added one script on Mouse over of the button element so that the animation starts playing when the cursor enters the button. Then, I added another script on mouse out so that the play direction is reversed when the cursor leaves the button. This is all working ... but there is something strange happening.

I noticed that when the cursor enters the button and stays on it long enough for the animation to complete then the reversing of the animation when the cursor leaves the button does not work. But when the cursor leaves the button when the animation is still playing the the reversing works fine when it leaves.

It looks like when animation completes then it stops playing and reversing it just won't work.

I'm trying to write an if/else statement to check if the animation is still playing and if it is then simply reverse it but if it has completed then play if from the end to the beginning but I'm struggling with this.

Play_lottie-fixed.hype.zip (85.9 KB)

Any help and guidance is appreciated.

Thanks!

Hi,

It looks like you did not understand when I said there is a bug in Lottie that means you MUST have loop set to true or reverse will not work.

What you want to do is more complex than I worked out above but should be doable using the same principles.

I just had a look around trying to find a reference to if there was a get current frame in the Lottie API and found this thread which goes some way to point to what you want to do and validate what I worked out already.

I think my version and the info in that thread will hopefully help with this Lottie question.
There are probably other pointers out there. But ultimately I think you will need to get a handle on the API and some javascript. I do not think it will be that hard to finally figure out.


I hope this does not come across as condescending it certainly is not meant to and I am trying to show you how to find answers..

It can sometime seem hard in not knowing where to go but as an example on approach to problems like this.

Once I realised that reverse was not working, I search for Lottie reverse not working.

I found references that confirmed there was a bug and loop needed to be set to true.
But I did not find much more on how to fix this.

I now knew that loop had to be on which meant the animation would loop forever and the code would need a way to not only know when a loop completed but to stop the animation, reverse the play direction and start again.

So again I searched for reference on know when Lottie loop is complete, and so on..

My thinking walked along the path of what was needed of the animation and the logical steps to get around the road blocks to continue that path and then searching with the terms of the query as simple and direct as possible to what I currently want.

3 Likes

Thanks for all your suggestions and pointers Mark. They surely make a lot of sense.

I think I should familiarise myself better with Lottie Files and what interactivity can be added with JS as I'm going to be using them more often from now on.

In the end I went for something like this:

On button mouse over:

hypeDocument.customData.animation.playSegments([0, 101], true)
hypeDocument.customData.animation.setDirection(1);

On button mouse out:

var current_frame = hypeDocument.customData.animation.currentRawFrame
if (current_frame == 100) {
hypeDocument.customData.animation.goToAndPlay(80, true); hypeDocument.customData.animation.setDirection(-1);	
} else {   
hypeDocument.customData.animation.setDirection(-1);	
}

Next step, I'm going to study and understand your solution better so I can implement it in the future.

Thanks again
Greg

1 Like

See, Excellent .
Nice and clean.
Your solution found a way to bypassed the loop issue by mixing segments and goToAndPlay.
Great job..