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

How to switch animation after initialization? #23

Open
laulaaa opened this issue May 11, 2018 · 5 comments
Open

How to switch animation after initialization? #23

laulaaa opened this issue May 11, 2018 · 5 comments

Comments

@laulaaa
Copy link

laulaaa commented May 11, 2018

Hello.
I'm trying to figure out how to switch animation after initialization, but I don't see it in the documentation. Is it possible?

I found the same question in airbnb/ios. Here is the reference: LINK

Right now, I'm reloading the component of the animation using *ngif hiding and showing it again, it works, but not always.
I'm looking for a better solution.

@1pocketaces1
Copy link

Hi @laulaaa if you notice Im the one who asked in that ios thread how to do it for angular hah. So far the solution I have implemented is not ideal for loading times but it performs okay after initialization.

  • I create a div container for the animation view (this assumes the different anims that you switch require the same size animation view).
  • Inside that div container I put all of the lottie-animation-views for all of the animations I want to switch in and out. So this does require initializing all of the anims on load and keeping JS anim and config objects allocated for each of them. Set them all to autoplay: false.
  • Set the container to position: relative, and then give each animation inside a unique id and set them to position: absolute, giving them different z-index so they can overlay each other in the div.
  • create a class (I call it "off") that includes opacity: 0, and pointer-events: none, and apply this to all the animations that should not be showing.
  • whenever you need to switch animations, you can now toggle the "off" class for whichever animation you want to show and then use play() or whatever from there.

This performs fine after the views are initialized as the CSS changes in the "off" class do not trigger screen re-draws, and only one animtion is playing at one time.
I have used this to allow a user to win a prize, and in the prize display I have all of the different prize animations, and I switch to the one that is won upon its display.

Hope this maybe helps as a temporary fix!

@1pocketaces1
Copy link

And maybe it helps or doesnt but in the JS, I keep a variable to hold an ID for whichever animation is currently on, which helps with making the necessary changes

@rccueva
Copy link

rccueva commented Mar 11, 2019

Hi, please help.. I need the solution too.

@kmturley
Copy link

kmturley commented Mar 19, 2019

According to the documentation here:
http://airbnb.io/lottie/#/web?id=html-player-installation

Available methods are:

anim.play() 
anim.stop() 
anim.pause() 
anim.setLocationHref(locationHref) 
anim.setSpeed(speed) 
anim.goToAndStop(value, isFrame)
anim.goToAndPlay(value, isFrame)
anim.setDirection(direction)
anim.playSegments(segments, forceFlag)
anim.setSubframe(flag)
anim.destroy()

So i'm guessing you would use them with ng-lottie by using the html:
<lottie-animation-view class="animation" [options]="lottieConfig" (animCreated)="animCreated($event)"></lottie-animation-view>

And then the function:

animCreated(anim: any) {
  this.anim = anim;
  console.log('animCreated', anim);
}

and then later:

animLoad(url) {
  console.log('animLoad', url);
  if (this.anim) {
    this.anim.destroy();
  }
  this.lottieConfig = {
    path: url,
    renderer: 'canvas',
    autoplay: false,
    loop: false
  };
}

But doesn't seem to work for me...as destroy seems to destroy lottie instance but not reset the angular element.

Inspecting the lottie instance there are these methods available:

addEventListener: ƒ _addEventListener(t,e)
addPendingElement: ƒ ()
adjustSegment: ƒ (t)
advanceTime: ƒ (t)
checkLoaded: ƒ ()
checkSegments: ƒ ()
configAnimation: ƒ (t)
destroy: ƒ (t)
elementLoaded: ƒ ()
getAssetData: ƒ (t)
getAssets: ƒ ()
getAssetsPath: ƒ (t)
getPath: ƒ ()
goToAndPlay: ƒ (t,e,r)
goToAndStop: ƒ (t,e,r)
gotoFrame: ƒ ()
hide: ƒ ()
includeLayers: ƒ (t)
loadNextSegment: ƒ ()
loadSegments: ƒ ()
moveFrame: ƒ (t,e)
pause: ƒ (t)
play: ƒ (t)
playSegments: ƒ (t,e)
remove: ƒ (t)
removeEventListener: ƒ _removeEventListener(t,e)
renderFrame: ƒ ()
resetSegments: ƒ (t)
resize: ƒ ()
setCurrentRawFrameValue: ƒ (t)
setData: ƒ (t,e)
setDirection: ƒ (t)
setParams: ƒ (t)
setSegment: ƒ (t,e)
setSpeed: ƒ (t)
setSubframe: ƒ (t)
show: ƒ ()
stop: ƒ (t)
togglePause: ƒ (t)
trigger: ƒ (t)
triggerEvent: ƒ _triggerEvent(t,e)
updaFrameModifier: ƒ ()
updateAnimation: ƒ (t)
waitForFontsLoaded: ƒ ()

When resetting an animation it looks as though you have to do destroy then loadAnimation:

animation.destroy();
lottie.loadAnimation();

Example:
https://codepen.io/kmtbynd/project/editor/Zrzqyj

which ng-loggie doesn't seem to have support for.

I managed to kind of get it working by modifying ng-lottie:

import { Component, Input, OnInit, Output, EventEmitter, ViewChild, ElementRef, PLATFORM_ID, Inject } from '@angular/core';
import { isPlatformServer } from '@angular/common';

declare let require: any;
const lottie: any = require('lottie-web/build/player/lottie.js');

@Component({
  selector: 'app-lottie-animation-view',
  template: `<div #lavContainer [ngStyle]="{'width': viewWidth, 'height': viewHeight, 'overflow':'hidden', 'margin': '0 auto'}"></div>`
})

export class LottieAnimationViewComponent implements OnInit {
  private anim: any;
  public viewWidth: string;
  public viewHeight: string;
  private optionsData: any;

  @ViewChild('lavContainer') lavContainer: ElementRef;
  @Input() width: number;
  @Input() height: number;
  @Input()
  set options(options: any) {
    this.optionsData = {
      container: this.lavContainer.nativeElement,
      renderer: options.renderer || 'svg',
      loop: options.loop !== false,
      autoplay: options.autoplay !== false,
      autoloadSegments: options.autoloadSegments !== false,
      animationData: options.animationData,
      path: options.path || '',
      rendererSettings: options.rendererSettings || {}
    };
    this.load();
    console.log('optionsData', this.optionsData);
  }
  @Output() animCreated: any = new EventEmitter();

  constructor(
    @Inject(PLATFORM_ID) private platformId: string
  ) { }

  ngOnInit() {
    if (isPlatformServer(this.platformId)) {
      return;
    }
  }

  load(path?: string) {
    if (this.anim) {
      this.anim.destroy();
    }
    if (path) {
      this.optionsData.path = path;
    }

    this.viewWidth = this.width + 'px' || '100%';
    this.viewHeight = this.height + 'px' || '100%';

    this.anim = lottie.loadAnimation(this.optionsData);
    this.animCreated.emit(this.anim);
  }

  ngOnDestroy() {
    if (this.anim) {
      this.anim.destroy();
    }
  }
}

Usage:
import { LottieAnimationViewModule } from './shared/lottieAnimationView.module';

and:
<app-lottie-animation-view #animation class="animation" [options]="lottieConfig" (animCreated)="animCreated($event)"></app-lottie-animation-view>

@FloLech
Copy link

FloLech commented Dec 13, 2019

Any update on this? I ran into the same issue.

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