Angular Material 17+ 高级教程 – Material Ripple

介绍

Ripple (波纹) 是 Material Design 中一个标志性的特色。

点击 button 会溅起水波的感觉。

 

参考

Docs – Ripples

 

When to use it?

一般情况下,我们很少需要自己去使用 Ripple。因为 Angular Material 的各个组件 (比如 mat-button) 都已经自带 Ripple 了。

我是遇到一个比较特殊的需求才用上 Ripple 的。

需求是这样的:

有一个 Sidebar,Sidebar 里有一个 Extended Fab Button,这个 Sidebar 可以 collapse,当 collapsed 后 Extended Fab Button 会变小。

假如我们直接给 Extended Fab Button 一个 width: 56px,效果是这样的

没关系,我们 text hide 起来看看

 依然被一层东西盖着了,翻看 Extended Fab Button 的 HTML 结构

有一堆的 div,每个 div 负责不同的东西,比如 Ripple,focus 时的变暗色等等。

结论:要改 Extended Fab Button 的 width 不那么容易。

为了满足需求,我们只能自己模拟一个 Extended Fab Button 了。

 

Simulate Extended Fab Button with Ripple

模拟 Extended Fab Button 的 Layout,颜色,字体,这些还不算太难

HTML

<button class="my-mat-extended-fab-button">
  <mat-icon>edit</mat-icon>
  Create products
</button>

Styles

.my-mat-extended-fab-button {
  display: flex;
  align-items: center;
  gap: 12px;
  border-radius: var(--mdc-extended-fab-container-shape);
  background-color: var(--mdc-fab-container-color);
  color: var(--mat-fab-foreground-color);
  padding-inline: 12px 20px;
  padding-block: 16px;
  font-weight: 500;
  font-size: 14px;

  box-shadow: var(--mdc-extended-fab-container-elevation-shadow);

  &:hover,
  &:focus {
    /*
      1. Angular Material 的 Extended Fab Button 用了 2 层来做 hover 效果
          这里偷工减料,只用一层,直接抄它 2 层效果的颜色来用。
    */
    background-color: #cecef4;
  }
}

效果

唯一比较难搞的是点击后的 Ripple 效果。

幸好 Angular Material 有独立封装 Ripple 效果。

添加 Ripple 效果

使用 matRipple 指令就可以了

<button class="my-mat-extended-fab-button" matRipple>
  <mat-icon>edit</mat-icon>
  Create products
</button>

效果

至少有 90% 以上相似度就可以了。

 

Ripple の Options

比较常用的 options:

  1. color

    <button class="my-mat-extended-fab-button" matRipple matRippleColor="red">

    效果

  2. radius

    <button class="my-mat-extended-fab-button" matRipple matRippleColor="red" [matRippleRadius]="20">

    效果

  3. centered

    by default 波纹是从点击的位置发散的,设置 centered 会让波纹从中心开始发散。

    <button 
      class="my-mat-extended-fab-button" 
      matRipple 
      matRippleColor="red" 
      [matRippleRadius]="20" 
      [matRippleCentered]="true"
    >

    效果

 

Ripple の Trigger

Trigger 的玩法是这样的

<button class="my-mat-extended-fab-button" matRipple [matRippleTrigger]="rippleTrigger">
  <mat-icon>edit</mat-icon>
  Create products
</button>

<button class="trigger-btn" #rippleTrigger>trigger</button>

当点击 Extended Fab Button 时,它不会有 Ripple 效果,反而是点击 trigger button 时 Extended Fab Button 才会出现 Ripple 效果,换了触发器。

效果

 

Ripple の Manual Trigger

Ripple 指令有一个 launch 方法,我们可以完全控制触发的时机。

export class AppComponent {
  // 1. 获取 Ripple 指令
  readonly myMatExtendedFabButtonRipple = viewChild.required('myMatExtendedFabButton', { read: MatRipple });

  constructor() {
    // 2. 最好等第一轮渲染完成后才干活
    afterNextRender(() => {
      // 3. 每 500ms 波动一次
      window.setInterval(() => {
        // 4. 设定坐标 x, y
        const x = 97;
        const y = 161;

        // 5. 覆盖原本的,比如 e.g. color 等等,当然也可以不要覆盖
        const overrideConfig = {
          color: 'pink',
        } satisfies RippleConfig;

        // 6. 调用 launch 方法触发 Ripple 效果
        this.myMatExtendedFabButtonRipple().launch(x, y, overrideConfig);
      }, 500);
    });
  }
}

触发时可以设置坐标 x, y。

效果

坐标是对着 viewport 算的,不管有没有 scroll,它和 getBoundingClientRect 算法一样。

 

目录

上一篇 Angular Material 17+ 高级教程 – Material Icon

下一篇 Angular Material 17+ 高级教程 – CDK Accessibility の Focus

想查看目录,请移步 Angular 17+ 高级教程 – 目录

 

posted @ 2024-03-09 15:58  兴杰  阅读(12)  评论(0编辑  收藏  举报