【问题标题】:Dynamically create Angular animations动态创建 Angular 动画
【发布时间】:2017-11-03 12:43:44
【问题描述】:

我正在创建一个滑动到下一个或上一个全屏页面的分页组件。因为不同浏览器和设备的问题,我暂时放弃了只使用 CSS 过渡。我有一个可行的角度动画解决方案,但新问题是它无法缩放。

import { Component } from '@angular/core';
import { animate, state, style, transition, trigger } from '@angular/animations';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  animations: [
    trigger('slideTransition', [
      state('firstPage', style({ transform: 'translateX(0)' })),
      state('secondPage', style({ transform: 'translateX(-100%)' })),
      transition('firstPage=>secondPage', animate('0.6s ease')),
      transition('secondPage=>firstPage', animate('0.6s ease'))
  ])]
})
export class AppComponent {

  state = 'firstPage';

  nextPage() {
    this.state = 'secondPage';
  }

  previousPage() {
    this.state = 'firstShowing';
  }

}

问题是,如您所见,当我有 9 页时。我不想定义 9 个状态和 18 个转换。如何根据页数执行可重用状态或生成状态和转换运行时?有什么想法吗?

模板看起来像这样

<div class="container">
  <div [@slideTransition]="state" class="page">
    <h1>Page 1</h1>
    <div class="clicker" (click)="nextPage()">clickity</div>
  </div>
  <div [@slideTransition]="state" class="page">
    <h1>Page 2</h1>
    <div class="clicker" (click)="previousPage()">clackity</div>
  </div>
</div>

【问题讨论】:

    标签: angular ng-animate angular-animations


    【解决方案1】:

    我现在找到了一个可能的解决方案。虽然因为我使用 margin-left 进行过渡,但性能并没有达到应有的水平。

    import { Component } from '@angular/core';
    import { animate, state, style, transition, trigger } from '@angular/animations';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
      animations: [
        trigger('slideTransition', [
          state('previous', style({ marginLeft: '-100%', display: 'none' })),
          state('current', style({ marginLeft: '0' })),
          state('next', style({ display: 'none' })),
          transition('current=>previous', animate('0.6s ease')),
          transition('current=>next', animate('0.6s ease')),
          transition('next=>current', animate('0.6s ease')),
          transition('previous=>current', animate('0.6s ease'))
        ])
      ]
    })
    export class AppComponent {
    
      state = ['current', 'next', 'next'];
      current = 0;
    
      next() {
        this.current = this.current + 1;
        this.updateState();
      }
    
      previous() {
        this.current = this.current - 1;
        this.updateState();
      }
    
      private updateState() {
        for (let i = 0; i < this.state.length; i++) {
          if (i < this.current) {
            this.state[i] = 'previous';
          } else if (i === this.current) {
            this.state[i] = 'current';
          } else {
            this.state[i] = 'next';
          }
        }
      }
    }
    

    和模板

    <div class="the-host">
      <div [@slideTransition]="state[0]" class="fullscreen first">
        <h1>Page 1</h1>
        <div class="clicker" (click)="next()">next</div>
      </div>
      <div [@slideTransition]="state[1]" class="fullscreen second">
        <h1>Page 2</h1>
        <div class="clicker" (click)="previous()">previous</div>
        <div class="clicker" (click)="next()">next</div>
      </div>
      <div [@slideTransition]="state[2]" class="fullscreen third">
        <h1>Page 3</h1>
        <div class="clicker" (click)="previous()">previous</div>
      </div>
    </div>
    

    【讨论】:

      【解决方案2】:

      您需要将params 发送到该州。这可以通过添加一个班级成员并根据您的页码不断更新它来实现。然后将其连接到您的 HTML 中。

      以下是对现有代码的潜在补充:

      animations: [
        trigger('slideTransition', [
          // ...
          state('*',
                style({ marginLeft: '{{pageMarginValue}}%' }), 
                {params: {pageMarginValue: 0}}),
          transition('*=>*', animate('0.6s ease')),
          // ...
      ])
      

      ]

      然后将其添加到您的课程中:

      export class AppComponent {
        // ...
        private currentMargin = 0;
        private step = 10; // replace with actual value
      
        next(): void { this.currentMargin += this.step; }
        previous(): void { this.currentMargin -= this.step; }
      
        // ...
      }
      

      在您的 HTML 中,像这样传递currentMargin

      <div [@slideTransition]="{value: state, params: { pageMarginValue: currentMargin }}"></div>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-27
        • 1970-01-01
        • 2011-12-30
        • 2012-05-26
        • 2016-09-27
        • 1970-01-01
        • 2013-08-31
        • 1970-01-01
        相关资源
        最近更新 更多