kittencup / angular2-ama-cn

angular2 随便问
692 stars 101 forks source link

Angular2 开发指引:动画 #176

Open Imporial opened 8 years ago

Imporial commented 8 years ago

运动是在现代Web应用程序设计中的一个重要方面。我们希望我们的用户界面,有一定的状态,并调用在需要的地方注意引人入胜的动画之间的平滑过渡。精心设计的动画可以使UI不仅更加有趣,但也更容易使用。

Angular 的动画系统给了我们什么,我们需要做的各种我们想要的动画。我们可以构建与同类机性能,我们已经习惯了用纯CSS动画运行动画。但是我们也可以有我们的动画逻辑与我们的应用程序代码,在那里他们可以很容易地触发并控制其余的紧密集成。

Angular 的动画都是建立在标准的Web动画API之上的,他们本身就能在支持它的浏览器上运行。

对于其他浏览器,则需要填充工具。从这里抓住网络animations.min.js并把它添加到您的网页。

由 Angular 团队维护一个更轻巧填充工具即将推出。

目录

快速入门实例:在两种状态之间过渡 状态和转移 例如:进入和离开 例如:进入和不同国家离开 动画属性和单位 自动计算房产 动画计时 多步动画关键帧 并行动画组 本章中所引用的实施例可作为一个活的例子。

快速入门实例:在两种状态之间过渡

一个简单的过渡动画 让我们建立一个简单的动画过渡由一个模型属性驱动的两种状态之间的一个元素。

动画@Component元数据中定义。之前,我们可以添加一些,我们需要导入一些特定的动画函数:

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

有了这些,我们现在可以定义在组件元数据称为heroState动画触发。活动和非活动:它有两个状态之间的过场动画。当一个英雄是积极的,我们在稍大的尺寸和颜色较浅显示的元素。

  animations: [
    trigger('heroState', [
      state('inactive', style({
        backgroundColor: '#eee',
        transform: 'scale(1)'
      })),
      state('active',   style({
        backgroundColor: '#cfd8dc',
        transform: 'scale(1.1)'
      })),
      transition('inactive => active', animate('100ms ease-in')),
      transition('active => inactive', animate('100ms ease-out'))
    ])
  ]

在这个例子中,我们定义动画中的元数据的动画风格(颜色,变换)内联。在即将到来的 Angular 发布中,将支持增加了从组件CSS样式表拉样式来代替。

我们现在有定义动画,但是还没有使用的任何地方。我们可以通过将其附加到在使用“@triggerName”语法组件的模板的一个或多个元件改变:

template: `
  <ul>
    <li *ngFor="let hero of heroes"
        @heroState="hero.state"
        (click)="hero.toggleState()">
      {{hero.name}}
    </li>
  </ul>
`,

这里我们采用的动画触发由ngFor重复的每一个元素。每个重复元素将独立动画。我们结合属性表达hero.state的值。我们希望它永远是要么不活动或活动,因为这就是我们为定义动画状态。

有了这个设置,显示动画转换时的英雄对象改变状态!下面是完整的组件实现:

import {
  Component,
  Input,
  trigger,
  state,
  style,
  transition,
  animate
} from '@angular/core';
import { Heroes } from './hero.service';
@Component({
  moduleId: module.id,
  selector: 'hero-list-basic',
  template: `
    <ul>
      <li *ngFor="let hero of heroes"
          @heroState="hero.state"
          (click)="hero.toggleState()">
        {{hero.name}}
      </li>
    </ul>
  `,
  styleUrls: ['hero-list.component.css'],
  animations: [
    trigger('heroState', [
      state('inactive', style({
        backgroundColor: '#eee',
        transform: 'scale(1)'
      })),
      state('active',   style({
        backgroundColor: '#cfd8dc',
        transform: 'scale(1.1)'
      })),
      transition('inactive => active', animate('100ms ease-in')),
      transition('active => inactive', animate('100ms ease-out'))
    ])
  ]
})
export class HeroListBasicComponent {
  @Input() heroes: Heroes;
}

状态和转换

Angular 的动画在逻辑状态和状态之间的转换来定义的。

动画的状态是,我们在我们的应用程序代码中定义一个字符串值。在上面的例子中,我们使用了美国“活跃”,并根据英雄对象的逻辑状态“无效”。状态的来源可以是一个简单的对象属性,因为它是在这种情况下,也可以是在一个方法计算出的值。重要的是,我们可以将它读入组件的模板。

我们可以定义每个动画状态样式:

state('inactive', style({
  backgroundColor: '#eee',
  transform: 'scale(1)'
})),
state('active',   style({
  backgroundColor: '#cfd8dc',
  transform: 'scale(1.1)'
})),

这些状态的定义指定结束款式每个状态的。它们被施加到元件一旦已经转换到该状态,并且将留只要它保持在该状态。在这个意义上,我们定义不仅仅是动画这里。我们实际上是在定义元素在不同的状态是什么风格。

