@pikselin/ngx-fittext is an Angular library that allow you fit text in a box or a line.
Demo Page | Stackblitz Example
You can see in examples Angular Material components like mat-card. These are not required. It is only for showing examples clearly in demo page.
npm i -S @pikselin/ngx-fittext
import { NgxFitTextModule } from '@pikselin/ngx-fittext';
@NgModule({
imports: [
// other modules
NgxFitTextModule
]
})
With fit-line component you can fit text to line. Every child element in this component will be fitted to line.
Important!
Because of this library calculate overflow by element scrollWidth, every child element need to be full width or display block by the default. For the same reason using block elements in child elements may cause problems.
<fit-line><div>Lorem ipsum dolor sit amet.</div></fit-line>
<fit-line>
<div style="background-color: orange">AM<b style="color: tomato">O</b>K</div>
<div style="background-color: teal; color: #fafafa">Stefan Zweig</div>
</fit-line>
If you will change content dynamicly you need to refresh the fit-line component. Remember that calculation function works on AfterViewInit.
- component.html
<mat-card class="mx-auto my-3 w-720px" *ngIf="exampleLine">
<fit-line #dynamicFitText>
<div>{{ exampleLine }}</div>
</fit-line>
</mat-card>
<div class="py-3 d-flex justify-content-center">
<button mat-raised-button color="primary" (click)="setRandomQuote()">
Random Quote
</button>
</div>
- component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import { FitLineComponent } from '@pikselin/ngx-fittext';
@Component({
selector: 'fit-line-hero',
templateUrl: './fit-line-hero.component.html',
styleUrls: ['./fit-line-hero.component.scss'],
})
export class FitLineHeroComponent implements OnInit {
@ViewChild('dynamicFitText') dynamicFitText: FitLineComponent;
exampleLines = [
'Peace at Home, Peace in the World',
'Our true mentor in life is science.',
'The unexamined life is not worth living',
'To be or not to be',
'An ounce of practice is worth a thousand words.',
'I am indebted to my father for living, but to my teacher for living well.',
'It is during our darkest moments that we must focus to see the light.',
'The supreme art of war is to subdue the enemy without fighting.',
];
exampleLine: string;
ngOnInit(): void {
this.setRandomQuote();
}
setRandomQuote() {
this.exampleLine =
this.exampleLines[Math.floor(Math.random() * this.exampleLines.length)];
this.dynamicFitText.refreshText();
}
Option | Type | Description |
---|---|---|
[stepSize] | number | When increasing or decreasing font uses stepSize. Default value is 2. Unit is getting from getComputedStyle component. |
[calcOnResize] | boolean | When true component will listen window resize event and it will calculate again on resized. |
[minFontSize] | number | Set minimum font size of component. If it overflow element may be multiline. |
[maxFontSize] | number | Set maximum font size of component. Default value is 500. |
(showInfo) | output | When font resize return font size and resized element. |
If you need to fit text into the box you could use fit-text component. fit-text component's display is flex. To align items, justify content you could use style tag. height is required params for fit-text component.
Using line-height in style may cause vertical align problems. Please take a care when styling, if styling block calculating component wont work correctly.
<mat-card class="my-3" style="width:400px">
<fit-text height="200px" [stepSize]="1" style="align-items: center;">
Aliquam erat volutpat. Curabitur et tincidunt nisl. Nunc non pellentesque
erat. Ut non dignissim nunc. Aenean condimentum venenatis augue vel
ultricies. Ut consequat egestas purus.
</fit-text>
</mat-card>
<div
style="
width: 500px;
display: grid;
grid-template-columns: repeat(2, 1fr);
"
>
<fit-text
height="250px"
width="250px"
style="background-color: cyan; justify-content: center; align-items: center;"
>C</fit-text
>
<fit-text
height="250px"
width="250px"
style="background-color: magenta;justify-content: center;align-items: center;"
>M</fit-text
>
<fit-text
height="250px"
width="250px"
style="background-color: yellow;justify-content: center;align-items: center;"
>Y</fit-text
>
<fit-text
height="250px"
width="250px"
style="background-color: black; color:#efefef;justify-content: center;align-items: center;"
>K</fit-text
>
</div>
As like as fit-line component if you change content dynamicly you need to refresh the fit-text component. You could do this by using ViewChild in Angular.
- component.html
<div
class="mat-elevation-z5 mt-3"
style="
padding: 10px;
background-color: #efefef;
width: 600px;
margin-top: 30px;
border-radius: 6px;
"
>
<img src="assets/ataturk-ders.jpg" alt="Atatürk ders dinlerken" />
<div
style="background-color: #fafafa; border-radius: 6px; padding: 10px"
class="mt-3"
>
<fit-text
#dynamicFitText
height="200px"
width="560px"
style="justify-content: center; align-items: center"
>{{ ataturkQuote }}</fit-text
>
</div>
</div>
- component.ts
import { Component, OnInit, ViewChild } from "@angular/core";
import { FitTextComponent } from "@pikselin/ngx-fittext";
@Component({
selector: "fit-text-hero",
templateUrl: "./fit-text-hero.component.html",
styleUrls: ["./fit-text-hero.component.scss"],
})
export class FitTextHeroComponent implements OnInit {
@ViewChild("dynamicFitText") private dynamicFitText: FitTextComponent;
readonly ataturkQuotes = [
"Everything we see in the world is the creative work of women.",
"Heroes who shed their blood and lost their lives! You are now lying in the soil of a friendly country. Therefore rest in peace. There is no difference between the Johnnies and Mehmets to us where they lie side by side here in this country of ours. You, the mothers, who sent their sons from far away countries wipe away your tears; your sons are now lying in our bosom and are in peace. After having lost their lives on this land they have become our sons as well.",
"Teachers are the one and only people who save nations.",
"Peace at Home, Peace in the World",
"Unless a nation's life faces peril, war is murder.",
"Our true mentor in life is science.",
'Victory is for those who can say "Victory is mine". Success is for those who can begin saying "I will succeed" and say "I have succeeded" in the end.',
"If one day, my words are against science, choose science.",
"The biggest battle is the war against ignorance.",
"My people are going to learn the principles of democracy the dictates of truth and the teachings of science. Superstition must go. Let them worship as they will, every man can follow his own conscience provided it does not interfere with sane reason or bid him act against the liberty of his fellow men.",
];
ataturkQuote = this.randomQuote;
constructor() {}
ngOnInit(): void {}
get randomQuote() {
return this.ataturkQuotes[
Math.floor(Math.random() * (this.ataturkQuotes.length - 1))
];
}
setRandomQuote() {
this.ataturkQuote = this.randomQuote;
this.dynamicFitText.refreshText();
}
}
Option | Type | Description |
---|---|---|
[height] | string | Height is a required field that set component height. |
[width] | string | Width is a optional field that set component width. By default width is 100%. |
[stepSize] | number | When increasing or decreasing font uses stepSize. Default value is 2. Unit is getting from getComputedStyle component. |
[calcOnResize] | boolean | When true component will listen window resize event and it will calculate again on resized. |
[minFontSize] | number | Set minimum font size of component. If it overflow element may be multiline. |
[maxFontSize] | number | Set maximum font size of component. Default value is 500. |
(showInfo) | output | When font resize return font size with unit. |
@pikselin/ngx-fittext library is nested in demo project. With this section you see changes easly.
- build library in watch mode
ng build @pikselin/ngx-fittext --watch
Then you can serve app by ng serve
command in local at 4200 port by defaulty.