Miraiclip SDK
Creative

Text & typography

Weight, line height, letter spacing, alignment.

project.dispatch({
  type: "asset/add",
  payload: { id: "inter-700", kind: "font", src: "/fonts/Inter-Bold.woff2", family: "Inter", weight: 700 },
});

project.dispatch({
  type: "clip/add",
  payload: {
    kind: "text",
    id: "headline",
    trackId: "titles",
    startUs: 0,
    durationUs: 3_000_000,
    text: "SALE\nToday only",
    fontFamily: "Inter",
    fontSizePx: 96,
    color: "#ffffff",
    fontWeight: 700,
    lineHeight: 1.1,
    letterSpacing: 0.04,
    textAlign: "center",
    transform: { y: 0.3 },
  },
});

Text clip fields

FieldDefaultMeaning
textrequiredThe string to draw. \n starts a new line
fontFamily"sans-serif"A font asset's family, or a system font
fontSizePx48Size in composition pixels
color"#ffffff"CSS color
fontWeight, fontStyle, lineHeight, letterSpacingabsentTypography
textAlignabsent ("left")Aligns lines within the text block. It doesn't move the block: transform places it

Text clips also have the fields every clip has (transform, animations, effects). See Clips.

Typography fields

Text clips and caption styles share these optional fields. Absent means the default in TYPOGRAPHY_DEFAULTS, and the document only stores fields you set.

FieldValuesDefault
fontWeight100 to 900, multiples of 100400
fontStyle"normal" | "italic""normal"
lineHeightMultiple of font size, > 0 and ≤ 5The font's natural line height (captions: 1.3)
letterSpacingEm, from -0.5 to 2. Scales with font size0
textAlign"left" | "center" | "right""left". Text clips only
import { TYPOGRAPHY_DEFAULTS } from "@miraiclip/core";

TYPOGRAPHY_DEFAULTS;
// { fontWeight: 400, fontStyle: "normal", letterSpacing: 0, textAlign: "left", captionLineHeight: 1.3 }

Read defaults from TYPOGRAPHY_DEFAULTS in a properties panel instead of hard-coding them.

Editing

project.dispatch({
  type: "clip/set-property",
  payload: { clipId: "headline", text: "SALE\nThis weekend", fontWeight: 900, fontStyle: "italic" },
});

// null clears a typography field back to its default
project.dispatch({ type: "clip/set-property", payload: { clipId: "headline", letterSpacing: null, textAlign: null } });
Field in clip/set-propertyAccepts null
text, fontFamily, fontSizePx, colorNo
fontWeight, fontStyle, lineHeight, letterSpacing, textAlignYes: clears to default

Typography fields on a non-text clip are rejected with not-text. For captions, set them inside style: see Captions.

Fonts

Register one font asset per face. Clips reference the family, not the asset id.

project.transaction(() => {
  project.dispatch({
    type: "asset/add",
    payload: { id: "inter-400", kind: "font", src: "/fonts/Inter-Regular.woff2", family: "Inter", weight: 400 },
  });
  project.dispatch({
    type: "asset/add",
    payload: { id: "inter-400i", kind: "font", src: "/fonts/Inter-Italic.woff2", family: "Inter", weight: 400, style: "italic" },
  });
});

For a variable font, register one asset with a weight range. Every weight in the range then renders from the font's own axis:

project.dispatch({
  type: "asset/add",
  payload: { id: "inter-var", kind: "font", src: "/fonts/InterVariable.woff2", family: "Inter", weightRange: [100, 900] },
});
Font asset fieldMeaning
familyRequired. The CSS family name clips use
weightThe face's weight (default 400)
style"normal" or "italic" (default "normal")
weightRange[min, max] for a variable font. Takes precedence over weight
  • Without a face that matches the clip's fontWeight or fontStyle, the browser synthesizes bold or italic.
  • asset/add rejects a font without family (font-needs-family), and weight/style/weightRange on non-font assets (not-font).
  • The player, exportProject and renderProjectStill load font assets before drawing. Call loadFontAssets(doc) from @miraiclip/renderer only when your own code needs the fonts in the page, for example to preview a font in a picker.
import { loadFontAssets } from "@miraiclip/renderer";

await loadFontAssets(project.getState().doc); // true when a new font finished loading

On this page