How to inject SVG icon sprites in Angular component HTML DOM?

前端 未结 4 1803
Happy的楠姐
Happy的楠姐 2021-02-15 22:12

I am building an Angular application (Angular 4/5/6) and would like to use SVG sprites in my component template.

Question: Assuming I already have my S

相关标签:
4条回答
  • 2021-02-15 22:44

    you can convert your svg file to font by https://icomoon.io/app/#/select, upload your svg file and select it,click on the Generate Font then click the download button, download font file and choose font folder and put it in a folder in your project,

    import font file into css files

    @font-face {
       font-family: 'icomoon';
       src:  url('fonts/icomoon.eot?31svmk');
       src:  url('fonts/icomoon.eot?31svmk#iefix') format('embedded-opentype'),
       url('fonts/icomoon.ttf?31svmk') format('truetype'),
       url('fonts/icomoon.woff?31svmk') format('woff'),
       url('fonts/icomoon.svg?31svmk#icomoon') format('svg');
      font-weight: normal;
      font-style: normal;
    }
    

    declear your class like this

    .icon-home:before {
      content: "\ea77";
    }
    .icon-conection:before {
      content: "\ea78";
    }
    .icon-rocket:before {
     content: "\ea79";
    }
    

    and use it in your html

      <p>Icon (rocket): <i class="icon-rocket"></i> </p>
    

    The solution was to add the icons in the project, but if you want to use the svg code in the project, it's best to add the loader to it.

    If you have used the webpack:

      npm install svg-inline-loader --save-dev
    

    Simply add configuration object to module.loaders like this.

    {
        test: /\.svg$/,
        loader: 'svg-inline-loader'
    }
    

    more info

    0 讨论(0)
  • 2021-02-15 22:45

    I was in your same boat today with designers pushing back about the svg font. I also did not want to move the icon def out of the node_modules because it would change over time. I came up with a solution.

    You need to first create an angular icon component, then do something like this:

    import { Component, OnInit, Input } from '@angular/core';
    declare const require;
    @Component({
      selector: 'my-icon',
      templateUrl: './my-icon.component.html',
      styleUrls: ['./my-icon.component.scss']
    })
    export class IconComponent implements OnInit {
    
      constructor() { }
    
      @Input() icon: string = "";
      @Input() x: string = "0";
      @Input() y: string = "0";
      @Input() fillColor: string = "black";
      @Input() strokeColor: string = "black";
      @Input() height: string = "";
      @Input() width: string = "";
      private baseUrl: string = require("../../../../../node_modules/path/to/defs.svg") + "#beginning-of-iconset-";
    
      svgUrl: string = "";
    
      ngOnInit() {
      }
    
      ngAfterViewInit() {
        setTimeout(()=>{
          this.svgUrl = this.baseUrl + this.icon;
        },0);
    
      }
    
    }
    

    And then, in the html:

    <svg [attr.height]="height" [attr.width]="width" xmlns="http://www.w3.org/2000/svg">
      <use [attr.href]="svgUrl" [attr.x]="x" [attr.y]="y" [attr.fill]="fillColor" [attr.stroke]="strokeColor" />
    </svg>
    

    I'm still working on scaling the solution as the width and height attributes don't work as expected. You can also expand on the inputs as I know I will.

    Hope that helps.

    0 讨论(0)
  • 2021-02-15 22:57

    I think your root path is where you are having problems. In your code you are telling angular to look in app but the browser sees this as https://your-site.com./icons

    If you move your icon file under your /assets folder, then it should be available already because the src\assets folder is already included in angular.json, the "assets" collection tells Angular where to look.

    <svg class="icon">
       <use xlink:href="/assets/icons.svg#icon-rocket"></use> // Notice root path not "./"
    </svg>
    

    If you would like your files to be served from another directory all you need to do is add a path in your angular.json:

    …
    "assets": [
       "src/favicon.ico",
       "src/assets",
       "src/your-dir"
    ],
    …
    

    Then in your code

    <svg class="icon">
       <use xlink:href="/your-dir/icons.svg#icon-rocket"></use>
    </svg>
    

    I wouldn't suggest adding /src/app as an asset path, this would basically open up your entire app for serving files, making your entire directory accessible.

    I forked your example and updated here

    0 讨论(0)
  • 2021-02-15 23:08

    I solved this issue using angular material icon.

    Angular material injects the SVG by id and without shadow-dom.

    first install angular material:

    "@angular/material": "^7.3.7", // change version according to your angular version 
    

    Import to your module:

    MatIconModule
    

    Then declare your SVG sprite in the app.component or service..

        constructor(
            private matIconRegistry: MatIconRegistry,
            private domSanitizer: DomSanitizer) { 
    matIconRegistry.addSvgIconSet(this.domSanitizer.bypassSecurityTrustResourceUrl(`assets/sprite.svg`));
            }
    

    And last, In Html use angular material icon:

    <mat-icon svgIcon="svg-id"></mat-icon> // or use as directive <div svgIcon="svg-id"></div>
    

    Read more here

    0 讨论(0)
提交回复
热议问题