Angular: карта отображения анимации поверх другой карты

Я использую конструктор анимации angular для создания анимации. У меня есть список сетки со списком карт. Когда я нажимаю кнопку, я хочу, чтобы другой div появился поверх исходной карты (поплавок слева, чтобы закрыть первую карту). На данный момент div появляется с анимацией, но отображается сбоку исходной карты. Я сделал пример stackblitz, чтобы показать текущий прогресс. Вот мой 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;
}

EDIT: мне нужно, чтобы другая карта была полностью скрыта под входящей картой. Также после нажатия на кнопку внутри входящей карты анимация должна быть отменена (карта должна вернуться назад). Также то, что я делаю сейчас, увеличивает ширину. Я ожидаю, что новая карта должна входить слева, как мы видим в ящике.


person Mohit Harshan    schedule 06.04.2019    source источник


Ответы (2)


проверьте этот 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>
person Akber Iqbal    schedule 06.04.2019
comment
Можете ли вы сделать это немного больше, как то, что мне нужно. Мне нужно, чтобы другая карта была полностью скрыта под входящей картой. Также после нажатия кнопки внутри входящей карты анимация должна быть отменена (карта должна втягиваться назад). Кроме того, сейчас я увеличиваю ширину. Что я ожидаю, что новая карта должна входить слева, как мы видим в ящике - person Mohit Harshan; 06.04.2019
comment
позвольте мне поделиться этим Мохитом - person Akber Iqbal; 06.04.2019
comment
вы хотите использовать угловую анимацию... как насчет того, чтобы сделать это без этого? но чистый угловой? - person Akber Iqbal; 06.04.2019
comment
не могли бы вы проверить мой обновленный stackblitz и сказать мне, что вы из этого делаете. В нем есть еще несколько логических ошибок, которые нужно исправить. - person Mohit Harshan; 06.04.2019
comment
наблюдения (1) слишком много кода для простых вещей... (2) если я открою, а затем закрою ячейку 2... после этого, если я открою любую ячейку, ячейка 2 снова станет видимой... это то, что портит предполагаемую логику ... рассмотрите возможность использования рендерера вместо elementRef для манипулирования DOM (но в конечном итоге избегайте обоих, если вы можете с другим дизайном приложения) - person Akber Iqbal; 06.04.2019
comment
Пожалуйста, проверьте мой последний код. Можете ли вы сделать так, чтобы он появлялся сбоку, а не расширялся посередине? - person Mohit Harshan; 06.04.2019
comment
Давайте продолжим это обсуждение в чате. - person Akber Iqbal; 06.04.2019

Это мое окончательное решение:

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;
}
person Mohit Harshan    schedule 08.04.2019