Angular:一些 Google Material 图标未在浏览器中显示

问题描述 投票:0回答:1

我正在为我的 Angular 项目开发一个自定义图标库,因为 Font Awesome 中的许多图标现在都不是免费的。 我使用了 Google Material Icons,将它们实现为样式表。然后我创建了一个图标服务和一个图标指令以便于调用。

这是我的 icon.service.ts:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class IconsService {
  constructor(private http: HttpClient, private sanitizer: DomSanitizer) {}

  getIcon(name: string): Observable<SafeHtml> {
    return this.http.get(`assets/icons/${name}.svg`, { responseType: 'text' }).pipe(
      map(svgString => this.sanitizer.bypassSecurityTrustHtml(svgString) as SafeHtml) // assert non-null
    );
  }
}

我的图标指令是完成大部分工作的地方:

import {Directive, ElementRef, Input, Renderer2} from '@angular/core';

@Directive({
  selector: '[icon]',
  standalone: true,
})
export class IconDirective {
  private _iconName: string = '';
  private _spin: boolean = false;
  private _size: string | undefined;
  private _flipHorizontal: boolean = false;
  private _flipVertical: boolean = false;
  private _color: string | undefined;

  @Input('icon')
  set icon(value: string) {
    const parts = value.split(' ');
    this._iconName = parts[0];

    this._spin = parts.includes('spin');

    this._flipHorizontal = parts.includes('flip-horizontal');

    this._flipVertical = parts.includes('flip-vertical');

    this._size = parts.find(part => part.match(/^[0-5]x$/)) || '1x'; // Default to 1x

    const colorPart = parts.find(part => part.startsWith('color-'));
    this._color = colorPart ? colorPart.split('-')[1] : undefined;

    this.updateIcon();
  }

  constructor(private el: ElementRef, private renderer: Renderer2) {
  }

  ngAfterViewInit(): void {
    this.setupLazyLoading();
  }

  private setupLazyLoading(): void {
    const options = {
      root: null, // observes changes in the viewport
      threshold: 0.01, // trigger when 1% of the element is visible
    };

    const observer = new IntersectionObserver((entries, observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          this.updateIcon();
          observer.unobserve(entry.target); // Stop observing once loaded
        }
      });
    }, options);

    observer.observe(this.el.nativeElement);
  }

  private updateIcon(): void {
    console.log('Updating icon');
    // Clear previous classes
    this.el.nativeElement.className = '';

    // Set text content to the icon name
    this.renderer.setProperty(this.el.nativeElement, 'textContent', this._iconName);
    this.renderer.addClass(this.el.nativeElement, 'material-icons');

    // Apply size, spin, and flip classes
    if (this._spin) {
      this.renderer.addClass(this.el.nativeElement, 'spin');
    }
    if (this._flipHorizontal) {
      this.renderer.addClass(this.el.nativeElement, 'flip-horizontal');
    }
    if (this._flipVertical) {
      this.renderer.addClass(this.el.nativeElement, 'flip-vertical');
    }
    if (this._size) {
      this.renderer.addClass(this.el.nativeElement, `icon-${this._size}`);
    }
    if (this._color) {
      this.renderer.setStyle(this.el.nativeElement, 'color', this._color);
    }
  }
}

此时我的html:

<h1>Icon examples</h1>
<h2>Sizing: <i icon="search"></i><i icon="search 2x"></i><i icon="search 3x"></i></h2>
<h2>Spinning: <i icon="search spin"></i></h2>
<h2>Flipping horizontally and vertically: <i icon="search flip-horizontal"></i><i icon="search flip-vertical"></i></h2>
<h2>Colors: <i icon="search color-blue"></i><i icon="search color-red"></i><i icon="search color-green"></i></h2>
<h1>Button example: <button><i icon="donut_large spin"></i>Loading</button></h1>
<button><i icon="settings 2x"></i></button>
<button><i icon="menu 2x"></i></button>
<!--<button><i icon="stacks 2x"></i></button>-->
<button><i icon="print 2x"></i></button>
<button><i icon="open_with 2x"></i></button>
<button><i icon="add 2x"></i></button>
<button><i icon="public 2x"></i></button>
<!--<button><i icon="captive_portal 2x"></i></button>-->
<button><i icon="filter_alt 2x"></i></button>
<button><i icon="filter_alt_off 2x"></i></button>
<button><i icon="arrow_forward_ios 2x"></i></button>
<button><i icon="arrow_back_ios 2x"></i></button>
<button><i icon="pan_tool 2x"></i></button>
<button><i icon="progress_activity 2x"></i></button>

但这就是我在屏幕上看到的,一些图标(例如进度活动)没有呈现,我做错了什么?

last icon not visible/rendering

我尝试更改浏览器,更改我的CSS以包含字体系列..什么也没有。

 /*Icon base styles */
[icon] {
  display: inline-block;
  font-size: 16px;
  padding: 2px;
  fill-opacity: 0;
  vertical-align: middle;
  horiz-align: center;
}

 @font-face {
   font-family: 'Material Icons';
   font-style: normal;
   font-weight: 400;
   src: url(https://example.com/MaterialIcons-Regular.eot); /* For IE6-8 */
   src: local('Material Icons'),
   local('MaterialIcons-Regular'),
   url(https://example.com/MaterialIcons-Regular.woff2) format('woff2'),
   url(https://example.com/MaterialIcons-Regular.woff) format('woff'),
   url(https://example.com/MaterialIcons-Regular.ttf) format('truetype');
 }


/* Icon size variations */
@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.spin {
  animation: spin 2s infinite linear;
  padding: 2px;
}

 .flip-horizontal {
   transform: scaleX(-1);
 }

 .flip-vertical {
   transform: scaleY(-1);
 }

 .flip-left {
   transform: rotateY(180deg);
 }

 .flip-right {
   transform: rotateY(-180deg);
 }

 .material-icons.icon-1x { font-size: 16px; } /* Default Material Icons size */
 .material-icons.icon-2x { font-size: 32px; }
 .material-icons.icon-3x { font-size: 48px; }
 .material-icons.icon-4x { font-size: 64px; }
angular angular-directive google-material-icons material-icons
1个回答
0
投票

我可以看到

[progress_activity](https://fonts.google.com/icons?icon.query=progress_activity)
位于 Material Symbols 集合中,但 位于 Material Icons 集合中。

我最初的猜测是,您按照说明安装了 Material Icons,如果您想要其他图标,例如

progress_activity
,您应该 遵循 Material Symbols 的说明

© www.soinside.com 2019 - 2024. All rights reserved.