Angular动画
Angular动画基于W3C的Web Animations标准。不在Angular Core中了。


组件里面定义一个或多个触发器trigger,每个触发器有一系列的状态和过渡效果来实现。
动画其实就是从一个状态过渡到另一个状态。状态本身包含形状,颜色,大小等。
核心是State和Transition。
State就是定义每一帧状态
Transition是定义一帧到下一帧如何过渡。
transition中定义animation,Animate规定了具体怎样过渡,比如时间,过渡的速度等。Animate有多个重载形式。
一、例子
先安装动画库
npm i --save @angular/animations
导入module
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
imports: [
...
BrowserAnimationsModule, //放在最后导入
],
定义一个宽度100的黑色正方形。
.square{
width: 100px;
height: 100px;
background-color:black;
align-items: center;
}
在animations元数据中定义一个触发器,触发器名字叫square。html的响应元素中[@square]是动画的触发器的名字。这个变量或者函数在某一情况下改变元素的状态。
<div class="square" [@square]="squareState" (click)="onClick()">
</div>
触发器有2个重要组成State和Transition。
State定义状态,在不同的状态下应用不同的样式。通过style把一些css样式应用于实现动画的元素,定义好某一帧的颜色,大小,位置。
Transition负责在不同状态切换时候做怎样的变换,定义如何迁移状态,如何过渡。
import { trigger, state, transition, style, animate } from '@angular/animations';
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
animations: [
trigger('square', [
state('green', style({ 'background-color': 'green','height':'100px','transform':'translateX(0)' })),
state('red', style({ 'background-color': 'red','height':'50px' ,'transform':'translateX(100%)'})),
transition('green=>red', animate('.2s 1s')),//动画持续的时间,延迟多久开始
transition('red=>green', animate()),
])
]
})
export class AppComponent {
squareState:string;
onClick(){
this.squareState = this.squareState ==='red'?'green':'red';
}
}
二、缓动函数
动画执行时候的速度,使其看起来更加真实。
因为不是所有的动画都是匀速的,可以先加速后减速。
例如:皮球下落,先是越调越快,撞到地上后回弹最终才又碰到地板。
例子:
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
animations: [
trigger('square', [
state('green', style({ 'background-color': 'green','height':'100px','transform':'translateY(-100%)' })),
state('red', style({ 'background-color': 'red','height':'100px' ,'transform':'translateY(100%)'})),
transition('green=>red', animate('.8s ease-in')),
transition('red=>green', animate('.8s ease-out')),
])
]
})
可以在一个网站看到动画的速度

可以参考:
三、关键帧
不是所有的cubic-bezier函数都能在css动画中得到支持,可以通过关键帧来实现。
keyframes是一个数组,里面定义每一帧的样式。
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
animations: [
trigger('square', [
state('green', style({ 'background-color': 'green','height':'100px','transform':'translateY(-100%)' })),
state('red', style({ 'background-color': 'red','height':'100px' ,'transform':'translateY(100%)'})),
transition('green=>red', animate('.8s ease-in')),
transition('red=>green', animate(, keyframes([
style({transform:'translateY(100%)'}),
style({transform:'translateY(98%)'}),
style({transform:'translateY(95%)'}),
style({transform:'translateY(90%)'}),
style({transform:'translateY(80%)'}),
style({transform:'translateY(60%)'}),
style({transform:'translateY(30%)'}),
style({transform:'translateY(0)'}),
style({transform:'translateY(-10%)'}),
style({transform:'translateY(-5%)'}),
style({transform:'translateY(-2%)'}),
style({transform:'translateY(0)'}),
style({transform:'translateY(10%)'}),
style({transform:'translateY(15%)'}),
style({transform:'translateY(-15%)'}),
style({transform:'translateY(-40%)'}),
style({transform:'translateY(-80%)'}),
style({transform:'translateY(-90%)'}),
style({transform:'translateY(-95%)'})
])))
])
]
})
四、实际应用
把动画分离出来,不要和组件强耦合。
新建一个文件夹animate放所有的动画文件。
1、card相关的动画——绑定到宿主
新建一个card.animate.ts放card相关的动画。
import { trigger, state, transition, style, animate ,keyframes} from '@angular/animations';
export const cardAnim = trigger('card',[
state('out',style({transform:'scale(1)','box-shadow':'none'})),
state('hover',style({transform:'scale(1.1)','box-shadow':'3px 3px 5px 6px #ccc'})),
transition('out => hover',animate('200ms ease-in')),
transition('hover => out',animate('200ms ease-out'))
]);
在project-item里使用动画。
1、从@angular/core里导入HostBinding。
2、引入另外一个HostListener
监听鼠标enter和leave的事件
@HostListener('mouseenter', ['$event.target'])
onMouseEnter(target) {
this.cardState = 'hover';
}
@HostListener('mouseleave', ['$event.target'])
onMouseLeave(target) {
this.cardState = 'out';
}
import { Component, OnInit, Input, EventEmitter, Output ,HostBinding ,HostListener} from '@angular/core';
import { cardAnim } from '../../animate/card.animate'
@Component({
selector: 'app-project-item',
templateUrl: './project-item.component.html',
styleUrls: ['./project-item.component.scss'],
animations:[
cardAnim
]
})
export class ProjectItemComponent implements OnInit {
@Input() item;
@Output() onInvite = new EventEmitter<void>();
@Output() onEdit = new EventEmitter<void>();
@Output() onDelete = new EventEmitter<void>();
@HostBinding('@card') cardState = 'out';
constructor() { }
ngOnInit() {
}
@HostListener('mouseenter')
onmouseenter(){
this.cardState = 'hover'
}
@HostListener('mouseleave')
onmouseleave(){
this.cardState = 'out'
}
onInviteClick() {
this.onInvite.emit();
}
onEditClick() {
this.onEdit.emit();
}
onDeleteClick(){
this.onDelete.emit();
}
}

