Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic font loading with Angular 2

Hey is it possible to load Fonts dynamically with Angular 2.4? I tried the following but it does not work.

<style>
  @font-face { font-family: '{{ font.name }}';
    src: url('{{ font.url }}')  format('woff'); }
</style>
@Component({
  selector: 'nova-font-loader',
  templateUrl: './template.html'
})
export class NovaFontLoaderComponent implements OnInit {

  private font;

  constructor() { }

  ngOnInit() {
    this.font = {
      url: 'test.woff',
      name: 'test'
    };
  }

}

It generates the following console output:

GET http://localhost:4200/url(%7B%7B%20font.url%20%7D%7D) 404 (Not Found)

Unhandled Promise rejection: Failed to load url(%7B%7B%20font.url%20%7D%7D) ; Zone: ; Task: Promise.then ; Value: Failed to load url(%7B%7B%20font.url%20%7D%7D)

like image 837
Andre Steudel Avatar asked Jan 03 '23 13:01

Andre Steudel


2 Answers

You can create a compononent for each font-style, and import in your root component conforms the condition:

Example for Roboto.

Component

Note: encapsulation: ViewEncapsulation.None is very important for this case.

import { Component, OnInit, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'app-font-roboto',
  templateUrl: './font-roboto.component.html',
  encapsulation: ViewEncapsulation.None,
  styleUrls: ['./font-roboto.component.scss']
})
export class FontRobotoComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

SCSS

@font-face {
    font-family: 'Roboto';
    src: url("/assets/fonts/Roboto/Roboto-Regular.eot");
    /* IE9 Compat Modes */
    src: url("/assets/fonts/Roboto/Roboto-Regular.eot?#iefix") format('embedded-opentype'), /* IE6-IE8 */
    url('/assets/fonts/Roboto/Roboto-Regular.ttf') format('truetype'), /* Safari, Android, iOS */
}

@font-face {
    font-family: 'RobotoBold';
    src: url("/assets/fonts/Roboto/Roboto-Bold.eot");
    /* IE9 Compat Modes */
    src: url("/assets/fonts/Roboto/Roboto-Bold.eot?#iefix") format('embedded-opentype'), /* IE6-IE8 */
    url('/assets/fonts/Roboto/Roboto-Bold.ttf') format('truetype'), /* Safari, Android, iOS */
}

body { 
    font-family: 'Roboto', sans-serif;
}

Root component logic

Template [HTML]

<div [ngSwitch]="fontType">
   <app-font-roboto *ngSwitchCase="'Roboto'"></app-font-roboto>
</div>

Component

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  fontType: string;

  ngOnInit(): void {
    this.fontType = 'Roboto';
  }
}

Just add your application logic to get the current font and add new nodes in switch for each font styles that you need.

like image 74
Leonardo Oliveira Avatar answered Jan 27 '23 18:01

Leonardo Oliveira


You can easily do that by injecting css in your dom

const fontUrl = '[get your font url here]';
this.styles = `
@font-face {
  font-family: 'font1';
  src: url(${fontUrl}) format('woff');
}
h1, h2, h3 {
  font-family: font1, sans-serif;
}`

const node = document.createElement('style');
node.innerHTML = this.styles;
document.body.appendChild(node);
like image 35
Thibaud Lacan Avatar answered Jan 27 '23 20:01

Thibaud Lacan