给下拉组件加缓入缓出动画

113 阅读1分钟

实现

拿公开库 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  下的第一级子元素上。

image.png

第四步:设置动画的转换源点 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>

image.png

方式二:如果 Overlay 是编程式打开的,比如我们的 Popover 组件,可以通过  PositionStrategy  的 withTransformOriginOn 设置动画源点。

private positionStrategy = this.overlay
  .position()
  .flexibleConnectedTo(this.elementRef.nativeElement)
  .withPositions(positions)
  .withTransformOriginOn('.thy-popover-container');

image.png

注意: 如果使用者在打开 popover 时是直接调用 Angular cdk 的 updatePositionStrategy 方法实现的,需要设置上顺便设置上 withTransformOriginOn('.thy-popover-container')