2、task相关的动画——绑定到部分元素
不是组件本身的动画,而是组件中一部分元素的动画。
新建一个item.animate.ts放task相关的动画
import { trigger, state, transition, style, animate ,keyframes} from '@angular/animations';
export const itemAnim = trigger('item',[
state('in',style({'border-left-width':'3px'})),
state('out',style({'border-left-width':'8px'})),
transition('in => out',animate('200ms ease-in')),
transition('out => in',animate('200ms ease-out'))
]);
在test-item中使用
import { Component, OnInit, Input, EventEmitter, Output, HostListener } from '@angular/core';
import {itemAnim} from '../../animate/item.animate';
@Component({
selector: 'app-task-item',
templateUrl: './task-item.component.html',
styleUrls: ['./task-item.component.scss'],
animations:[
itemAnim
]
})
export class TaskItemComponent implements OnInit {
@Input() item;
@Input() avatar: string;
@Output() taskClick = new EventEmitter<void>();
widerPriority = 'in';
constructor() { }
ngOnInit() {
this.avatar = this.item.owner ? this.item.owner.avatar : 'unassigned';
}
@HostListener('mouseenter')
onmouseenter(){
this.widerPriority='out';
}
@HostListener('mouseleave')
onmouseleave(){
this.widerPriority='in';
}
onItemClick() {
this.taskClick.emit();
}
onCheckBoxClick(event: Event): void {
event.stopPropagation();
}
}
在模版中用
<mat-list-item class="container"
[@item]="widerPriority"
[ngClass]="{
'priority-normal':item.priority===3,
'priority-important':item.priority===2,
'priority-emergency':item.priority===1
}"
(click)=onItemClick()>
<mat-checkbox [checked]="item.completed" class="status" (click)="onCheckBoxClick($event)"> </mat-checkbox>
<div class="content" mat-line [ngClass]="{'completed':item.completed}">
<span [matTooltip]="item.desc">{{item.desc}}</span>
</div>
<div class="bottom-bar" mat-line>
<span class="due-date" *ngIf="item.dueDate">
{{item.dueDate | date:"yy-MM-dd"}}
</span>
<mat-icon *ngIf="item.reminder">
alarm
</mat-icon>
</div>
<mat-icon [svgIcon]="avatar" mat-list-avatar class="avatar"> </mat-icon>
</mat-list-item>
效果

