Анимированное изменение ширины fxFlex после удаления контейнера-брата - PullRequest
0 голосов
/ 31 октября 2019

У меня есть простой макет, который состоит из двух столбцов (боковая панель и содержимое), как показано в демонстрации. Когда боковая панель удаляется с помощью анимации углов :leave, другой контейнер растягивается до 100% ширины от 65%. Это делается с помощью атрибута fxFlex. Здесь происходит то, что, когда анимация для боковой панели запускается, контент уже растягивается до 100%, а когда анимация заканчивается, контент будет ужасно прыгать.

Когда я пытаюсь анимировать переход, анимация всегда запускается после прыжка или просто полностью нарушает макет. То же самое происходит, если я пытаюсь отложить переход через css или напрямую через timeout в моем компоненте.

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

Как сделать переход плавным?

Демонстрация Stackblitz

Ответы [ 2 ]

0 голосов
/ 05 ноября 2019

Я думаю, это то, что вы хотели.

https://stackblitz.com/edit/angular-j2p2kg?file=src/app/app.component.ts

Хитрость в том, что flex не позволяет вам иметь дело с width. Поэтому я сконцентрировался на изменении значений flex, а также на удаленных переходах и оставил все это угловым для обработки.

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ],
  animations: [
      trigger('slidePanel', [
        state('leave', style({
          flex: '0 0 100%'
        })),
        state('enter', style({
          flex: '1'
        })),
          transition('* => leave',
              animate('300ms cubic-bezier(0.35, 0, 0.25, 1)' ),
          ),
          transition('* => enter', 
          animate('400ms cubic-bezier(0.35, 0, 0.25, 1)'),
          )
      ]),
    ]
})
export class AppComponent  {

  public panelShown = 'leave';

  public toggle() : void {
      this.panelShown = this.panelShown === 'enter' ? 'leave' : 'enter';
  }

}

<div fxLayout="row" fxLayoutAlign="end center" class="fullScreen">
  <div [@slidePanel]="panelShown" fxLayout="column" fxLayoutAlign="center center" fxFlex="35" class="green fullHeight">

  </div>
  <div fxLayout="column" fxLayoutAlign="center center" class="content" [fxFlex]="100">
    <div fxLayout="column" fxLayoutAlign="start start" class="blue">
    </div>
    <button (click)="toggle()">Toggle panel</button>
  </div>
</div>
0 голосов
/ 03 ноября 2019

Я не удовлетворен результатом, но вы можете сделать это без угловой анимации:

<div fxLayout="row" fxLayoutAlign="end center" class="fullScreen">
  <div fxLayout="column" fxLayoutAlign="center center" [style.transform]="panelShown ? 'translateX(0%)': 'translateX(-100%)'" fxFlex="35" class="green fullHeight">

  </div>
  <div fxLayout="column" fxLayoutAlign="center center" class="content" [fxFlex]="100"
  [style.min-width]="panelShown?'65%':'100%'">
    <div fxLayout="column" fxLayoutAlign="start start" class="blue">
    </div>
    <button (click)="toggle()">Toggle panel</button>
  </div>
</div>

и у вас css:

.content {
  transition: 2s cubic-bezier(0.35, 0, 0.25, 1);
}

.green {
  background: green;
  transition: 2s cubic-bezier(0.35, 0, 0.25, 1);
}

Что важно заметить:

  • fxLayoutAlign="end center"
  • [style.transform]="panelShown ? 'translateX(0%)': 'translateX(-100%)'"
  • [style.min-width]="panelShown?'65%':'100%'

Рабочая ДЕМО

...