https://github.com/josephuspaye/svg-text
Measure and wrap text into lines for SVG in the browser
https://github.com/josephuspaye/svg-text
createweekly svg text-wrapping
Last synced: 10 months ago
JSON representation
Measure and wrap text into lines for SVG in the browser
- Host: GitHub
- URL: https://github.com/josephuspaye/svg-text
- Owner: JosephusPaye
- License: mit
- Created: 2020-12-01T11:24:24.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2020-12-01T12:28:16.000Z (over 5 years ago)
- Last Synced: 2025-02-21T21:41:25.836Z (over 1 year ago)
- Topics: createweekly, svg, text-wrapping
- Language: TypeScript
- Homepage:
- Size: 10.7 KB
- Stars: 1
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# svg-text
> Measure and wrap text into lines for SVG in the browser.
This project is part of [#CreateWeekly](https://twitter.com/JosephusPaye/status/1214853295023411200), my attempt to create something new publicly every week in 2020.
## Installation
```bash
npm install -g @josephuspaye/svg-text
```
## Usage
### Measure text
The following example shows how to measure strings of text (runs in the browser):
```js
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):
```js
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
```js
[
{
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
```ts
type ElementAttrs = Record;
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
* elements, temporarily appending to the DOM, and
* measuring their rendered bounding boxes.
*
* `fontAttrs` is an object of SVG `font-*` attributes for
* the rendered 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](LICENCE)