【问题标题】:Angular 8 - how to trigger animation with different values on Desktop and Mobile?Angular 8 - 如何在桌面和移动设备上触发具有不同值的动画?
【发布时间】:2020-11-13 00:39:40
【问题描述】:

我正在完成我的 webApp 并使其具有响应性。 我遇到了最后一个我似乎无法解决的问题!

我有一个动画,用于类似弹出框的元素,它在桌面上从Left 滑动到Right

在移动设备上,没有足够的空间,所以我将在输入字段下方打开该元素,而不是在侧面,所以我需要一个从 Bottom 滑动到 Top 的动画。

这是我用于桌面屏幕的默认动画代码:

animations: [
    trigger("slideInOut", [
      transition(":enter", [
        style({ transform: "translateX(60%)", opacity: 0 }),
        animate(
          "300ms ease-in",
          style({ transform: "translateX(0%)", opacity: 1 })
        ),
      ]),
      transition(":leave", [
        animate(
          "300ms ease-in",
          style({ transform: "translateX(60%)", opacity: 0 })
        ),
      ]),
    ]),
  ]

而我唯一要更改的是transform 的 3 个值

对于移动设备,我需要:

translateY(60%)
translateY(0%)
translateY(60%)

所以基本上只需将 X 轴与 Y 轴交换即可!

我怎样才能做到这一点? 如果无法更改这些值,即使禁用移动动画也可以!

我想到了一个解决方案,但是很脏,很脏! 基本上我会创建一个我的“popover-like DIV”的副本,然后在他们两个上打一个类,例如:

.mobile

.desktop

然后,基于媒体查询,我会显示一个或另一个,最后在每一个上,我会附加一个不同的动画触发器,我会在我的组件中声明两个触发器,一个用于 Y 轴和一个用于 X 轴。 这应该可以,但我一点也不喜欢!

【问题讨论】:

  • 这里需要使用 Angular 动画有什么特别的原因吗?像这样的简单事情可以在纯 css 中完成,Angular 只设置一些动态类。
  • 不,当然没有,我不是动画专家,所以我用我在 Angular 中所知道的简单的方法!这个动画在 css 中的等价物是什么?

标签: angular animation


【解决方案1】:

在我的例子中,我使用移动查询来选择 div 的类,然后在动画查询中,根据类编写不同的动画。通过这种方式,我可以使用非常独立的动画,而无需传递参数。

我的组件.html

<div class="dp-a" [@fadeOut]>
    <div class="d0" (click)="closePanel()"></div>
        <div [ngClass]="mobileQuery.matches? 'd1':'d1-desktop'"><!--HERE class query-->

我的组件.ts

query('.d1', // mobile class
    animate('0.3s ease-in', style({ transform: 'translateY(0%)' })), 
    { optional: true }
),
query('.d1-desktop', // desktop class
    animate('0.2s ease-out', style({ transform: 'scale(1)' })), 
    { optional: true }
)

重要提示:不要忘记{ optional: true }[ngClass] 中的三元运算符需要它,因为是类选择。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题并设法解决了这个问题。不确定这是否是最好的解决方案,但它确实有效。

    所以在组件中我监听页面宽度大小。不要忘记从构造函数中调用监听器,否则只有在屏幕调整大小时才会触发。

    @Component({
      selector: 'my-component',
      templateUrl: './my-component.component.html',
      styleUrls: ['./my-component.component.scss'],
      animations: [
        trigger('slideInOut', [
          transition(':enter', [
            style({ transform: '{{translateType}}(-100%)' }),
            animate('900ms ease-in', style({ transform: '{{translateType}}(0%)' })),
          ]),
          transition(':leave', [animate('700ms ease-in', style({ transform: '{{translateType}}(-100%)' }))]),
        ]),
      ],
    })
    export class MyComponent {
      screenWidth: number;
    
      @HostListener('window:resize', ['$event'])
      onResize() {
        this.screenWidth = window.innerWidth;
      }
    
      constructor() {
        this.onResize();
      }
    
      getAnimationTransformValue(): string {
        return this.screenWidth <= 800 ? 'translateY' : 'translateX';
      }
    }
    

    在您的 html 模板中,我使用以下语法传入样式转换值。

    <div  [@slideInOut]="{ value: true, params: {translateType: getAnimationTransformValue() }}">
      Content
    </div>
    

    【讨论】:

    • 这是一个不错的解决方案!最后,我创建了两次相同的 DIV,创建了 2 个单独的动画,一个用于 X,一个用于 Y 过渡,最后使用 CSS 类来隐藏/显示这些 DIV,具体取决于是否移动......我最终可能会更改为您的解决方案,因为它更清洁
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-26
    • 1970-01-01
    • 2021-12-13
    • 2018-04-11
    相关资源
    最近更新 更多