动画其实就是从一个状态过渡到另一个状态,状态本身包含形状颜色大小等等,State就是定义状态而Transition是定义如何过渡,state和transition构成了trigger
Animate规定了具体怎样过渡,比如时间、过渡的速度等,animate有多个重载形式
'1s 2s'
表示延迟1s,动画时长2snpm i --save @angular/animations
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
//引入animation的module
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserAnimationsModule,
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
import { Component } from '@angular/core';
//引入animation的对应内容
import { trigger,state,transition,style,animate } from '@angular/animations';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
animations: [
trigger('square',//trigger的名称
[
state('green',style({'background-color':'green','height':'200px'})),//定义状态green:定义状态的style
state('red',style({'background-color':'red','height':'100px'})),//定义状态red:定义状态的style
transition('red => green', animate(2000)),//从red到green的动画:动画持续2s
transition('green => red', animate('1s 2s')) //从green到red的动画:延迟1s,动画持续2s
]
)
]
})
export class AppComponent {
squareString = "red";//[@trigger名称]的对应内容
changeInfo() {//改变trigger的state
this.squareString = this.squareString === "red"? "green":"red";
}
}
<div style="text-align:center">
<!-- 使用 @trigger名称 绑定对应的state名 -->
<div class="squareDiv" [@square]="squareString" (click)="changeInfo()"></div>
</div>
.squareDiv {
width: 200px;
}
缓动函数指定动画效果在执行时的速度,使其看起来更加真实【例:当皮球下落,先是越掉越快,撞到地上后回弹最终才又触碰底板】【示例:transition('green => red',animate('.8s ease-in'))
表示动画时长0.8s,缓冲动画是ease-in格式】
easings.net/zh-cn#
W3C的Web Animation标准暂时无法支持所有的cubin-bezier函数帧-就是动画中最小单位的单幅影像画面
关键帧-物体运动或变化的关键动作所处的那一帧
示例:
transition('red => green', animate(5000,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%)'}),
style({transform:'translateY(100%)'})
])))//其实就是使用animate参数2定义keyframes关键帧上的动作内容(style)
在代码中使用Hostbinding注解绑定内容【是给当前元素绑定trigger】,如:
@HostBinding('@card')
cardState = 'out'
//表示给当前元素绑定trigger为@card,初识状态值为out
给当前元素绑定指定的监听事件内容,注解参数一是事件名称,参数二是事件对象数组,如:
@HostListener('mouseenter',['$event','$event.target'])
onMouseEnter(event,target) {
this.cardState = 'hover';
}
路由动画需要在host元数据中指定触发器
实例Demo
router.anim.ts
export const slideToRight = trigger('routerAnim',[
state('void',style({'position':'fixed','width':'100%','height':'80%'})),//void表示空状态
state('*',style({'position':'fixed','width':'100%','height':'80%'})),//*表示其他任意状态
//进场动画
transition(':enter',[//:enter相当于void => *
style({transform:'translateX(-100%)'}),
animate('.5s ease-in-out',style({transform:'translateX(0)'}))
]),
//出场动画
transition(':leave',[//:leave相当于* => void
style({transform:'tranlateX(0)'}),
animate('.5s ease-in-out',style({transform:'translateX(100%)'}))
])
])
定义路由动画,在切换路由的页面中全局绑定
//定义路由动画
@HostBinding('@routerAnimate') state;
Group是同时进行一组的动画变换【group([animate(...),animate(...)])
】
使用group定义一组动画
export const slideToRight = trigger('routerAnim',[
state('void',style({'position':'fixed','width':'100%','height':'80%'})),//void表示空状态
state('*',style({'position':'fixed','width':'100%','height':'80%'})),//*表示其他任意状态
//进场动画
transition(':enter',[//:enter相当于void => *
style({transform:'translateX(-100%)',opacity:0}),
group([//设置一组动画执行
animate('.5s ease-in-out',style({transform:'translateX(0)'})),
animate('.3s ease-in',style({opacity:1}))
])
]),
//出场动画
transition(':leave',[//:leave相当于* => void
style({transform:'tranlateX(0)',opacity:1}),
group([//设置一组动画执行
animate('.5s ease-in-out',style({transform:'translateX(100%)'})),
animate('.3s ease-in',style({opacity:0}))
])
])
])
Query用于父节点寻找子节点
Stagger指定有多个满足Queryade元素,每个的动画之间有间隔
实例Demo:
export class listAnimation = trigger('listAnim',[
transition('* => *',[//任意状态变化时,当不同的情况发生会触发不同的状态变化
query(':enter',style({opacity:0}),{optional:true}),
query(':enter',stagger(100,[//stagger的作用在于在多个元素发生时会一个一个执行动画,参数一表示每个元素动画发生的间隔时间(毫秒)
animate('1s',style({opacity:1}))
]),{optional:true}),
query(':leave',style({opacity:1}),{optional:true}),
query(':leave',stagger(100,[
animate('1s',style({opacity:0}))
]),{optional:true})
])
]);
//optional:true表示元素绑定是可选的,如果没有元素则不绑定
<div [@listAnim]="projects.length">
<item *ngFor="let project of projects">
{{project}}
</item>
</div>