Angular 5 动画 - 多个按钮的状态转换

Angular 5 animation - state transition for multiple buttons

我正在使用 angular material 和 angular 5 个动画处理 PWA 应用程序。我正在使用步进器组件,每一步都有 2 个按钮。我想在每个按钮的悬停事件期间创建一个状态 (inactive/active) 动画。我可以使用 variable/state 分别绑定每个按钮来实现这一点。但是HTML里面的代码好像很多。有什么办法可以使用 HostListener 和主机绑定来实现这一点,并避免那些 html 脚本。

app.component.html

步骤 - 1

<button id="login-form" [@buttonStateAnimation]="states.loginButton" (mouseenter)="toggleState('loginButton')" (mouseleave)="toggleState('loginButton')"
          [disabled]="!loginForm.valid" mat-raised-button (click)="loginEmail()" color="primary">
          <span>Login</span>
        </button>
        <button mat-raised-button (click)="signup()" [@buttonStateAnimation]="states.signupButton" (mouseenter)="toggleState('signupButton')"
          (mouseleave)="toggleState('signupButton')" matTooltip="New user? Sign up">
          <span>Sign up</span>
        </button>

步骤 - 2

<button matTooltip="Login with Facebook" [@socialButtonsAnimation]="states.facebookButton" (mouseenter)="toggleState('facebookButton')"
          (mouseleave)="toggleState('facebookButton')" mat-mini-fab color="primary" (click)="loginFacebook()">
          <mat-icon class="fa-lg" fontSet="fontawesome" fontIcon="fa-facebook-square"></mat-icon>
        </button>
        <button matTooltip="Login with Google" [@socialButtonsAnimation]="states.googleButton" (mouseenter)="toggleState('googleButton')"
          (mouseleave)="toggleState('googleButton')" mat-mini-fab color="warn" (click)="loginGoogle()">
          <mat-icon class="fa-lg" fontSet="fontawesome" fontIcon="fa-google"></mat-icon>
        </button>
        <button matTooltip="Login with Twitter" [@socialButtonsAnimation]="states.twitterButton" (mouseenter)="toggleState('twitterButton')"
          (mouseleave)="toggleState('twitterButton')" mat-mini-fab color="primary" (click)="loginTwitter()">
          <mat-icon class="fa-lg" fontSet="fontawesome" fontIcon="fa-twitter"></mat-icon>
        </button>

app.component.ts

export class LoginComponent implements OnInit {
  private states: any;
  ngOnInit() {
    this.states = {
      loginButton: "inactive",
      signupButton: "inactive",
      facebookButton: "inactive",
      googleButton: "inactive",
      twitterButton: "inactive"
   }
 }
}

animations.ts

export const buttonStateAnimation =

 trigger('buttonStateAnimation', [
    state('inactive', style({ transform: 'translateX(0) scale(1)' })),
    state('active', style({ transform: 'translateX(0) scale(1.2)' })),
    transition('inactive => active', animate('200ms ease-in')),
    transition('active => inactive', animate('200ms ease-out')),
    transition(
      ':enter', [
        style({ transform: 'scale(.7)', opacity: 0 }),
        animate('0.3s', style({ opacity: 1, transform: 'scale(1)' })),
      ]
    ),
    transition(
      ':leave', [
        style({ opacity: 1, transform: 'scale(1)' }),
        animate('5.3s', style({ opacity: 0, transform: 'scale(.7)' })),
      ]
    )
  ])

现在上面的代码在 html 中看起来重复且难看。有什么办法可以通过主机绑定来避免和处理这种情况,同时分别维护每个按钮的状态。请帮忙!!

是的!您应该能够使用指令和主机绑定以及主机监听器来实现所有这些。这是一个粗略的(未经测试的)示例:

import { Directive, ElementRef, HostListener, HostBinding } from '@angular/core';

@Directive({
  selector: '[socialButton]',
})
export class SocialButtonDirective {

  constructor(private ref: ElementRef) {}

  @HostBinding('@socialButtonsAnimation') private state = 'inactive';

  @HostListener('mouseenter')
  @HostListener('mouseleave') 
  private toggleState() {    
    this.state = this.state === 'inactive' ? 'active': 'inactive';
  }
}

您仍然需要将动画定义导入到使用此指令的组件中才能正常工作。