资讯专栏INFORMATION COLUMN

使用Angular4动画为页面添彩

jay_tian / 3696人阅读

摘要:使用组件将根据视口放置,并滑过页面。这意味着我们不能使用状态来对路由组件进行样式,因为这样可以将样式应用于父结点我们的示例中的主元素,而不是路由组件。

原文:Angular — Supercharge your Router transitions using new animation features (v4.3+)

首先我们看一下效果展示的demo

Basic

Variation

Stagger

Final

样例

为了介绍这个新的动画,我们将用一个只有home和about页面的简单应用来做演示。我们将要用内容向左飞出然后用下图所示的交错进入的效果实现一个很酷的路由页面切换

动画依赖安装

独立引入Angular 4里的动画部分,这样可以使你的项目更轻便,如果你不想用动画的话只要直接拿掉就可以了

首先,我们把下列依赖独立引入你的项目:@angular/animations@angular/platform-browser/animations 接下来在项目中的入口模块的代码引入 BrowserAnimationsModule

app.module.ts

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";

@NgModule({
  imports: [ BrowserModule, BrowserAnimationsModule, ... ],
  declarations: [ App, ... ],
  bootstrap: [ App ]
})
export class AppModule { }

如果你需要使用 不支持原生WEB动画API的浏览器 的话:比如IE、Edge、Safari等等。你必须要引入web-animations依赖

正如我们所见,我们的例子将由顶部导航和主体内容部分组成。各个内容部分将共享同一个导航栏,我们使用router-outlet元素来通知路由我们需要渲染组件的地方和需要匹配路由的地方

app.module.ts

@Component({
  selector: "my-app",
  template: `
    
    
` }) export class App { }

我们使用静态路由来创建不同的导航链接。然后我们用routerLinkActive指令来装饰当前的内容部分。举个例子,如果我们要导航到首页Home,导航链接的标签上将加上active选择器并根据这个渲染对应部分

Home
添加路由转换

让我们改变默认的路由变换设置。首先我们需要加上动画触发器属性 routerTransition ,然后我们绑定@routerTransition在主标签元素上,之后,我们可以装饰内部的路由组件并交由Angular的路由来实例化

我们可以用一个div或者其他标签来替换主标签元素,只要它是router-outlet的父结点

我们用getState方法传递外部设置的参数来设置正确的状态。这个方法将返回一个 state 的用于设置路由定义的属性。我们接下来看下一个部分,这个设置将允许我们去控制每个路由将执行哪种切换

提示:我们可以通过使用#o="outlet"来获得外部传参,由于在router-outlet definition里使用exportAs使之成为可能。这给了我们一个快速获取底层RouterOutlet选择器类的途径

app.module.ts

@Component({
  selector: "my-app",
  animations: [ routerTransition ],
  template: `
    
` }) export class App { getState(outlet) { return outlet.activatedRouteData.state; } }
设置路由

在Angular里面,路由会去尝试匹配路由定义和当前的url,同一个生效的配置优先级由上到下

app.routing.ts

const routes = [
  { path: "", redirectTo: "home", pathMatch: "full" },
  { path: "home", component: Home, data: { state: "home" } },
  { path: "about", component: About, data: { state: "about" } },
  { path: "**", component: NotFound }
];

export const AppRouting = RouterModule.forRoot(routes, { 
  useHash: true
});

路由设置告诉路由当匹配到Home和About页面的路径时去实例化对应的组件。注意这个data属性设置每个状态给对应的路由。这些状态将要去匹配我们在routerTransition中设置的切换

我们也需要设置两个为了通常展示的特殊路由。这个空路径的路由将提供一个默重定向到主页的路由以防导航去了一个非我们需要的路径。其他的路由或者未定义的路由展示一个用户友好的404页面就好

为了这个例子,因为Plunker的原因我们使用一个哈希定位的策略。如果我们需要后端我们可以沿用普通的路径跳转,但是如果没有后端来展示404错误的话我们就使用这个策略来重定向未知路径到index.html

Angular 动画

让我们隆重介绍Angular动画。Angular是基于最新的Web Animations API,我们使用动画触发器(animation triggers)来定义一系列状态和变换属性。我们也可以用CSS样式来改写实现我们想要的效果

主要的原则是开始和结尾的动画样式由我们自定义,中间变换的计算过程交给工具本身

当然,可以通过设置时间来设置中间动画,比如1s,1.2s,200ms。其他的就是大家熟悉的CSS动画的速度属性比如easelinerease-in-out

而Angular 4.2以上的版本里我们可以用顺序(sequence)和组合(group)来让动画一个接一个执行还是同时执行;查询(query)可以操作子元素而交错(stagger)可以创造一个很棒的连锁效果

这些事件将触发一个动画:

向或者从视图里装载或者卸载一个元素

改变已绑定触发器的状态 比如:[@routerTransition]="home"

在路由转换的前后关系中,要注意,组件正在被移除并作为导航的一部分被添加到视图中的过程。

定义动画

首先让我们看一下如何使用Angular动画来让内容向左滑出

最初,定义我们的触发器routerTransition。在这个实现中,我们使用了一个覆盖所有可能状态的通用转换

这是个通过两个独立转换* => home* => about完成的重写

我们可以在我们的转换中用两个特殊标识 void*来代表:一个元素尚未被挂载到视图或者任何状态


outer.animations.ts

import {trigger, animate, style, group, animateChild, query, stagger, transition} from "@angular/animations";

