Angular 2/4—路由动画教程及示例
Angular 2/4—路由动画教程及示例
TERRILL-T 发表于6个月前
Angular 2/4—路由动画教程及示例
  • 发表于 6个月前
  • 阅读 1597
  • 收藏 23
  • 点赞 2
  • 评论 2
摘要: 个人翻译的第一篇技术文章,转载请引用全文,标明原文链接。 ------------ 为了便于阅读,以下 Angular 统一代表 Angular2/4 版本,AngularJS 代表 Angular1.x 版本 在这个教程里,将告诉你如何使用 Angular 和 TypeScript 在路由转场间执行动画

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,state,animate,transition,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,state,animate,transition,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, 0, 0.8)'
        })),
        // 路由 '进入' 过渡
        transition(':enter', [
            // 过渡开始时的样式
            style({
                // 开始是内容区域相对于右侧的位置
                // -400%代替100%,是由于负位置增加了元素的宽度
                right: '-400%',
                // 开始时背景是全透明的
                backgroundColor: 'rgba(0, 0, 0, 0)'
            })
            // 动画和结束时的样式状态
            animate('.5s ease-in-out', style({
                // 过渡到右侧为0,让内容进入视图
                right: 0,
                // 过渡背景从透明到0.8
                backgroundColor: 'rgba(0, 0, 0, 0.8)'
            }))
        ]),
 
        // 路由'离开'过渡
        transition(':leave', [
            // 在过渡结束的动画和样式
            animate('.5s ease-in-out', style({
                // 过渡到右侧-400%,加了位移的内容宽度
                right: '-400%',
                // 过渡背景透明度为0淡出
                backgroundColor: 'rgba(0, 0, 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 >

共有 人打赏支持
粉丝 2
博文 2
码字总数 6685
评论 (2)
1felse
1
奥道易通短信平台
更新分享
×
TERRILL-T
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: