Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

JosephusPaye/svg-text

Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

svg-text

Measure and wrap text into lines for SVG in the browser.

This project is part of #CreateWeekly, my attempt to create something new publicly every week in 2020.

Installation

npm install -g @josephuspaye/svg-text

Usage

Measure text

The following example shows how to measure strings of text (runs in the browser):

import { measureText } from '@josephuspaye/svg-text';

const measures = measureText(['nyan', 'oh hai mark'], {
  fontFamily: 'Helvetica, Arial, sans-serif',
  fontWeight: 'bold',
  fontSize: '2em',
});

console.log(`measure for 'nyan':`, measures[0]);
console.log(`measure for 'oh hai mark':`, measures[1]);
View output
measure for 'nyan': { width: 74.6875, height: 35.21875 }
measure for 'oh hai mark': { width: 180.21875, height: 35.21875 }

Wrap text

The following example shows how to layout text into wrapped lines (runs in the browser):

import { layoutText } from '@josephuspaye/svg-text';

const lines = layoutText(
  'The tired teacher told Tom to take thirty-three tables to the townhall.',
  { maxWidth: 300, maxLines: 2 },
  {
    fontFamily: 'Helvetica, Arial, sans-serif',
    fontWeight: 'bold',
    fontSize: '2em',
  },
  {
    lineSpacing: 8,
  }
);

console.log(lines);
View output
[
  {
    width: 259.015625,
    height: 78.4375,
    lines: [
      {
        text: 'The tired teacher',
        measure: {
          width: 259.015625,
          height: 35.21875,
        },
        position: {
          x: 0,
          y: 0,
        },
      },
      {
        text: 'told Tom to take',
        measure: {
          width: 244.734375,
          height: 35.21875,
        },
        position: {
          x: 0,
          y: 43.21875,
        },
      },
    ],
  },
  {
    width: 270.28125,
    height: 78.4375,
    lines: [
      {
        text: 'thirty-three tables',
        measure: {
          width: 270.28125,
          height: 35.21875,
        },
        position: {
          x: 0,
          y: 0,
        },
      },
      {
        text: 'to the townhall.',
        measure: {
          width: 234.640625,
          height: 35.21875,
        },
        position: {
          x: 0,
          y: 43.21875,
        },
      },
    ],
  },
];

API

type ElementAttrs = Record<string, string | number>;

interface TextMeasure {
  width: number;
  height: number;
}

interface MeasuredLine {
  text: string;
  measure: TextMeasure;
  position: {
    x: number;
    y: number;
  };
}

interface LineGroup {
  width: number;
  height: number;
  lines: MeasuredLine[];
}

/**
 * Measure the given array of texts by converting them to SVG
 * <text> elements, temporarily appending to the DOM, and
 * measuring their rendered bounding boxes.
 *
 * `fontAttrs` is an object of SVG `font-*` attributes for
 * the rendered <text> elements.
 */
function measureText(texts: string[], fontAttrs: ElementAttrs): TextMeasure[];

/**
 * Layout the given text to fit the given constraints, with line
 * wrapping and line spacing. Returns groups of lines each with
 * no more than `constraints.maxLines` number of lines.
 */
function layoutText(
  text: string,
  constraints: {
    maxWidth: number;
    maxLines: number;
  },
  fontAttrs: ElementAttrs,
  lineAttrs: {
    lineSpacing: number;
  }
): LineGroup[];

Licence

MIT

About

Measure and wrap text into lines for SVG in the browser

Topics

Resources

Stars

Watchers

Forks

Releases

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.