Angular 2/4—路由动画教程及示例
为了便于阅读,以下 Angular 统一代表 Angular2/4 版本,AngularJS 代表 Angular1.x 版本
在这个教程里,将告诉你如何使用 Angular 和 TypeScript 在路由转场间执行动画
项目代码地址:https://github.com/cornflourblue/angular2-animation-tutorial-example
查看使用 AngularJS 的路由动画示例:http://jasonwatmore.com/post/2016/01/20/angular-nganimate-tutorial-with-ui-router
Angular 动画和 AngularJS 动画间的不同
Angular 动画的工作方式与 AngularJS 中动画的工作方式是完全不同的,在 AngularJS 中通过 CSS 类钩子来实现视图切入和切出时的元素动画,但在 Angular 中,在你的组件中动画的执行是依靠一个方法的集合来实现的,这些方法包括 ( trigger,state,animate,transition,style ) ,集成在 @angular/animations 模块中
仍然使用 CSS 定义动画样式,但它们是写在 Typescript 中的 JSON 对象(TSON?)而不是 CSS / LESS 文件编写的,还有一种新的 Angular 动画 DSL(Domain Specific Language),创建它们用于定义不同的路由状态和路由之间转扬切换。 因为可以在Angular网站上找到所有这些详情信息,所以我不会太多地讲解所有新的动画系统的细节,而是将重点放在一个例子上以及如何在路由之间进行动画处理。
如果你觉得新的Angular动画系统让你痛苦的想撞墙,不要沮丧;很长一段时间内我也是抓耳挠腮很尴尬,但我仍然要掌握它!
Angular 动画教程示例
这里提供一个可以运转的教程示例应用,在顶级的标签切换使用淡入淡出的过渡,添加产品和修改产品页面使用滑入滑出的过渡动画。
在 Plunker 中查看示例 http://plnkr.co/edit/AfIB1i?p=preview
在本地运行 Angular 动画教程示例
1,通过 https://nodejs.org/en/download/ 安装 NodeJS 和 NPM,命令行运行 node -v 和 npm -v 检测安装版本
2,下载项目源代码:https://github.com/cornflourblue/angular2-animation-tutorial-example
3,在项目的根目录 ( package.json 所在的目录),通过 npm install 命令安装相关依赖的包
4,通过在项目根目录运行 npm start 命令启动应用
让我们专注于动画
我尝试制作一个真实领域的应用,所以它包含了少量的 Services 和一些其它的东西;但是在文中我将专注于动画和把这些动画怎样添加到 Angular 的路由中去。
在 app.module.ts 中导入 BrowserAnimationsModule 模块
随着 Angular4 的发布,animations 模块已经从 Angular 核心模块中拆分到他们自己的模块中,所以,你不得不在 app.module.ts 文件顶部中引入 BrowserAnimationsModule 模块。
- import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
并且在@NgModule元数据中,把 BrowserAnimationsModule 添加到 imports 列表中。
- @NgModule({
- imports:[
- ...,BrowserANimationsMdoule
- ],...
- })
- export class AppModule{}
第一个导入使 BrowserAnimationsModule 在 app.module.ts 文件中可用,
第二个导入使 BrowserAnimationsModule 中的方法可以在包含在 AppModule 中的其它组件中使用
定义你的 Angular 动画
Animations 可以被直接定义在你的组件里,但我更喜欢把它们分离出来到它们自己的文件中,这样可以让这些动画在多处重用,并且可以使得你的组件代码更加清晰,更加易于维护和关注点分离。
在这个例子了中,我把动画放在了 app/_animations 文件夹中,我偏爱为无特征的文件夹加一个下划线前缀 [" _ "],目的是为了和那些特征性文件夹在最顶级目录做区分,特征文件夹用来存放应用的视图或者路由代码,像首页和产品页,无特征文件夹包含那些共享重用的代码,像 services,animations,directives,css等基本一切代码。
Angular 淡入动画
在示例中,淡入动画被用于主页组件和产品列表组件
- //从angular animations module 导入需要的动画方法
- import {trigger,style} from '@angular/animations';
- export const fadeInAnimation=
- //触发器名称,附加这个动画到元素上使用[@triggerName]语法
- trigger('fadeInAnimation',[
- //路由 '进入' 过渡
- transition(':enter',[
- //在过渡刚开始时的样式
- style({opacity:0}),//动画和过渡结束时的样式
- animate('.3s',style({opacity:1}))
- ])
- ])
Angular 滑入滑出动画
在示例中,滑入滑出动画被用在产品的添加和编辑组件上
- //从angular animations module 导入需要的动画方法
- import {trigger,style} from '@angular/animations';
- export const slideInOutAnimation=
- //触发器名称,附加这个动画到元素上使用[@triggerName]语法
- trigger('slideInOutAnimation',[
- // 路由容器的最终状态样式 (host)
- state('*',style({
- // 视图覆盖整个屏幕并且半透明背景
- position: 'fixed',top: 0,left: 0,right: 0,bottom: 0,backgroundColor: 'rgba(0,0.8)'
- })),// 路由 '进入' 过渡
- transition(':enter',[
- // 过渡开始时的样式
- style({
- // 开始是内容区域相对于右侧的位置
- // -400%代替100%,是由于负位置增加了元素的宽度
- right: '-400%',// 开始时背景是全透明的
- backgroundColor: 'rgba(0,0)'
- })
- // 动画和结束时的样式状态
- animate('.5s ease-in-out',style({
- // 过渡到右侧为0,让内容进入视图
- right: 0,// 过渡背景从透明到0.8
- backgroundColor: 'rgba(0,0.8)'
- }))
- ]),// 路由'离开'过渡
- transition(':leave',[
- // 在过渡结束的动画和样式
- animate('.5s ease-in-out',style({
- // 过渡到右侧-400%,加了位移的内容宽度
- right: '-400%',// 过渡背景透明度为0淡出
- backgroundColor: 'rgba(0,0)'
- }))
- ])
- ])
附加 Angular 动画到你路由的组件上
随着动画清晰的被分离进他们自己的文件,这样更容易附加它们到你的 Angular 路由,你需要做的就是导入动画到你想要添加的组件的 @Component 元数据中。
Angular 首页组件淡入动画
- import { Component } from '@angular/core';
- // 导入淡入动画
- import { fadeInAnimation } from '../_animations/index';
- @Component({
- moduleId: module.id.toString(),templateUrl: 'home.component.html',// 添加使用淡入动画在组件可用
- animations: [fadeInAnimation],// 附加淡入动画到组件的最外层元素上
- host: { '[@fadeInAnimation]': '' }
- })
- export class HomeComponent {}
Angular 添加淡入动画的产品列表组件
示例中添加了淡入动画的产品列表组件
- import { Component,OnInit,OnDestroy } from '@angular/core';
- import { Subscription } from 'rxjs/Subscription';
- import { ProductService,PubSubService } from '../_services/index';
- // 导入淡入动画
- import { fadeInAnimation } from '../_animations/index';
- @Component({
- moduleId: module.id.toString(),templateUrl: 'product-list.component.html',// 使淡入动画在组件中可用
- animations: [fadeInAnimation],// 添加淡入动画到组件的最外层元素上
- host: { '[@fadeInAnimation]': '' }
- })
- export class ProductListComponent implements OnInit,OnDestroy {
- products: any[];
- subscription: Subscription;
- constructor(
- private productService: ProductService,private pubSubService: PubSubService) { }
- deleteProduct(id: number) {
- this.productService.delete(id);
- this.loadProducts();
- }
- ngOnInit() {
- this.loadProducts();
- // 当更新时重载产品视图
- this.subscription = this.pubSubService.on('products-updated').subscribe(() => this.loadProducts());
- }
- ngOnDestroy() {
- // 取消订阅避免内存泄漏
- this.subscription.unsubscribe();
- }
- private loadProducts() {
- this.products = this.productService.getAll();
- }
- }
Angular 添加滑入滑出效果的产品添加编辑组件
- import { Component,OnInit } from '@angular/core';
- import { Router,ActivatedRoute } from '@angular/router';
- import { ProductService,PubSubService } from '../_services/index';
- // 导入滑入滑出动画
- import { slideInOutAnimation } from '../_animations/index';
- @Component({
- moduleId: module.id.toString(),templateUrl: 'product-add-edit.component.html',// 使滑入滑出动画在组件中可用
- animations: [slideInOutAnimation],// 添加滑入滑出动画到组件最外层的元素上
- host: { '[@slideInOutAnimation]': '' }
- })
- export class ProductAddEditComponent implements OnInit {
- title = 'Add Product';
- product: any = {};
- constructor(
- private route: ActivatedRoute,private router: Router,private productService: ProductService,private pubSubService: PubSubService) { }
- ngOnInit() {
- let productId = Number(this.route.snapshot.params['id']);
- if (productId) {
- this.title = 'Edit Product';
- this.product = this.productService.getById(productId);
- }
- }
- saveProduct() {
- // 保存产品
- this.productService.save(this.product);
- // 重定向到products视图
- this.router.navigate(['products']);
- // 发布产品更新事件
- this.pubSubService.publish('products-updated');
- }
- }
附注:Angular动画是基于标准的Web动画API(Web Animations API)构建的,它们在支持此API的浏览器中会用原生方式工作。至于其它浏览器,就需要一个填充库(polyfill)了。你可以从这里获取web-animations.min.js
,并把它加入你的页面中。
> 个人翻译的第一篇技术文章,转载请注明翻译者:TERRILLTANG >
> 原文地址:http://jasonwatmore.com/post/2017/04/19/angular-2-4-router-animation-tutorial-example >