ng-zorro-antd-mobile icon的实现及拓展

发布时间 2023-09-20 20:47:56作者: kongshu

ng-zorro-antd-mobile icon的实现及拓展

  • 首先在全局的Dom 上面会插入一个id 为 ANTD_MOBILE_SVG_SPRITE_NODE的雪碧图,这个里面是个svg,其中包含了所有的svg的定义,每个svg 采用图标名称作为id.代码如下
<svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="https://www.w3.org/1999/xlink"
  id="__ANTD_MOBILE_SVG_SPRITE_NODE__"
  style="position:absolute;width:0;height:0"
>
  <defs>
    ${contents}
  </defs>
</svg>
`
  • 第一步的操作是在IconHandler.load()方法种实现的,同事所有的图标的定义也是存放在IconHandler中的。
  • 对于某一个图标的使用是通过Icon组件来实现的,其中的Template也是比较直接的
<svg *ngIf="type" class="am-icon" [ngClass]="clsMap" [ngStyle]="{ color: color }">
  <use xmlns:xlink="https://www.w3.org/1999/xlink" attr.xlink:href="#{{ type }}"></use>
</svg>
<img *ngIf="src" src="{{ src }}" class="am-icon" [ngClass]="clsMap" />
<ng-content></ng-content>

type 其实就是图标的名称,也就是雪碧图中的图标的id.

  • 如果我们想拓展图标集合,原生的图标集合是非常有限的。我提供一种方式来拓展。其实最主要的就是将定制化的图标集合添加到雪碧图中。思路答题是,先获取IconHandler,然后,将定制的图标集合添加到icons中,最后挂载dom.
// 调用该函数完成所有的操作
export function attachIcons(zorrowService: IconHandler, icons: { [iconName: string]: string } = ADIcons) {
  Object.assign(zorrowService.icons, icons);
  _reload(zorrowService);
}

// 卸载挂载点,如果已经挂载的化
function _reload(zorrowService: IconHandler) {
  if (!document) {
    return;
  }
  const existing = document.getElementById('__ANTD_MOBILE_SVG_SPRITE_NODE__');
  if (existing) {
    existing.parentElement?.removeChild(existing);
  }
  zorrowService.load();
}

//由于该操作只需要执行一次,我们可以借助App_INITIALIZE 来完成初始化的操作
@NgModule({
  imports: [CommonModule],
})
export class IconExtensionModule {
  static forRoot(): ModuleWithProviders<IconExtensionModule> {
    return {
      ngModule: IconExtensionModule,
      providers: [IconHandler, {
        provide: APP_INITIALIZER,
        deps: [IconHandler],
        useFactory: ((iconService: IconHandler) => {
          attachIcons(iconService);
          return () => { }
        }),
        multi: true,
      }]
    }
  }
}

svg 本身是个很神奇的工具,可以让我们画出一些很精致的图片,常用于logo图标的绘制。它相对于其他图片的好处是可以被css 作用。随便写写玩svg 用到的一些东西

  • viewBox="x1 y1 width height" 这个是定义画布的尺寸
  • defs元素,定义在这个里面的元素可以被其他地方使用,通过id 来进行定位。代码示例
<svg>
  <defs>
    <circle id="circle" cx="10" cy="10" r="10"/>
  </defs>
</svg>
  • use可以用来复制某个svg 元素,
<svg>
  <use xmlns:xlink="https://www.w3.org/1999/xlink" attr.xlink:href="{{#circle}}"></use>
</svg>

这个里面的东西很多,可以参考文档来使用