3

Is there a way to use the same css animation for a different DOM element? I have created the same animation twice, and I was looking for a way to just write it once and make note of which DOM element I am wanting to fade in and out. Now, I am aware of View Child and ElementRef, but I am a little unclear on the implementation. Also, I am trying to look for an implementation that avoids ElementRef due to XSS security concerns. https://angular.io/docs/ts/latest/api/core/index/ElementRef-class.html

Here is my HTML

<div>
    <md-checkbox (change)="toggleFadeOne()">Show</md-checkbox>
    <div fxLayout="row" [@fadeOne]="fadeOne" class="oneToggle">
        <p>

        </p>
    </div>
</div>

<div>
    <md-checkbox (change)="toggleFadeTwo()">Show</md-checkbox>
    <div fxLayout="row" [@fadeTwo]="fadeTwo" class="twoToggle">
    <p>

    </p>
</div>

Here is my css

.oneToggle, .twoToggle {//initial style for el, instead of void
   opacity: 0;
   visibility: hidden;
}

Here is my TypeScript

@Component({
  selector : 'c-select-composite-config-dialog',
  templateUrl: './page.html',
  styleUrls: ['./style.css'],
  animations: [
  trigger('fadeOne', [
    state('in', style({
      'opacity' : '1', 'visibility' : 'visible'
    })),
    state('out', style({
      'opacity' : '0', 'visibility' : 'hidden'
    })),
    transition('* => *', animate(500))
  ]),
  trigger('fadeTwo', [
    state('in', style({
      'opacity' : '1', 'visibility' : 'visible'
    })),
    state('out', style({
      'opacity' : '0', 'visibility' : 'hidden'
    })),
    transition('* => *', animate(500))
  ])
]
})
export class MyComponent {



  private fadeOne : string;
  private fadeTwo : string;

  private toggleFadeOne() {
  if(this.fadeOne === 'out' || this.fadeOne === undefined) {
    this.fadeOne = 'in';
  } else {
    this.fadeOne = 'out'
  }
}

private toggleFadeTwo() {
  if(this.fadeTwo === 'out' || this.fadeTwo === undefined) {
    this.fadeTwo = 'in';
  } else {
    this.fadeTwo = 'out'
  }
}

...
}
Arjan
  • 22,808
  • 11
  • 61
  • 71
John Stafford
  • 565
  • 2
  • 9
  • 29

1 Answers1

1

I'm pretty sure you could define the anmiation elsewhere, then import it and assign it to your animation property.

Like this:

**import the animation classes**

export static class Animations {
    public sharedAnimation = trigger('fadeOne', [
    state('in', style({
      'opacity' : '1', 'visibility' : 'visible'
    })),
    state('out', style({
      'opacity' : '0', 'visibility' : 'hidden'
    })),
    transition('* => *', animate(500))
  ]),
  trigger('fadeTwo', [
    state('in', style({
      'opacity' : '1', 'visibility' : 'visible'
    })),
    state('out', style({
      'opacity' : '0', 'visibility' : 'hidden'
    })),
    transition('* => *', animate(500))
  ])
]
}

Then I think you could do:

animations: Animations.sharedAnimation
chrispy
  • 3,552
  • 1
  • 11
  • 19
  • 1
    Thanks for your response @chrispy. Yes, I am familiar with defining an animation in an external file, but again, the same animation, written twice? There has to be some way to target the one animation to different DOM elements. – John Stafford Feb 23 '17 at 20:28
  • I just found this. http://stackoverflow.com/questions/42068914/angular-2-animate-a-speciffic-targeted-element ; this might do it. – John Stafford Feb 23 '17 at 20:33
  • Working on a solution using ngClass and keeping the animations as keyframes in external css. Animation state could be kept much the same like I am doing here and toggling the state with a function tied to a checkbox or something. – John Stafford Feb 23 '17 at 20:42
  • I am sure there are multiple ways to skin the cat, but using ngClass provides an extensible way to give multiple elements access to the animation through keyframes in external css without accessing the DOM. – John Stafford Feb 23 '17 at 20:44
  • Thanks for that :) – Tim Consolazio Feb 23 '17 at 23:54
  • @TimConsolazio, how did you set the initial state on your ngClass? – John Stafford Feb 24 '17 at 00:18
  • I ended finding an 'Angular' way to solve this problem. I only write the animate once, but tie the animation to two different state variables. For example, – John Stafford Feb 24 '17 at 00:55
  • I only have one fade in and out animation, but I can set the [@fade]="fadeOne" and [@fade]="fadeTwo". Hope this helps someone. – John Stafford Feb 24 '17 at 01:01
  • @JohnStafford I don't quite understand. Can I see your trigger definition. I am trying to apply the same "trigger" animation to multiple DOM elements. I am having the same issue you mentioned. I don't want to define an animation "trigger" for each DOM element in the view. – TerNovi Jul 03 '17 at 03:44