export const routerTransition = trigger("routerTransition", [
  transition("* <=> *", [
    /* order */
    /* 1 */ query(":enter, :leave", style({ position: "fixed", width:"100%" })
      , { optional: true }),
    /* 2 */ group([  // block executes in parallel
      query(":enter", [
        style({ transform: "translateX(100%)" }),
        animate("0.5s ease-in-out", style({ transform: "translateX(0%)" }))
      ], { optional: true }),
      query(":leave", [
        style({ transform: "translateX(0%)" }),
        animate("0.5s ease-in-out", style({ transform: "translateX(-100%)" }
      ], { optional: true }),
    ])
  ])
])

我们在第二个参数里定义了一个顺序执行通用转换的数组 。第一个参数呢,使用了一个新的查询指令去选择新的路径组件和离开的组件;查询指令可以使用类似CSS伪类的选择器方式选中,比如一些特殊的关键词::enter:leave*

在第一次查询中,:enter:leave将会匹配被挂载和卸载的组件,多个选择器用逗号分开。一旦我们有了这些路由组件,我们可以设置他们的样式去达到滑动的效果。使用 { position: fixed } 组件将根据视口放置,并滑过页面。

接下来,我们将设置一个组合使得内部动画同时执行。

让我们想象一下,我们从Home切换到About页面,第一次查询将会匹配这个被加了:enter的组件,那就是About组件。我们首先在右边很远的地方设置动画,然后让它缓缓的进入滑动到固定的位置。结果就是About组件从右边滑到左边。第二次查询中,我们用了一个相似的路径,使用:leave来匹配同样在左边很远处的Home组件

CSS小提示:为了更好的表现,我们使用transform取代top,bottom,left,right

注意这种实现方式与我们将触发器绑定到我们想要动画的元素的动画中的用例不同。
这意味着我们不能使用状态来对路由组件进行样式,因为这样可以将样式应用于父结点(我们的示例中的主元素),而不是路由组件。

在路由初始化期间,一些查询指令会返回空的结果,为了避免抛出错误,我们在所有查询中设置了可选参数。

加上交错动画

一旦我们的基础部分完成了,我们可以很容易在这个基础上用查询和交错控制加上一些新的效果

export const routerTransition = trigger("routerTransition", [
  transition("* <=> *", [
    /* order */
    /* 1 */ query(":enter, :leave", ...),
    /* 2 */ query(".block", style({ opacity: 0 })),
    /* 3 */ group([  // block executes in parallel
      query(":enter", [...]),
      query(":leave", [...]),
    ]),
    /* 4 */ query(":enter .block", stagger(400, [
      style({ transform: "translateY(100px)" }),
      animate("1s ease-in-out", 
        style({ transform: "translateY(0px)", opacity: 1 })),
    ])),
  ])
])

最终,我们使用转换(transform)和透明(opacity)来垂直向上滑动进入并淡入。
通过使用交错,我们为每个动画引入了一个小的延迟(以毫秒为单位),创建了一个很好的窗帘效果。最后一点,我们不得不引入一个新的查询,用(opacity:0)初始化.block元素,这样当组件滑入时就不会显示。

最终步骤

作为最终的润色,我添加了一些反向交错离开Home组件的代码并且也加入了贝塞尔曲线来优化路径,最后效果如下图

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84462.html

相关文章

  • ReactNative开发常用的三方模块

    摘要:写在前面一个好的缺不了好的三方支持,生活在这个活跃的开源社区,寻找合适的三方组件是一个开发者最基本的能力。下面分享几个我收集的三方模块,希望对大家有点帮助。 写在前面 一个好的App缺不了好的三方支持,生活在ReactNative这个活跃的开源社区,寻找合适的三方组件是一个开发者最基本的能力。不过不积跬步,无以至千里,不积小流,无以成江海。下面分享几个我收集的三方模块,希望对大家有点帮...

    frolc 评论0 收藏0
  • Angular2 VS Angular4 深度对比:特性、性能

    摘要:的特性和性能是的超集,用于帮助的开发。注解提供了连接元数据和功能的工具。通过在库中提供基本信息可以调用函数或创建类的实例来检查相关元数据,从而简化了对象实例的构建。停用它会响应跳出旧控制器的成功事件。 showImg(https://segmentfault.com/img/bVSqTU?w=850&h=460); 在Web应用开发领域,Angular被认为是最好的开源JavaScri...

    孙淑建 评论0 收藏0
  • angular4动画使用

    摘要:引入动画模块的动画模块是独立出去,所以要通过来下拉动画模块在中导入动画模块并注册注册下面就开始写一个简单的动画这里是封装好动画引入,在里面新建一个文件引入动画需要的模块编写默认,出场,离场的动画下面是实现代码之后和平时使用动画差不多 引入动画模块 angular4的动画模块是独立出去,所以要通过npm来下拉动画模块 npm install -S @angular/animations...

    chadLi 评论0 收藏0
  • 使用angular4.0来搭建一个博客类的项目

    摘要:前言也就是的最新版本最近也是大红大紫的公司项目主管推上学习日程自己也就抽时间写了一个小的博客类的意在于去看一下最新的特性和的语法由于刚接触和所以有点小糙望见谅项目原址我是项目地址我是地址项目简介整个项目是使用脚手架搭建的项目目录结构项目功 前言 angular也就是angular.js的最新版本,最近也是大红大紫的公司项目主管推上学习日程,自己也就抽时间写了一个小的博客类的demo,意...

    BakerJ 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<