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

时间:2017-12-04 13:49:24

标签: angular animation button transition

我正在使用角度材料和角度5动画处理PWA应用程序。我使用步进组件,每步都有2个按钮。我想在每个按钮的悬停事件期间创建一个状态(非活动/活动)动画。我能够分别使用每个按钮的变量/状态绑定来实现这一点。但它看起来像HTML中的很多代码。有什么办法可以使用HostListener& hostbinding并避免使用那些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中看起来很重复和丑陋。有没有什么办法可以避免和主机绑定处理,同时分别维护每个按钮的状态。请帮忙!!

1 个答案:

答案 0 :(得分:1)

是的!您应该能够使用指令和hostbindings以及hostlisteners来实现所有这些功能。这是一个粗略的(未经测试的)例子:

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';
  }
}

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