有什么方法可以混合 'push' 和 'over' 模式的 Angular Material mat-sidenav?

Any way to mix 'push' and 'over' modes of Angular Material mat-sidenav?

请检查这里的代码:https://stackblitz.com/edit/angular-sidenav-mixedpushover

我想设置一个 angular material sidenav,以便它有一个始终可见的切换按钮,并在打开和关闭时与 sidenav 一起滑动。主要内容区域在打开时应被按钮和 sidenav 遮挡(即 mode="over")。

基本上我希望 sidenav 在“结束”模式下运行,但要“按下”切换它的按钮。

我尝试了几种方法,但没有一种方法是正确的。我当前的实现(不共享,因为很难做一个简单的例子)有两个切换按钮:一个位于屏幕边缘,手动 shown/hidden,另一个按钮是 sidenav 的一部分内容本身。如果你眯着眼睛看,它几乎就像一个随侧导航滑动的按钮!我还使用了一些动画来尝试将两个按钮混合一点,但是很难匹配 sidenav 的速度。

我正在尝试做的一些图片。

Sidenav 已关闭:

Sidenav 已打开:

有人有什么可行的建议吗?谢谢!

如果只想看结果,请到答案末尾

要做的主要事情是将切换按钮与 sidenav 分开。

HTML

<p><button [ngClass]="{'button':true,'open':opened}" (click)="toggle()">Open</button></p>

<mat-sidenav-container class="sidenav" (backdropClick)="close()">
  <mat-sidenav #sidenav (keydown.escape)="close()" disableClose position="end">
    <p>Sidenav content</p>
  </mat-sidenav>

  <mat-sidenav-content>
    Page content with "over" sidenav
  </mat-sidenav-content>
</mat-sidenav-container>

在这里,您将按钮从 sidenav 中移出,classes 允许您首先将按钮放置在您想要的位置 - 使用 button class -然后在打开或关闭 sidenav 时移动它 - 使用 open class.

这里的 (backdropClick)="close()"(keydown.escape)="close()" 是为了确保我们移动切换按钮,即使我们没有用它关闭 sidenav

所以这个的样式是这样的

CSS

.button{
  position:absolute;
  width:40px;
  height:40px;
  background-color: green;
  color:black;
  border-top-left-radius:5px;
  border-bottom-left-radius:5px;
  top: 50%;
  right:0;
  z-index: 2;
  transform: translate3d(0,0,0);
  transition:0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
}

.open{
  transform: translate3d(-200px,0,0);
  transition:0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
}

transition 效果上,您会看到一个 cubic-bezier(0.25, 0.8, 0.25, 1);,这是 sidenav 用来显示其内容的转换。因此,将此转换用于我们的按钮后,它将完全适合 sidenav 移动。

最后在你的 typescript 文件上,你只需要这些函数来切换你的 sidenav

TS

@ViewChild('sidenav') sidenav: MatSidenav;

opened: boolean = false;

toggle(){
  this.opened = !this.opened
  if(this.opened){
      this.sidenav.open();
    }else{
      this.sidenav.close();
    }
}

close() {
  this.opened = false;
  this.sidenav.close();
}

Here 你可以看到一个有效的 stackblitz。