Angular: 动画显示卡在另一张卡上
Angular: animation display card on top of another card
我正在使用 angular 动画生成器来创建动画。我有一个带有卡片列表的网格列表。当我点击一个按钮时,我希望另一个 div 出现在初始卡片的顶部(从左侧浮动以覆盖第一张卡片
)。截至目前,div 随动画一起出现,但出现在初始 card.I 的一侧,已经制作了一个 stackblitz 示例以显示当前 progress.Here 是我的 stackblitz:
https://stackblitz.com/edit/angular-ty4rfh
同时在此处粘贴代码:
import { Component,OnInit,ElementRef } from '@angular/core';
import { trigger, state, style, transition, animate, AnimationBuilder, AnimationPlayer } from '@angular/animations';
export class Asset
{
constructor(public name:string,public description:string){};
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
assets:Asset[]=[];
cards=[];
private player: AnimationPlayer;
constructor(private animationBuilder:AnimationBuilder,
private elRef:ElementRef
){}
ngOnInit(){
this.setAssets();
this.setswitch();
}
setAssets(){
this.assets.push(new Asset("Asset1","Latest1"));
this.assets.push(new Asset("Asset2","Latest2"));
this.assets.push(new Asset("Asset3","Latest3"));
this.assets.push(new Asset("Asset4","Latest4"));
this.assets.push(new Asset("Asset5","Latest5"));
this.assets.push(new Asset("Asset6","Latest6"));
this.assets.push(new Asset("Asset7","Latest7"));
this.assets.push(new Asset("Asset8","Latest8"));
this.assets.push(new Asset("Asset9","Latest9"));
for(var i=0; i<this.assets.length;i++){
console.log(this.assets[i].name);
}
}
setswitch() {
for (let i = 0; i < this.assets.length; i++) {
let cardshow = {
id: i.toString(),
isShow : false
};
this.cards.push(cardshow);
}
console.log(this.cards);
}
animate(i){
this.cards[i].isShow=true;
let animationFactory;
animationFactory = this.animationBuilder
.build([
style({ width: '0' }),
animate(200, style({ width: 200 }))
]);
let elem:Element = document.getElementById("div"+(i));
console.log("Elament",elem);
console.log("INDEX",i);
this.player = animationFactory.create(elem);
this.player.play();
}
}
html:
<div>
<mat-grid-list cols="3" rowHeight="3:1">
<mat-grid-tile *ngFor="let asset of assets; index as i">
<div class="border">
<p>{{asset.name}} </p>
<p>{{asset.description}} </p>
<button (click)="animate(i)">click</button>
</div>
<div [ngClass]="!cards[i].isShow?'hide':''" id="{{'div'+i}}" class="border" >
<p>{{asset.description}} </p>
<button>click</button>
</div>
</mat-grid-tile>
</mat-grid-list>
</div>
css:
p {
font-family: Lato;
}
.border{
border:1px solid black;
padding-left: 20px;;
padding-right:20px;
}
.hide{
display:none;
}
编辑:我需要另一张卡片完全隐藏在传入card.Also下面点击传入卡片内的按钮后,动画应该被撤消(卡应缩回)。另外我现在正在做的是增加宽度。我希望新卡应该像我们在抽屉里看到的那样从左边进来
检查这个stackblitz
app.component.css 为:
p {
font-family: Lato;
}
.border{
border:1px solid black;
padding-left: 20px;;
padding-right:20px;
background: #ffe6ea;
}
.hide{
display:none;
}
.borderPopUp{
padding-left: 20px;;
padding-right:20px;
position:absolute;
background:#d3d3d3d4;
animation: openLikeDrawer 800ms ease-in-out;
width:50%;
left:20%;
}
@keyframes openLikeDrawer{
from {left:0px; }
to { left: 20%; }
}
app.component.html 为:
<div>
<mat-grid-list cols="3" rowHeight="3:1">
<mat-grid-tile *ngFor="let asset of assets; index as i">
<div class="border">
<p>{{asset.name}} </p>
<p>{{asset.description}} </p>
<button (click)="asset.isShow = true">click</button>
</div>
<div *ngIf="asset.isShow" class="borderPopUp" >
<p>{{asset.description}} </p>
<button (click)='asset.isShow = false'>click</button>
</div>
</mat-grid-tile>
</mat-grid-list>
</div>
这是我的最终解决方案:
import { Component, OnInit } from '@angular/core';
import { LearningContentService } from '../../../service/learningcontent.service';
import { ActivatedRoute } from '@angular/router'
import { trigger, style, transition, animate, keyframes, query, stagger } from '@angular/animations';
export class Asset {
name: string;
description: string;
cardtoggle:boolean=false;
constructor(rawObj: any) {
this.name = rawObj.name;
this.description = rawObj.description;
this.cardtoggle = rawObj.cardtoggle;
}
}
@Component({
selector: 'app-catalogue',
templateUrl: './catalogue.component.html',
styleUrls: ['./catalogue.component.scss'],
animations: [
trigger('listAnimation', [
transition('* => *', [
query(':enter', style({ opacity: 0 }), { optional: true }),
query(':enter', stagger('50ms', [
animate('1s ease-in', keyframes([
style({ opacity: 0, transform: 'translateY(-75%)', offset: 0 }),
style({ opacity: .5, transform: 'translateY(35px)', offset: 0.3 }),
style({ opacity: 1, transform: 'translateY(0)', offset: 1.0 }),
]))]), { optional: true })
])
],
),
]
})
export class CatalogueComponent implements OnInit {
assets: Array<Asset> = [];
constructor(private route: ActivatedRoute,
private learningService: LearningContentService,
) {
}
ngOnInit() {
this.loadAssets();
}
loadAssets() {
this.learningService.assets().subscribe((res: any) => {
const datas: Array<any> = res;
datas.forEach(asset => this.assets.push(new Asset(asset)));
console.log(this.assets);
});
}
animate(asset) {
asset.cardtoggle = true;
}
close(asset) {
asset.cardtoggle = false;
}
}
html:
<div fxLayout="column">
<div fxLayout="row">
<p class="page-heading" fxFlex="80%">Catalogue</p>
<div class="page-content-filter" fxLayoutAlign="end">
<button mat-button class="search-btn"><i class="material-icons"> search </i></button>
<input class="form-filter" matInput placeholder="Search...">
</div>
</div>
<mat-grid-list gutterSize="20px" cols="3" rowHeight="3:1" [@listAnimation]="assets.length">
<mat-grid-tile *ngFor="let asset of assets">
<div class="full-width white">
<div class="padding20px" fxLayout="column" fxLayoutGap="15px">
<div fxLayout="row" fxLayoutGap="15px">
<img fxFlex="10" style="width:50px;height:50px;" src="../../../../assets/images/images.jpeg" mat-card-image>
<b fxFlex="100">{{asset.name}}</b>
<mat-icon fxLayoutAlign="end end" class="small-icon pointer" (click)="animate(asset)">spa</mat-icon>
</div>
<div fxLayout="row" fxLayoutGap="10px">
<mat-icon class="small-icon">person</mat-icon>
<p class="small-heading"> Mohit Harshan</p>
<mat-divider vertical="true"></mat-divider>
<mat-icon class="small-icon">play_arrow</mat-icon>
<p class="small-heading">Video</p>
<mat-divider vertical="true"></mat-divider>
<mat-icon class="small-icon">face</mat-icon>
<p class="small-heading">5 points</p>
</div>
<mat-progress-bar class="progress" mode="determinate" value="40"></mat-progress-bar>
</div>
</div>
<div class="pull-right" [ngClass]="{'show': asset.cardtoggle }" class="card2">
<div class="padding20px" fxLayout="column" fxLayoutGap="15px">
<div fxLayout="row" fxLayoutGap="15px">
<b fxFlex="100" class="small-heading">{{asset.name}}</b>
<mat-icon fxLayoutAlign="end end" class="small-icon pointer" (click)="close(asset)">clear</mat-icon>
</div>
<div fxLayout="row" fxLayoutGap="10px">
<p class="small">{{asset.description}}</p>
</div>
<div fxLayout="row" fxLayoutGap="10px" fxFLex="100" fxLayoutAlign="end end">
<button fxFLex="100" mat-button class="green-button" >View Details</button>
</div>
</div>
</div>
</mat-grid-tile>
</mat-grid-list>
</div>
css:
.card2{
position:absolute;
z-index: 20;
background: white;
padding-left: 0px;
padding-right:0px;
width:100%;
height:100%;
margin-left: 100%;
transition: margin-left .5s ease-in-out;
}
.show {
margin-left: 0%;
}
.green-button{
border:1px solid lightgreen;
border-radius: 10%;
font-size: 10px;
color:green;
}
我正在使用 angular 动画生成器来创建动画。我有一个带有卡片列表的网格列表。当我点击一个按钮时,我希望另一个 div 出现在初始卡片的顶部(从左侧浮动以覆盖第一张卡片 )。截至目前,div 随动画一起出现,但出现在初始 card.I 的一侧,已经制作了一个 stackblitz 示例以显示当前 progress.Here 是我的 stackblitz:
https://stackblitz.com/edit/angular-ty4rfh
同时在此处粘贴代码:
import { Component,OnInit,ElementRef } from '@angular/core';
import { trigger, state, style, transition, animate, AnimationBuilder, AnimationPlayer } from '@angular/animations';
export class Asset
{
constructor(public name:string,public description:string){};
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
assets:Asset[]=[];
cards=[];
private player: AnimationPlayer;
constructor(private animationBuilder:AnimationBuilder,
private elRef:ElementRef
){}
ngOnInit(){
this.setAssets();
this.setswitch();
}
setAssets(){
this.assets.push(new Asset("Asset1","Latest1"));
this.assets.push(new Asset("Asset2","Latest2"));
this.assets.push(new Asset("Asset3","Latest3"));
this.assets.push(new Asset("Asset4","Latest4"));
this.assets.push(new Asset("Asset5","Latest5"));
this.assets.push(new Asset("Asset6","Latest6"));
this.assets.push(new Asset("Asset7","Latest7"));
this.assets.push(new Asset("Asset8","Latest8"));
this.assets.push(new Asset("Asset9","Latest9"));
for(var i=0; i<this.assets.length;i++){
console.log(this.assets[i].name);
}
}
setswitch() {
for (let i = 0; i < this.assets.length; i++) {
let cardshow = {
id: i.toString(),
isShow : false
};
this.cards.push(cardshow);
}
console.log(this.cards);
}
animate(i){
this.cards[i].isShow=true;
let animationFactory;
animationFactory = this.animationBuilder
.build([
style({ width: '0' }),
animate(200, style({ width: 200 }))
]);
let elem:Element = document.getElementById("div"+(i));
console.log("Elament",elem);
console.log("INDEX",i);
this.player = animationFactory.create(elem);
this.player.play();
}
}
html:
<div>
<mat-grid-list cols="3" rowHeight="3:1">
<mat-grid-tile *ngFor="let asset of assets; index as i">
<div class="border">
<p>{{asset.name}} </p>
<p>{{asset.description}} </p>
<button (click)="animate(i)">click</button>
</div>
<div [ngClass]="!cards[i].isShow?'hide':''" id="{{'div'+i}}" class="border" >
<p>{{asset.description}} </p>
<button>click</button>
</div>
</mat-grid-tile>
</mat-grid-list>
</div>
css:
p {
font-family: Lato;
}
.border{
border:1px solid black;
padding-left: 20px;;
padding-right:20px;
}
.hide{
display:none;
}
编辑:我需要另一张卡片完全隐藏在传入card.Also下面点击传入卡片内的按钮后,动画应该被撤消(卡应缩回)。另外我现在正在做的是增加宽度。我希望新卡应该像我们在抽屉里看到的那样从左边进来
检查这个stackblitz
app.component.css 为:
p {
font-family: Lato;
}
.border{
border:1px solid black;
padding-left: 20px;;
padding-right:20px;
background: #ffe6ea;
}
.hide{
display:none;
}
.borderPopUp{
padding-left: 20px;;
padding-right:20px;
position:absolute;
background:#d3d3d3d4;
animation: openLikeDrawer 800ms ease-in-out;
width:50%;
left:20%;
}
@keyframes openLikeDrawer{
from {left:0px; }
to { left: 20%; }
}
app.component.html 为:
<div>
<mat-grid-list cols="3" rowHeight="3:1">
<mat-grid-tile *ngFor="let asset of assets; index as i">
<div class="border">
<p>{{asset.name}} </p>
<p>{{asset.description}} </p>
<button (click)="asset.isShow = true">click</button>
</div>
<div *ngIf="asset.isShow" class="borderPopUp" >
<p>{{asset.description}} </p>
<button (click)='asset.isShow = false'>click</button>
</div>
</mat-grid-tile>
</mat-grid-list>
</div>
这是我的最终解决方案:
import { Component, OnInit } from '@angular/core';
import { LearningContentService } from '../../../service/learningcontent.service';
import { ActivatedRoute } from '@angular/router'
import { trigger, style, transition, animate, keyframes, query, stagger } from '@angular/animations';
export class Asset {
name: string;
description: string;
cardtoggle:boolean=false;
constructor(rawObj: any) {
this.name = rawObj.name;
this.description = rawObj.description;
this.cardtoggle = rawObj.cardtoggle;
}
}
@Component({
selector: 'app-catalogue',
templateUrl: './catalogue.component.html',
styleUrls: ['./catalogue.component.scss'],
animations: [
trigger('listAnimation', [
transition('* => *', [
query(':enter', style({ opacity: 0 }), { optional: true }),
query(':enter', stagger('50ms', [
animate('1s ease-in', keyframes([
style({ opacity: 0, transform: 'translateY(-75%)', offset: 0 }),
style({ opacity: .5, transform: 'translateY(35px)', offset: 0.3 }),
style({ opacity: 1, transform: 'translateY(0)', offset: 1.0 }),
]))]), { optional: true })
])
],
),
]
})
export class CatalogueComponent implements OnInit {
assets: Array<Asset> = [];
constructor(private route: ActivatedRoute,
private learningService: LearningContentService,
) {
}
ngOnInit() {
this.loadAssets();
}
loadAssets() {
this.learningService.assets().subscribe((res: any) => {
const datas: Array<any> = res;
datas.forEach(asset => this.assets.push(new Asset(asset)));
console.log(this.assets);
});
}
animate(asset) {
asset.cardtoggle = true;
}
close(asset) {
asset.cardtoggle = false;
}
}
html:
<div fxLayout="column">
<div fxLayout="row">
<p class="page-heading" fxFlex="80%">Catalogue</p>
<div class="page-content-filter" fxLayoutAlign="end">
<button mat-button class="search-btn"><i class="material-icons"> search </i></button>
<input class="form-filter" matInput placeholder="Search...">
</div>
</div>
<mat-grid-list gutterSize="20px" cols="3" rowHeight="3:1" [@listAnimation]="assets.length">
<mat-grid-tile *ngFor="let asset of assets">
<div class="full-width white">
<div class="padding20px" fxLayout="column" fxLayoutGap="15px">
<div fxLayout="row" fxLayoutGap="15px">
<img fxFlex="10" style="width:50px;height:50px;" src="../../../../assets/images/images.jpeg" mat-card-image>
<b fxFlex="100">{{asset.name}}</b>
<mat-icon fxLayoutAlign="end end" class="small-icon pointer" (click)="animate(asset)">spa</mat-icon>
</div>
<div fxLayout="row" fxLayoutGap="10px">
<mat-icon class="small-icon">person</mat-icon>
<p class="small-heading"> Mohit Harshan</p>
<mat-divider vertical="true"></mat-divider>
<mat-icon class="small-icon">play_arrow</mat-icon>
<p class="small-heading">Video</p>
<mat-divider vertical="true"></mat-divider>
<mat-icon class="small-icon">face</mat-icon>
<p class="small-heading">5 points</p>
</div>
<mat-progress-bar class="progress" mode="determinate" value="40"></mat-progress-bar>
</div>
</div>
<div class="pull-right" [ngClass]="{'show': asset.cardtoggle }" class="card2">
<div class="padding20px" fxLayout="column" fxLayoutGap="15px">
<div fxLayout="row" fxLayoutGap="15px">
<b fxFlex="100" class="small-heading">{{asset.name}}</b>
<mat-icon fxLayoutAlign="end end" class="small-icon pointer" (click)="close(asset)">clear</mat-icon>
</div>
<div fxLayout="row" fxLayoutGap="10px">
<p class="small">{{asset.description}}</p>
</div>
<div fxLayout="row" fxLayoutGap="10px" fxFLex="100" fxLayoutAlign="end end">
<button fxFLex="100" mat-button class="green-button" >View Details</button>
</div>
</div>
</div>
</mat-grid-tile>
</mat-grid-list>
</div>
css:
.card2{
position:absolute;
z-index: 20;
background: white;
padding-left: 0px;
padding-right:0px;
width:100%;
height:100%;
margin-left: 100%;
transition: margin-left .5s ease-in-out;
}
.show {
margin-left: 0%;
}
.green-button{
border:1px solid lightgreen;
border-radius: 10%;
font-size: 10px;
color:green;
}