改变垫子膨胀指示器的旋转

Fla*_*ash 2 css transform angular-material angular

我成功地将 mat Indicator 向左移动,而不是向右移动,并且我使用了 transform 属性使其在展开时向内转动。但是,我希望指标在展开时朝上,在折叠时朝下。我如何正确设置样式以实现此目的:https : //stackblitz.com/edit/indicatorrotation?file=styles.css

扩展概述-example.css

  .mat-expansion-panel-header {
       flex-direction: row-reverse;
   } 
Run Code Online (Sandbox Code Playgroud)

全局样式.css

  .mat-expansion-indicator::after {
      transform: rotate(225deg) !important;  
}
Run Code Online (Sandbox Code Playgroud)

ysf*_*ysf 7

垫子扩展指示器的旋转由这个动画处理。从那里可以看出,它很简单rotate(180deg)(顺时针 180 度)。指示器最初具有rotate(45deg)在面板关闭时默认显示向下图标和面板打开时显示向上图标的顺时针动画。

当您应用旋转时;

.mat-expansion-indicator::after {
    transform: rotate(225deg) !important;  
}
Run Code Online (Sandbox Code Playgroud)

图标在面板关闭时最初向上旋转,单击时顺时针旋转 180 度。在这一点上,你不能在关闭时显示向下的图标,在打开时显示向上的图标,因为rotate(225deg)如果你改变了,你会松开向内转动,因为动画是顺时针开始的,但我们需要完全相反。

最终不可能在不覆盖默认动画的情况下进行逆时针旋转。不幸的是,Angular Material 没有任何机制来覆盖默认动画,如下所示

所以我的解决方案是完全禁用默认动画mat-expansion-panel-header并实现一个自定义指令来模仿这个动画但逆时针。

首先禁用默认动画mat-expansion-panel-header

<mat-expansion-panel-header [@.disabled]="true">

然后以styles.css与默认动画相同的时间和行为创建新动画。

.mat-expansion-indicator::after {
    transform: rotate(225deg) !important;  
}
Run Code Online (Sandbox Code Playgroud)

并实现基于面板打开/关闭事件处理动画状态的自定义指令

@keyframes inwards-open {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(-135deg); }
}

@keyframes inwards-close {
  0%   { transform: rotate(-135deg); }
  100% { transform: rotate(0deg); }
}

.openAnimate {
  animation: inwards-open 225ms cubic-bezier(0.4,0.0,0.2,1) !important;
}

.closeAnimate {
  animation: inwards-close 225ms cubic-bezier(0.4,0.0,0.2,1) !important;
}
Run Code Online (Sandbox Code Playgroud)

最后将自定义指令应用于 mat-expansion-panel

import { Directive, ElementRef, HostListener, AfterViewInit, OnDestroy } from '@angular/core';
import { fromEvent, Subscription } from 'rxjs';

@Directive({
  selector: '[appCustomMatExpansionToggle]'
})
export class CustomMatExpansionToggleDirective implements AfterViewInit, OnDestroy {
  private elem: HTMLSpanElement;
  private uns: Subscription;
  constructor(private elRef: ElementRef) {}

  ngAfterViewInit() {
    this.elem = this.elRef.nativeElement.querySelector(".mat-expansion-indicator");

    this.uns = fromEvent(this.elem, 'animationend').subscribe(() => {
      this.elem.classList.remove("openAnimate");
      this.elem.classList.remove("closeAnimate");
    });
  }

  @HostListener("opened")
  onOpen() {
    this.elem.classList.add("openAnimate");
  }

  @HostListener("closed")
  onClose() {
    this.elem.classList.add("closeAnimate");
  }

  ngOnDestroy() {
    this.uns.unsubscribe();
  }
}
Run Code Online (Sandbox Code Playgroud)

这是一个工作演示https://stackblitz.com/edit/indicatorrotation-mp73uh


小智 6

禁用默认动画:

<mat-expansion-panel-header [@.disabled]="true">
Run Code Online (Sandbox Code Playgroud)

重写一些全局styles.scss中的样式

  .mat-expansion-panel {
    .mat-expansion-indicator {
      transition: transform .3s ease;

      &::after {
        transform: rotate(-135deg);
      }
    }

    &.mat-expanded {
      .mat-expansion-indicator {
        transform: rotate(40deg) !important;
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!这应该被接受的答案。 (2认同)