Polotno
Features

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:

FieldMeaningWhen omitted
textOverflow'resize', 'ellipsis' or 'fit'The global text overflow setting
maxLinesCap on visible lines, in every mode; text past it ends in an ellipsisNo cap
minFontSizeSmallest size 'fit' may draw at, in px1px
maxFontSizeLargest size 'fit' may draw at, in pxfontSize

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 minFontSize

Use 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.

On this page