вращение индикатора расширения мата обрабатывается этой анимацией . как можно видеть там, это просто rotate(180deg)
(180 градусов по часовой стрелке). и индикатор изначально имеет rotate(45deg)
, который показывает значок вниз по умолчанию, когда панель закрыта, и значок вверх, когда панель открыта с анимацией по часовой стрелке.
когда вы применяете вращение с помощью;
.mat-expansion-indicator::after {
transform: rotate(225deg) !important;
}
Значок
первоначально вращается вверх, когда панель закрыта, при нажатии она поворачивается на 180 градусов по часовой стрелке. в этот момент вы не можете показывать значок вниз, когда он закрыт, и вверх, когда он открыт, из-за rotate(225deg)
, если вы измените его, потеряв поворот внутрь, потому что анимация начинается по часовой стрелке, но нам нужно с точностью до наоборот.
в конце концов невозможно вращение против часовой стрелки без переопределения анимации по умолчанию. К сожалению, Angular Material не имеет механизма для переопределения анимации по умолчанию, , как показано здесь .
поэтому мое решение состоит в том, чтобы полностью отключить анимацию по умолчанию на mat-expansion-panel-header
и реализовать пользовательскую директиву, которая имитирует эту анимацию , но против часовой стрелки.
сначала отключить анимацию по умолчанию на mat-expansion-panel-header
;
<mat-expansion-panel-header [@.disabled]="true">
затем создайте новую анимацию в styles.css
с с тем же временем и поведением , что и у анимации по умолчанию.
@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;
}
и реализовать пользовательскую директиву, которая обрабатывает состояние анимации на основе событий открытия / закрытия панели
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();
}
}
и, наконец, применить пользовательскую директиву к mat-expansion-panel
<mat-expansion-panel appCustomMatExpansionToggle>
вот рабочая демоверсия https://stackblitz.com/edit/indicatorrotation-mp73uh