一旦我们的状态,我们可以定义状态间的转换。每过渡控制的一组的样式与下一个之间的切换的定时:

transition('inactive => active', animate('100ms ease-in')),
transition('active => inactive', animate('100ms ease-out'))

在 Angular 的动画,我们还确定了各国之间的状态和转换 如果我们有几个过渡相同的定时结构,我们可以将它们组合到相同的过渡定义:

transition('inactive => active, active => inactive',
 animate('100ms ease-out'))

当我们有一个过渡的两个方向相同的时间,就像我们在前面的例子中做的,我们可以用简写<=>语法:

transition('inactive <=> active', animate('100ms ease-out'))

有时候,我们有我们想要的动画过程中应用,但不能保持它周围结束后的风格。我们可以在过渡内嵌定义这种样式。在这个例子中,元件接收一组立即样式,然后动画到下一个。当过渡完成,没有这些样式将被保留,因为他们没有在一个国家定义。

transition('inactive => active', [
  style({
    backgroundColor: '#cfd8dc',
    transform: 'scale(1.3)'
  }),
  animate('80ms ease-in', style({
    backgroundColor: '#eee',
    transform: 'scale(1)'
  }))
]),

通配符*状态

在*(“通配符”)状态下的动画状态相匹配。这是定义样式和过渡应适用,无论何种状态的动画是有用,例如:

active => * 跃迁适用于当元素的状态改变从主动到别的。

有可能适用于任何动画一款专业的状态被称为无效。它适用于当元件未连接到的图。这可能是因为它尚未被添加,或者因为它已被删除。虚空状态是用于定义“输入”和“离开”动画是有用的。

例如,当元素离开鉴于* =>无效过渡适用,无论处于何种状态的它是在它离开之前。

空隙的状态可以用于进入和离开过渡 通配符*状态也匹配无效。

例子:输入和离开

进入和离开的动画 使用无效,*状态,我们可以定义动画进出元素的转换:

输入:void => 离开:\ => void

animations: [
  trigger('flyInOut', [
    state('in', style({transform: 'translateX(0)'})),
    transition('void => *', [
      style({transform: 'translateX(-100%)'}),
      animate(100)
    ]),
    transition('* => void', [
      animate(100, style({transform: 'translateX(100%)'}))
    ])
  ])
]

注意,在这种情况下,我们有直接在过渡定义施加到空隙状态的样式,而不是在一个单独的状态(无效)的定义。元素从左边进入和离开的权利:因为我们要的转换是在进入和离开不同,我们做到这一点。

例子:从不同的状态离开和进入

进入和离开的动画与国家动画相结合 我们也可以用英雄国家作为国家动画结合这个动画与早先的状态过渡动画。这是什么让我们做的是配置进入和基于什么英雄的状态是不同的离开转换:

Inactive hero enter: void => inactive
Active hero enter: void => active
Inactive hero leave: active => void
Active hero leave: inactive => void

我们现在有超过每次转换细粒度的控制:

这个例子活跃,不活跃,和无效状态之间的转换

animations: [
  trigger('heroState', [
    state('inactive', style({transform: 'translateX(0) scale(1)'})),
    state('active',   style({transform: 'translateX(0) scale(1.1)'})),
    transition('inactive => active', animate('100ms ease-in')),
    transition('active => inactive', animate('100ms ease-out')),
    transition('void => inactive', [
      style({transform: 'translateX(-100%) scale(1)'}),
      animate(100)
    ]),
    transition('inactive => void', [
      animate(100, style({transform: 'translateX(100%) scale(1)'}))
    ]),
    transition('void => active', [
      style({transform: 'translateX(0) scale(0)'}),
      animate(200)
    ]),
    transition('active => void', [
      animate(200, style({transform: 'translateX(0) scale(0)'}))
    ])
  ])
]

动画属性和单位

由于 Angular 的动画支持基础上的Web动画的顶部,我们可以动画浏览器认为动画的任何财产。这包括位置,大小,变换,颜色,边框等等。 W3C维护动画属性的列表。

对于具有一个数字值的位置的属性,我们可以通过提供值作为与适当的后缀的字符串定义一个单元:

'50px' '3em' '100%' 对于大多数dimensinal属性我们也可以只定义一个号码,然后假设在像素:

50是一样的说'50px“ 自动属性计算

动画与自动化的高度计算 有时候,我们想动画的尺寸样式属性的值不知道,直到在运行时。例如,它是很常见的元素,以具有依赖于它们的内容和屏幕尺寸的宽度和高度。这些特性往往是棘手的CSS动画。

与 Angular,我们可以使用在这些情况下,一种特殊的*属性值。它的意思是,这个属性的值将在运行时进行计算,然后插入动画。

