加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Angular动画——路由动画及高阶动画函数

发布时间:2020-12-17 07:13:24 所属栏目:安全 来源:网络整理
导读:一、路由动画 路由动画需要在host元数据中指定触发器。动画注意不要过多,否则适得其反。 内容优先,引导用户去注意到某个内容。动画只是辅助手段。 定义一个进场动画,一个离场动画。 因为进场动画和离场动画用的特别频繁,有一个别名叫 :enter 和 :leave

一、路由动画

路由动画需要在host元数据中指定触发器。动画注意不要过多,否则适得其反。

内容优先,引导用户去注意到某个内容。动画只是辅助手段。

定义一个进场动画,一个离场动画。

因为进场动画和离场动画用的特别频繁,有一个别名叫:enter:leave

import { trigger,state,transition,style,animate} from @angular/animations;

export const slideToRight = trigger(routeAnim,[
    state(void,style({position:fixed,width:100%,height:100%})),state(*,height:80%})),transition(void => *,[
        style({transform:translateX(-100%)}),animate(.5s ease-in-out,style({transform:translateX(0)}))
    ]),transition(* => void,[
        style({transform:translateX(0)}),style({transform:translateX(100%)}))
    ]),]);

在project-list中使用路由动画。

import { Component,OnInit,HostBinding } from "@angular/core";
import { MatDialog } from "@angular/material";
import { NewProjectComponent } from "../new-project/new-project.component";
import { InviteComponent } from ../invite/invite.component;
import { ConfirmDialogComponent } from ../../shared/confirm-dialog/confirm-dialog.component;
import {slideToRight} from ../../animate/router.animate

@Component({
  selector: "app-project-list",templateUrl: "./project-list.component.html",styleUrls: ["./project-list.component.scss"],animations:[
    slideToRight
  ]
})
export class ProjectListComponent implements OnInit {
  @HostBinding(@routeAnim) state;

  projects = [
    {
      name: "企业协作平台",desc: "这是一个企业内部项目",coverImg: "assets/images/covers/0.jpg"
    },{
      name: "自动化测试项目",coverImg: "assets/images/covers/2.jpg"
    }
  ];
  constructor(private dialog: MatDialog) { }

  ngOnInit() { }

  openNewProjectDialog() {
    // this.dialog.open(NewProjectComponent,{data:‘this is a dialog‘});
    const dialogRef = this.dialog.open(NewProjectComponent,{
      data: { title: 新建项目 }
    });
    dialogRef.afterClosed().subscribe((result) => {
      console.log(result);
    });
  }

  lauchInviteDialog() {
    const dialogRef = this.dialog.open(InviteComponent);
  }

  lauchUpdateDialog() {
    const dialogRef = this.dialog.open(NewProjectComponent,{
      data: { title: 编辑项目 }
    });
  }

  lauchConfimDialog() {
    const dialogRef = this.dialog.open(ConfirmDialogComponent,{
      data: { title: 编辑项目,content: 您确认删除该项目吗? }
    });
  }
}
View Code

在task-home中使用路由动画。

import { Component,HostBinding } from "@angular/core";
import { NewTaskComponent } from "../new-task/new-task.component";
import { MatDialog } from "@angular/material";
import { CopyTaskComponent } from "../copy-task/copy-task.component";
import { ConfirmDialogComponent } from "../../shared/confirm-dialog/confirm-dialog.component";
import { NewTaskListComponent } from "../new-task-list/new-task-list.component";
import {slideToRight} from ../../animate/router.animate;

@Component({
  selector: "app-task-home",templateUrl: "./task-home.component.html",styleUrls: ["./task-home.component.scss"],animations:[
    slideToRight
  ]
})
export class TaskHomeComponent implements OnInit {
  constructor(private dialog: MatDialog) {}

  @HostBinding(@routeAnim) state;
  ngOnInit() {}

  launchNewTaskDialog() {
    // this.dialog.open(NewTaskComponent);
    const dialogRef = this.dialog.open(NewTaskComponent,{
      data: { title: "新建任务" }
    });
  }
  lauchCopyTaskDialog() {
    const dialogRef = this.dialog.open(CopyTaskComponent,{
      data: { lists: this.lists }
    });
  }

  launchUpdateTaskDialog(task) {
    const dialogRef = this.dialog.open(NewTaskComponent,{
      data: { title: "修改任务",task: task }
    });
  }

  launchConfirmDialog() {
    const dialogRef = this.dialog.open(ConfirmDialogComponent,{
      data: { title: "删除任务列表",content: "您确定要删除该任务列表吗?" }
    });
  }

  launchEditListDialog() {
    const dialogRef = this.dialog.open(NewTaskListComponent,{
      data: { title: "更改列表名称" }
    });
    dialogRef.afterClosed().subscribe(result => console.log(result));
  }
  launchNewListDialog() {
    const dialogRef = this.dialog.open(NewTaskListComponent,{
      data: { title: "新建列表名称" }
    });
    dialogRef.afterClosed().subscribe(result => console.log(result));
  }
  lists = [
    {
      id: 1,name: "待办",tasks: [
        {
          id: 1,desc: "任务一: 去星巴克买咖啡",completed: true,priority: 3,owner: {
            id: 1,name: "张三",avatar: "avatars:svg-11"
          },dueDate: new Date(),reminder: new Date()
        },{
          id: 2,desc: "任务一: 完成老板布置的PPT作业",completed: false,priority: 2,owner: {
            id: 2,name: "李四",avatar: "avatars:svg-12"
          },dueDate: new Date()
        }
      ]
    },{
      id: 2,name: "进行中",desc: "任务三: 项目代码评审",priority: 1,name: "王五",avatar: "avatars:svg-13"
          },dueDate: new Date()
        },desc: "任务一: 制定项目计划",dueDate: new Date()
        }
      ]
    }
  ];
}
View Code

