实现
拿公开库 ngx-tethys 的 cascader 组件的下拉面板的缓入缓出实现举例
第一步:定义一个动画触发器,名为 scaleYMotion。动画效果为:垂直方向上的缓入缓出。
export const scaleYMotion: AnimationTriggerMetadata = trigger('scaleYMotion', [
transition('* => enter', [
style({
opacity: 0,
transform: 'scaleY(0.9)'
}),
animate(
`${AnimationDuration.BASE} ${AnimationCurves.EASE_IN_OUT_STANDARD}`,
style({
opacity: 1,
transform: 'scaleY(1)'
})
)
]),
transition('enter => *', [
style({
opacity: 1,
transform: 'scaleY(1)'
}),
animate(
`${AnimationDuration.BASE} ${AnimationCurves.EASE_IN_OUT_STANDARD}`,
style({
opacity: 0,
transform: 'scaleY(0.9)'
})
)
])
]);
第二步:给目标组件的元数据设置 animations 属性, animations: [slideMotion] 。
@Component({
selector: 'thy-cascader,[thy-cascader]',
templateUrl: './cascader.component.html',
animations: [scaleYMotion]
})
export class ThyCascaderComponent {}
第三步:给动画的目标 Dom 绑定触发器,设置状态值 [@slideYMotion]="'enter'" 。
在哪个元素上设置动画? 在 .cdk-overlay-pane 下的第一级子元素上。
第四步:设置动画的转换源点 transformOrigin:即设置缓入缓出动画的源点,使得不管菜单面板是往下弹或往上弹,保证动画都是以输入框为源点,向外缓入,向里缓出。
方式一:给 cdkConnectedOverlay 指令设置 cdkConnectedOverlayTransformOriginOn 属性,值为:绑定了动画的元素的类选择器。比如:
<div cdkOverlayOrigin #origin="cdkOverlayOrigin" #trigger>......</div>
<ng-template
cdkConnectedOverlay
[cdkConnectedOverlayOrigin]="origin"
[cdkConnectedOverlayTransformOriginOn]="'.thy-cascader-menus'">
<div
[attr.tabindex]="-1"
#menu
class="thy-cascader-menus"
[@slideMotion]="'enter'"
(mouseleave)="mouseleaveMenu($event)">......</div>
</ng-template>
方式二:如果 Overlay 是编程式打开的,比如我们的 Popover 组件,可以通过 PositionStrategy 的 withTransformOriginOn 设置动画源点。
private positionStrategy = this.overlay
.position()
.flexibleConnectedTo(this.elementRef.nativeElement)
.withPositions(positions)
.withTransformOriginOn('.thy-popover-container');
注意:
如果使用者在打开 popover 时是直接调用 Angular cdk 的 updatePositionStrategy 方法实现的,需要设置上顺便设置上 withTransformOriginOn('.thy-popover-container')。