本例中的“假”的动画需要任何高度的元件具有它离开并从该高度为零动画之前:

animations: [
  trigger('shrinkOut', [
    state('in', style({height: '*'})),
    transition('* => void', [
      style({height: '*'}),
      animate(250, style({height: 0}))
    ])
  ])
]

动画计时

有三个计时属性,我们可以调整为每一个动画过渡:持续时间,延迟和缓解作用。它们都被组合成一个单一的转换定时串。

为期

持续时间控制动画需要多长时间运行,从开始到结束。我们可以通过三种方式定义的持续时间:

作为一个普通的数字,以毫秒为单位:100 在一个字符串,如毫秒:“100毫秒” 在一个字符串,如秒:“0.1秒” 延迟

延迟控制等待多久动画触发后过渡实际开始之前。我们可以把它加在相同串的持续时间下列定义之一。它也具有相同的格式选项的持续时间:

等待100ms,然后为200ms的运行:“0.2S 100毫秒” 缓解

该缓和功能控制动画的加速和运行期间减速。例如,使用一个便于函数表示动画开始相对缓慢,但随后因为它的进展速度加快。我们可以通过的持续时间和延迟后的字符串中加入作为第三值控制宽松(或当没有延迟的第二值):

等待100ms,然后为200ms的运行,以缓和:“0.2S 100ms的渐出” 对于运行200毫秒,以缓和:“0.2S易于在出' 具体的时序动画 例

这里有一对夫妇在行动自定义定时。这两个“输入”,并在200毫秒内“离开”最后,但他们有不同的渐变效果。稍有延迟后的假期开始了:

animations: [
  trigger('flyInOut', [
    state('in', style({opacity: 1, transform: 'translateX(0)'})),
    transition('void => *', [
      style({
        opacity: 0,
        transform: 'translateX(-100%)'
      }),
      animate('0.2s ease-in')
    ]),
    transition('* => void', [
      animate('0.2s 10 ease-out', style({
        opacity: 0,
        transform: 'translateX(100%)'
      }))
    ])
  ])
]

多步动画关键帧

一些反弹动画关键帧来实现 与动画关键帧我们能够超越两套样式之间的简单过渡到一个更复杂的动画,通过一个或多个中间样式之间去。

对于每一个关键帧,我们可以指定一个偏移量,在该应用关键帧动画定义在这一点上。该偏移量是零之间的数值,这标志着动画的开始,和一个,这标志着结束。

在这个例子中,我们添加一些“反弹”我们进入和离开的动画关键帧:

animations: [
  trigger('flyInOut', [
    state('in', style({transform: 'translateX(0)'})),
    transition('void => *', [
      animate(300, keyframes([
        style({opacity: 0, transform: 'translateX(-100%)', offset: 0}),
        style({opacity: 1, transform: 'translateX(15px)',  offset: 0.3}),
        style({opacity: 1, transform: 'translateX(0)',     offset: 1.0})
      ]))
    ]),
    transition('* => void', [
      animate(300, keyframes([
        style({opacity: 1, transform: 'translateX(0)',     offset: 0}),
        style({opacity: 1, transform: 'translateX(-15px)', offset: 0.7}),
        style({opacity: 0, transform: 'translateX(100%)',  offset: 1.0})
      ]))
    ])
  ])
]

注意,该偏移不是绝对时间定义的。他们是从0到1的相对措施动画的最终时间表将根据关键帧偏移量,持续时间,延迟和宽松的结合。

限定偏移量的关键帧是可选的。如果我们忽略他们,即使间距偏移自动分配。例如,三个关键帧没有预定义的偏移将接收偏移0,0.5和1。

并行动画组

并行动画不同的时序,以实现群体 我们已经看到我们如何可以动画在同一时间多个样式属性:只要把他们都到相同的风格()的定义!

但是,我们也可能想在平行中发生的动画配置不同的时序。例如,我们可能要进行动画两个CSS特性,但使用不同的缓动函数为每一个。

为此,我们可以使用动画组。在这个例子中,我们使用的进入和离开,这样我们可以使用两种不同的时序配置组两者。两者都施加到并联的相同元素,但运行相互独立的:

animations: [
  trigger('flyInOut', [
    state('in', style({width: 120, transform: 'translateX(0)', opacity: 1})),
    transition('void => *', [
      style({width: 10, transform: 'translateX(50px)', opacity: 0}),
      group([
        animate('0.3s 0.1s ease', style({
          transform: 'translateX(0)',
          width: 120
        })),
        animate('0.3s ease', style({
          opacity: 1
        }))
      ])
    ]),
    transition('* => void', [
      group([
        animate('0.3s ease', style({
          transform: 'translateX(50px)',
          width: 10
        })),
        animate('0.3s 0.2s ease', style({
          opacity: 0
        }))
      ])
    ])
  ])
]

一组动画元素变换和宽度。其他动画的不透明度。