1

NOTE: "Note: Renderer can still be injected/used, but is deprecated." Change Log

Binding variables to the new Animations DSL isn't available and I have been looking for alternatives.

The only one I have found so far is the Renderer.animate function but I have not been able to get it working or find any examples for it.

Looking at the code I found that it uses the following parameters.

renderer.animate(
    element: any, 
    startingStyles: AnimateStyles, 
    keyframes: AnimiationKeyframe[], 
    duration: number, 
    delay: number, 
    easing: string
): AnimationPlayer

What I got (not working):

renderer.animate(
  element,
  {'opacity': this.temp},
  [
      {'opacity' : .5},
      {'opacity' : 1}
  ],
  2,
  1,
  'linear'
)

What would be the correct way to get this working? Any help would be appreciated.

Thanks

Adam j
  • 391
  • 5
  • 18
  • Why dont you trying adding a class to the element and create the animation in css ? – jgatjens May 13 '17 at 23:44
  • Hey @jgatjen, at the time of writing this Angular was in rc0 i believe and I was just learning it. This was my attempt at doing it the "Angular Way." I agree there are other ways to do it as well. Please feel free to post a solution if you wanted in just CSS. – Adam j May 23 '17 at 23:49

4 Answers4

4

Renderer is deprecated in Angular 4.x.x. So it is not good to use it. Instead you can you animate() method of nativeElement. You can use @ViewChild to get elmentRef and then nativeElement.

For example:

 @ViewChild("currentSlide") private currentSlide: ElementRef;

 let startPos = dir === "RIGHT"? "-100%": "100%";
 this.currentSlide.nativeElement.animate(
  [
    {transform: "translateX(" + startPos + ")"},
    {transform: "translateX(0)"},
  ], 
  {
    duration: 300,
    delay: 0,
    fill: "both",
    easing :'ease-in-out'
  }
);

Note: It is old post but i answered hoping it may help someone who is currently looking for animating through renderer.

Santosh Prasad Sah
  • 2,124
  • 1
  • 19
  • 14
  • Thanks adding this. I have it in an older project and didn't know it was deprecated in Angular 4. Added a comment to the original post – Adam j May 13 '17 at 14:29
  • @Santosh hi , how to change this so that I have a transition instead. having height as style and transition... I could have used `animations` from `@angular/animations` but I want to set the height dynamically and I couldn't do it using animations.. so using `animate()` might work for me... expanding from the current div height to `*` and vice versa (shrink) – Yasir May 22 '17 at 06:26
  • @DavidBracoly, sorry for delay response. I could not understand your question clearly. Could you please explain it? – Santosh Prasad Sah May 23 '17 at 12:38
1

Looks like I can use the renderer.invokeElementMethod to use custom animations in Angular 2.

animate(){
  let posX = 100;

  this.renderer.invokeElementMethod(
    this.temp.nativeElement, 
    'animate', 
    [
      [
        {transform: 'translate(0)'},
        {transform: 'translate('+posX+'px, 100px)'}
      ],
      {
        duration: 2000,
        delay: 0,
        fill: 'forwards'
      }
    ]
  );
}

Other options to use can be found here: https://developer.mozilla.org/en-US/docs/Web/API/Element/animate

plnkr example : http://plnkr.co/edit/JSGjbg8KPa34YxzPpofT

Adam j
  • 391
  • 5
  • 18
0

This is how you should format the animate function as of the angular 2.0.0 release:

renderer.animate(
    element,
    {
      styles: [{'opacity': this.temp}]
    },
    [
      {
        offset: .5,
        styles: {
          styles: [
            {'opacity' : .5}
          ]
        }
      },
      {
        offset: 1,
        styles: {
          styles: [
            {'opacity' : 1}
          ]
        }
      }
    ],
    2,
    1,
    'linear'
)
pzaenger
  • 11,381
  • 3
  • 45
  • 46
Edril
  • 13
  • 3
  • Thanks for the reply. Is there any benefit to using renderer.animate over `renderer.invokeElementMethod(animate, ...)` – Adam j Sep 30 '16 at 00:46
  • I'm actually not sure if there is a specific benefit to using this right now. The angular documentation mentions that the renderer is still experimental (https://angular.io/docs/js/latest/api/core/index/Renderer-class.html), so things might change in the future, but it seems like this is the direction the angular team wants to be heading in. – Edril Sep 30 '16 at 17:46
  • Didn't work for me on 2.0.2. renderer.invokeElementMethod works, though. – EternalLight Oct 26 '16 at 18:19
0

Have been banging my head against the wall for two days now, and went so far as to debug the JS code for the WebAnimationsPlayer class in the platform-browser module. Here are my findings so far:

#1 the player won't start playing until you call .play() on the AnimationPlayer object returned from Renderer.animate()

#2 I sense a potential bug in the WebAnimationsPlayer class, whereby as soon as the animation is finished, the player destroys itself unless there's some sort of "parentPlayer" which is a field/property on the class and which remains empty when we call Renderer.animate(). And that's cool, however in the course of self-destruction, WebAnimationsPlayer calls the reset() method on the internal player of the element, which essentially reverts the styles you'd want left alone at the end of your animation, and returns the element to its original state. - NOT GOOD! Please note: WebAnimationsPlayer does properly set 'fill':'both' which instructs the element player to maintain its final state in both directions, but that doesn't help anyways due to the explicit reset() call. This is what I've been struggling with and the only resolve seems to be the direct use of renderer.invokeElementMethod as pointed out later by the OP. BTW, the WebAnimationsPlayer class called by Renderer.animate() uses it internally anyways.

My code currently goes like this, and seems to work for me:

this._renderer.invokeElementMethod(
    element.nativeElement,
    'animate',
    [
        [
            {top : 0, left: 0, offset : 0},
            {top : `${offsetY}px`, left : `${offsetX}px`, offset : 1}
        ],
        {
            delay: 1000,
            duration: 5000,
            iterations: 1,
            easing: 'ease',
            fill: 'both'
        } 
    ]
);

#3 Please note that in the OP-s code, the delay and duration values are in milliseconds, so given the "reset" problem described in #2 he would not have been able to notice any animation even if .play() had been called.

Alex Lobakov
  • 704
  • 1
  • 6
  • 8
  • An issue has been opened on GitHub for #2: [link](https://github.com/angular/angular/issues/12456) – Alex Lobakov Oct 22 '16 at 06:14
  • When you do fill: "forward" does that make it work? On a side note I have found that invokeElementMethod with animate causes error for me on Safari/Edge. Although I do not know if others are having the same issue. – Adam j Oct 24 '16 at 02:11
  • I did try "forward" which produced the same outcome. – Alex Lobakov Jan 02 '17 at 00:31