Text Sizing
Fit variable text into a fixed box, cap lines, and measure the result
Templates reserve space for text that changes later: a name, a headline, a
price. Text sizing gives each text element its own policy: fit the text into
its box between size bounds, cap its lines, or cut it with an ellipsis.
fontSize is never rewritten, so a long value shrinks and a shorter one grows
back. The editor, polotno-node and every exporter size text the same way.
Live demo
Type into the fields: the headline and the price fit their boxes, the
description stops after two lines, the footer is cut with an ellipsis, and the
panel shows what measureText reports for the headline.
The four fields
Four optional fields on a text element control it:
| Field | Meaning | When omitted |
|---|---|---|
textOverflow | 'resize', 'ellipsis' or 'fit' | The global text overflow setting |
maxLines | Cap on visible lines, in every mode; text past it ends in an ellipsis | No cap |
minFontSize | Smallest size 'fit' may draw at, in px | 1px |
maxFontSize | Largest size 'fit' may draw at, in px | fontSize |
The fields work in the editor, in polotno-node and in the SVG, HTML, PDF and PPTX exporters, so an export shows the same text as the canvas.
Fit text into its box
'fit' draws the text at the largest size that fits the box, between
minFontSize and maxFontSize. It never writes the fitted size back: fontSize
stays the authored size, so a long value shrinks and a shorter one grows back.
const title = store.selectedElements[0];
// shrink down to 12px when the text is long, grow up to 72px when it is short
title.set({ textOverflow: 'fit', minFontSize: 12, maxFontSize: 72 });Without maxFontSize, 'fit' only shrinks. Set it above fontSize to let
short text grow.
Inline sizes in rich text, stroke and shadow scale with the fitted size, so a styled headline keeps its proportions.
Replace template values
Mark the variable elements in your template with a custom property, then set
their text and let 'fit' do the rest.
// in the template, once
nameElement.set({
custom: { field: 'name' },
textOverflow: 'fit',
minFontSize: 16,
maxFontSize: 64,
});
// for each generated design
const values = { name: 'Alexandra Konstantinopolsky', city: 'Berlin' };
store.pages.forEach((page) => {
page.children.forEach((element) => {
const field = element.custom?.field;
if (element.type === 'text' && field in values) {
element.set({ text: values[field] });
}
});
});Every renderer sizes the text the same way, so the design can be exported
right away with store.toDataURL() or on the server with polotno-node.
Cap the number of lines
maxLines limits visible lines in every mode. Text past the cap ends in an
ellipsis. Under 'fit' the cut falls between paragraphs: the text shrinks until
every visible paragraph is complete, and later paragraphs are dropped.
// a card description: two lines at the authored size, then "…"
description.set({ textOverflow: 'resize', maxLines: 2 });
// a fitted headline that may never wrap to a third line
headline.set({ textOverflow: 'fit', fontSize: 48, maxLines: 2 });With 'resize' the box grows to the capped height. With 'ellipsis' and
'fit' the box stays as authored.
Measure before you commit
measureText returns the layout the canvas
draws. Pass an element, or plain text properties with the sizing fields, to
check a value before writing it into the design.
import { measureText } from 'polotno/utils/measure-text';
const result = await measureText({
...title.toJSON(),
text: 'A much longer headline than the template planned for',
textOverflow: 'fit',
});
result.fontSize; // the size the text is drawn at
result.lineCount; // visible lines
result.truncated; // true when some text does not fit even at minFontSizeUse truncated to reject a value, pick a shorter one or fall back to a
different layout.
Fit everything
To fit every text element that sets no policy of its own, change the global setting instead:
import { setTextOverflow } from 'polotno/config';
setTextOverflow('fit');An element's own textOverflow, maxLines and size bounds still apply. On the
server, pass textOverflow: 'fit' in polotno-node's render attrs or the
exporter options for the same result.
Curved text
Under 'fit', curved text takes the largest size whose arc fits the element
width. maxLines and box height do not apply to curves.