定义路由

  <mat-list-item [routerLink]="[‘/project‘]"> 
    <mat-icon mat-list-icon svgIcon="projects"></mat-icon>
    <h4 mat-line>项目首页</h4>
    <p mat-line mat-subheader> 查看您的所有项目</p>
  </mat-list-item>
  <mat-list-item [routerLink]="[‘/task‘]"> 
    <mat-icon mat-list-icon svgIcon="projects"></mat-icon>
    <h4 mat-line>任务首页</h4>
    <p mat-line mat-subheader> 查看您的所有项目</p>
  </mat-list-item>?

注意:一定要用HostBinding形式。

二、Group

用于同时进行一组动画变换

group([animate(...),animate(...)...])接收一个数组,数组里写多个动画。

import { trigger,animate,group} from @angular/animations;

export const slideToRight = trigger(routeAnim,transition(:enter,[
        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,[
        style({transform:translateX(0),opacity:1}),style({transform:translateX(100%)})),style({opacity:0}))
        ])
    ]),]);

三、Query & Stagger

Query用于父节点寻找子节点,把动画应用到选中元素。非常强大。

Stagger指定有多个满足Query的元素,每个的动画之间有间隔。

做一个示例:新建的时候同时新建2个项目,两个新建出的项目的动画依次产生,第一个完成后才开始第二个。

建立list.animate.ts?

进场动画,先隐藏起来,通过stagger间隔1000s做一个1s的动画。

import { trigger,query,animation,stagger} from @angular/animations;

export const listAnimation = trigger(listAnim,[
    transition(* => *,[
      query(:enter,style({opacity: 0}),{ optional: true }),//加入optional为true,后面的状态动画都是可选的
      query(:enter,stagger(1000,[
        animate(1s,style({opacity: 1}))
      ]),{ optional: true }),query(:leave,style({opacity: 1}),{ optional: true }),style({opacity: 0}))
      ]),{ optional: true })
    ])
  ]);

在project_list中使用

应用query动画一般都是跟*ngFor在一起的,需要外面套一层div。

<div class="container" [@listAnim]="projects.length">
  <app-project-item *ngFor="let project of projects" [item]="project"
  class="card"
  (onInvite)="lauchInviteDialog()"
  (onEdit)="lauchUpdateDialog()"
  (onDelete)="lauchConfimDialog(project)">
  </app-project-item>
</div>
<button class="ab-buttonmad-fab fab-button" mat-fab type="button" (click)="openNewProjectDialog()">
  <mat-icon>add</mat-icon>
</button>

修改对应的css

// :host{
//     display: flex;
//     flex-direction: row;
//     flex-wrap: wrap;
// }

//把host改为div
.container{
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
}
View Code

修改一下component

import { Component,HostBinding } from "@angular/core";
import { MatDialog } from "@angular/material";
import { NewProjectComponent } from "../new-project/new-project.component";
import { InviteComponent } from ../invite/invite.component;
import { ConfirmDialogComponent } from ../../shared/confirm-dialog/confirm-dialog.component;
import {slideToRight} from ../../animate/router.animate
import { listAnimation } from ../../animate/list.animate;
import { projection } from @angular/core/src/render3;

@Component({
  selector: "app-project-list",animations:[
    slideToRight,listAnimation  //第一步,导入listAnimation
  ]
})
export class ProjectListComponent implements OnInit {
  @HostBinding(@routeAnim) state;

  //第二步,改造一下数组,加id
  projects = [
    {
      id:1,name: "企业协作平台",{
      id:2,name: "自动化测试项目",coverImg: "assets/images/covers/2.jpg"
    }
  ];
  constructor(private dialog: MatDialog) { }

  ngOnInit() { }

  //第三步,新增元素时hard code一下
  openNewProjectDialog() {
    // this.dialog.open(NewProjectComponent,{
      data: { title: 新建项目 }
    });
    dialogRef.afterClosed().subscribe((result) => {
      console.log(result);
      this.projects = [...this.projects,{id:3,name:一个新项目,desc:这是一个新项目,coverImg:"assets/images/covers/3.jpg"},{id:4,name:又一个新项目,desc:这是又一个新项目,coverImg:"assets/images/covers/4.jpg"}]
    });
  }

  lauchInviteDialog() {
    const dialogRef = this.dialog.open(InviteComponent);
  }

  lauchUpdateDialog() {
    const dialogRef = this.dialog.open(NewProjectComponent,{
      data: { title: 编辑项目 }
    });
  }

  //第四步,改造一下删除项目
  lauchConfimDialog(project) {
    const dialogRef = this.dialog.open(ConfirmDialogComponent,{
      data: { title: 删除项目,content: 您确认删除该项目吗? }
    });
    dialogRef.afterClosed().subscribe(result=>{
      console.log(result);
      this.projects=this.projects.filter(p=>p.id!=project.id);
    });
  }
}
View Code

Stagger使得在多个元素时候,动画交错开,而不是一起。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读