Как сделать анимацию раскрывающегося меню в ng-bootstrap, используя Angular Animations или css? - PullRequest
0 голосов
/ 14 марта 2019

Я пытаюсь анимировать выпадающее меню ng-bootstrap с помощью Angular Animations, и хотя анимация работает довольно хорошо в разработке, в производственном процессе, когда меню открывается, она по каким-то причинам перепрыгивает сверху вниз.Вот мой код:

анимация:

   trigger('openClose', [
        transition('closed => open', [
            style({ opacity: 0, transform: 'translateY(-30px)'}),
            animate('100ms ease-out',
                style({opacity: '*', transform: 'translateY(0)'}))
        ]),
        transition('open => closed', [
            style({ opacity: '*', transform: 'translateY(0)'}),
            animate('100ms ease-out',
                style({opacity: 0, transform: 'translateY(-30px)'}))
        ])
    ])

компонент:

<div  ngbDropdown 
      class="d-inline-block w-100">

 <!-- dropdown button -->
 <button class="dropdown-button btn btn-icon-right"
      type="button"
      ngbDropdownToggle>
  <span>
    <span>my title</span>
  </span>
 </button>

 <!-- dropdown menu -->
 <div  ngbDropdownMenu 
      class="dropdown-menu" 
      [@openClose]="isOpen ? 'open' : 'closed'">
  my content
 </div>
</div>

Анимация при закрытии также не работает.Я пробовал анимировать на :enter и :leave и void, они тоже не работают.Любая идея, где проблема может быть, или как правильно анимировать ngbDropdown?И есть ли способ оживить его, используя только css?

Обновление: Обходной путь ниже не работает в 4.1.0+.Я скоро обновлю решение.Если у кого-то есть лучшее решение, обновите его ниже или здесь.

Решение: Проблема в том, что в производственной среде по какой-то причине раскрывающееся меню настроено с помощью transform: translateY(0),в то время как в dev это установлено с помощью top: 0.Таким образом, чтобы сделать анимацию скольжения, вы должны использовать top в prod и transform в dev.Чтобы решить эту проблему, мне пришлось переопределить dropdown-menu своим собственным классом.Вот хакерское решение с использованием css, пока команда ngbootstrap не добавит анимацию:

HTML:

<div  ngbDropdown 
      class="dropdown"
      (openChange)="openChange($event)"
      #dropdown>

  <!-- dropdown button -->
  <button class="dropdown-button btn"
          [ngClass]="buttonClass"
          [disabled]="disabled"
          type="button"
          ngbDropdownToggle>
    <span> My Title   </span>
  </button>

  <!-- dropdown menu -->
  <div  ngbDropdownMenu 
        class="dropdown-menu2" // this is important to override the ngb class
        [ngClass]="dropdownOpenClass"
        #dropdownMenu>
    <ng-content></ng-content>
  </div>
</div>

SASS:

.dropdown-menu2 {
    display:block;
    visibility: collapse;
    transition: all .2s ease-in-out;
    top: 0 !important;
    &.dd-closed {
        visibility: hidden;
        opacity: 0;
        transform: translateY(20px) !important; // overwrite prod on closed
    }
    &.dd-open {
        visibility: visible;
        opacity: 1;
        transform: translateY(38px);
    }
}

TS:

dropdownOpenClass = 'dd-closed';

openChange(e: Event) {
    this.isOpen = !this.isOpen;
    this.dropdownOpenClass = this.isOpen ? 'dd-open' : 'dd-closed';
    this.openChanged.emit(e);
}

1 Ответ

0 голосов
/ 16 марта 2019

Работая над ' способом анимировать его, используя только css ' ... нам пришлось работать с классами начальной загрузки по умолчанию:

  • класс выпадающего меню из начальной загрузки, который по умолчанию скрывает раскрывающийся список
  • класс шоу, раскрывающий раскрывающийся список
  • мы должны были взять это в свои руки, что мы сделали, используя ngStyle
  • мы также создали классы для медленного раскрытия и медленного скрытия ... чтобы переключать их, мы создаем переменную и используем ngClass
  • чтобы настроить эффекты длительности, вы можете изменить эти классы, чтобы получить именно тот эффект, который вы хотите

HTML

<div ngbDropdown class="d-inline-block">
  <button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle (click)="dropDownClicked()">Toggle dropdown</button>
  <div 
  [ngStyle]="ddStyling? {'display': 'block'} : {'display': 'block'}"
  [ngClass]='ddStatus' ngbDropdownMenu aria-labelledby="dropdownBasic1">
    <button ngbDropdownItem>Action - 1</button>
    <button ngbDropdownItem>Another Action</button>
    <button ngbDropdownItem>Something else is here</button>
  </div>
</div>

CSS

.ddOpened{
  background:lightpink;
  animation: myOpenMove 1s ease-in;
}

@keyframes myOpenMove {
  0% {  visibility:hidden; opacity: 0; }
  100% { visibility:visible; opacity: 1; }
}

.ddClosed{
  background:lightpink;
  animation: myCloseMove 1s ease-in;
  transform: translate(0px, 38px);
  visibility:hidden;
}

@keyframes myCloseMove {
  0% { opacity: 1 !important; visibility: visible; }
  100% {  height:1px; opacity: 0; visibility:hidden; }
}

работает демо на стеке блиц здесь

...