Truncator

Truncate multi lines. Responsive

by kontrach

HTML

<div id="app"></div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
  text-align: center;
}

TypeScript

interface TruncatorOptions {
  /* selector for DOM element to be truncated */
  selector: string;
  /* string which will be added to last line */
  ellipsis: string;
  /* how many lines should stay after truncation */
  lines: number;
  /* string after ellipsis */
  afterEllipsis: string;
}

class Truncator {
  defaultOptions: TruncatorOptions = {
    ellipsis: '...',
    lines: 1,
    afterEllipsis: ''
  };
  
  container: HTMLElement;
  text: string;
  letters: Array<string>;
  lineHeight: number;
  targetHeight: number;
  
  constructor(private options: TruncatorOptions = {}) {
    this.options = {...defaultOptions, ...options};
    this.init();
  }
  
  init(): void {
    this.container = document.querySelector(this.selector);
    this.text = this.container.textContent.trim();
    this.letters = this.text.split('');
    this.lineHeight = this.getLineHeight(this.container);
    this.targetHeight = this.lines * this.lineHeight;
  }
  
  addListeners(): void {
    const bindedCalculate = this.calculate;
  	window.addEventListener('resize', bindedCalculate);

    window.addEventListener('unload', (): void => {
        window.removeEventListener('resize', bindedCalculate);
    });
  }
  
  calculate(): void {
  
  }
  
  getLineHeight(elem: HTMLElement): number {
    return parseFloat(window.getComputedStyle(elem).lineHeight);
  }
  
  getContainerHeight(elem: HTMLElement): number {
    return parseFloat(window.getComputedStyle(elem).height);
  }
  
  constructText(index: number): void {
    const ellipsis = (index > this.letters.length) ? ' ' : this.ellipsis;
    const text = this.letters.slice(0, index).join('').trim() + ellipsis + this.afterEllipsis;
    this.container.innerHTML = text;
  }

  calculate = function () {
    let fits = true;
    let i = 0;
    let currHeight = 0;

    while (fits) {
        if (i > this.letters.length) {
            this.constructText(i);
            fits = false;
        } else {
            this.constructText(i);
           ...