Angular动画的更多相关文章
- angular动画知识点以及代码样例
原文地址 https://www.jianshu.com/p/4400174072e2 大纲 1.angular动画的相关概念 2.angular动画的绑定方式 3.angular动画代码实例 1.a ...
- Angular动画(ng-repeat)
ng-repeat 动画 根据列表元素的插入与移除,触发相应的代码添加动画 <!doctype html> <html lang="en" ng-app=&quo ...
- Angular 动画
1.先做一个简单的例子 => 定义一个div 从open渐变成closed ts:定义一个触发器 openClose,有两个状态 open 和 closed,均有对应的样式,再定义装换函数 ...
- Angular动画——路由动画及高阶动画函数
一.路由动画 路由动画需要在host元数据中指定触发器.动画注意不要过多,否则适得其反. 内容优先,引导用户去注意到某个内容.动画只是辅助手段. 定义一个进场动画,一个离场动画. 因为进场动画和离场动 ...
- Angular动画(ng-class)
ng-class 同 触发的是 addClass//当给元素添加一个class时触发, removeClass //把元素的class移除时触发 <ul ng-style="ulWid ...
- Angular 小试牛刀[1]:Getting Started
首先,Angular2 与 Angular1.x 版本没有多大关系,甚至可以说是两个完全不一样的框架,故 Angular 指的是 Angular2 及以上的版本.而 Angular 与 TypeScr ...
- 动态创建angular组件实现popup弹窗
承接上文,本文将从一个基本的angular启动项目开始搭建一个具有基本功能.较通用.低耦合.可扩展的popup弹窗(脸红),主要分为以下几步: 基本项目结构搭建 弹窗服务 弹窗的引用对象 准备作为模板 ...
- 从源码看 angular/material2 中 dialog模块 的实现
本文将探讨material2中popup弹窗即其Dialog模块的实现. 使用方法 引入弹窗模块 自己准备作为模板的弹窗内容组件 在需要使用的组件内注入 MatDialog 服务 调用 open 方法 ...
- angular学习第1步
#### 最专业,最全面的angular的学习文档 https://www.jianshu.com/p/f0f81a63cbcb ### https://www.cnblogs.com/xiaowei ...
随机推荐
- [SDOI2017]天才黑客
题目大意 给一张有向图,再给一颗字典树,有向图上的每条边有一个非负边权还有一个字典树上的字符串,从一条边到另一条边的代价是那条边的边权和这两个字符串的最长公共前缀,问从1到其他点的最短路. 题解 一看 ...
- 20165223《网络对抗技术》Exp0 Kali的安装
(1)安装步骤 Kali官网,下载Kali Linux 64 bit版本,按照网上安装教程进行即可 我是直接拷贝了Kali的.vmx文件(Linux 64bit),在上学期已经安装好的VMware中可 ...
- python第十四天
今日内容 1. 带参装饰器 | wrapper 2. 迭代器 3. 可迭代对象 4.迭代器对象 5.for 迭代器 6.枚举对象 带参装饰器 是指装饰器为被装饰的函数添加新功能,需要外界的参数 - ...
- mysq建表参数设置
建表的完整性约束: not null 与 default unique primary auto_increment foreign key 外键的变种 三种关系 一.介绍 约束条件与数据类型的宽度 ...
- Python菜鸟快乐游戏编程_pygame(1)
Python菜鸟快乐游戏编程_pygame(博主录制,2K分辨率,超高清) https://study.163.com/course/courseMain.htm?courseId=100618802 ...
- 2018-2019 20165232 Exp5 MSF基础应用
2018-2019 20165232 Exp5 MSF基础应用 一.原理与实践说明 1.实践内容 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: 一个 ...
- [面试]future模式
Future模式 什么是future模式? 传统单线程环境下,调用函数是同步的,必须等待程序返回结果后,才可进行其他处理. Futrue模式下,调用方式改为异步. Futrue模式的核心在于:充分利用 ...
- DirectX11--实现一个3D魔方(1)
前言 可以说,魔方跟我的人生也有一定的联系. 在高中的学校接触到了魔方社,那时候的我虽然也能够还原魔方,可看到大神们总是可以非常快地还原,为此我也走上了学习高级公式CFOP的坑.当初学习的网站是在魔方 ...
- Eclipse——手把手教新手安装Eclipse
一.准备工作:安装JRE和JDK. 全名分别为:Java Runtime Environmen和Java SE Development Kit,推荐直接在某度软件中心下载即可,注意区分64位和32位. ...
- java常见题目总结
编写多线程程序的几种方法:java5以前可以通过继承Thread类或者实现Runnable接口,重写run方法来定义线程行为:java5以后出现了另一种方式,实现Callable接口,该接口的call ...