Skip to content

@texmorph/dom ​

The renderer-agnostic DOM driver. Applications usually reach it through @texmorph/katex or @texmorph/mathjax; use it directly with a shared or custom renderer.

createMorphWith ​

ts
function createMorphWith<Opts>(
  renderer: FormulaRenderer<Opts>,
  host: HTMLElement,
  from: FormulaInput,
  to: FormulaInput,
  options?: MathMorphOptions<Opts>,
): Promise<MathMorph>;

Prepares a morph with any renderer. The renderer packages' createMorph functions are thin wrappers around it.

renderFormula ​

ts
function renderFormula<Opts>(
  renderer: FormulaRenderer<Opts>,
  host: HTMLElement,
  state: LatexState,
  opts?: Opts,
  signal?: AbortSignal,
): Promise<RenderedFormula>;

Renders a single formula into host, exactly as a morph would. The result can be passed as from to a later morph without rendering again.

MathMorph ​

ts
interface MathMorph {
  readonly duration: number;
  readonly plan: MorphPlan;
  readonly diagnostics: readonly MorphDiagnostic[];
  readonly state: 'ready' | 'refreshing' | 'disposed';
  readonly target: RenderedFormula;
  readonly shapes: boolean;
  render(progress: number): void;
  refresh(): Promise<MorphPlan>;
  dispose(options?: { settle?: 'source' | 'target' }): void;
}
MemberDescription
render(progress)Draws the frame for progress. Values are clamped to [0, 1]; NaN throws RangeError. Reads no layout. At exactly 0 and 1 the real formulas are shown.
refresh()Re-measures both formulas and rebuilds the plan, then re-renders the last progress. Until it settles, render uses the previous plan; a newer refresh() cancels an older one. On failure the previous state stays intact.
dispose({ settle })Removes the morph and leaves the target (default) or source formula in the container. Idempotent; aborts pending work.
durationoptions.duration or 800 ms. Metadata for your clock.
planThe current plan (replaced by refresh).
diagnosticsDiagnostics from preparation and planning.
targetThe target RenderedFormula, reusable as the next morph's from. Throws TexMorphLifecycleError after dispose({ settle: 'source' }).
shapesWhether outlines are being morphed right now (outline morphing). False when no glyph changes shape, on renderers without outlines, and after a frame-rate fallback.

MathMorphOptions ​

ts
interface MathMorphOptions<Opts = unknown> extends Omit<PlanOptions, 'origins'> {
  duration?: number;
  strict?: boolean;
  signal?: AbortSignal;
  rendererOptions?: Opts;
  progressMap?: (t: number) => number;
  shapes?: 'auto' | 'always' | 'off';
  minFps?: number;
}
OptionDefaultDescription
easing'easeInOutCubic'An EasingSpec.
morphMapnoneExplicit token mapping (guide).
arc0.2Path curvature of matched tokens.
removed.endScale0.7Final scale of removed tokens.
added.startScale, added.start0.7, 0.3Initial scale and fade-in start of added tokens.
duration800Milliseconds; metadata only.
strictfalseReject instead of falling back to a crossfade.
signalnoneCancels preparation (and waiting for fonts).
rendererOptionsnonePassed to the renderer for both formulas.
progressMapnoneApplied to progress before sampling; use for custom easing functions.
shapes'auto'Outline morphing for matched glyphs whose shapes differ. 'auto' falls back to stretch-and-crossfade when playback drops below minFps; 'always' never falls back (use it for video export); 'off' disables it.
minFps50Frame rate below which shapes: 'auto' falls back.

FormulaInput ​

ts
type FormulaInput = LatexState | RenderedFormula | { adopt: Element; fallback?: LatexState };

type LatexState = { latex: string; displayMode?: boolean; className?: string };

See Chaining steps.

RenderedFormula ​

ts
interface RenderedFormula {
  readonly root: HTMLElement | SVGElement;
  readonly snapshot: FormulaSnapshot;
  readonly state: LatexState;
  readonly renderer: { readonly name: string; readonly version: string };
  readonly diagnostics: readonly MorphDiagnostic[];
}

Errors ​

ClassThrown when
MorphPrepareErrorPreparation fails in strict mode, or an input cannot be adopted. Has diagnostics.
TexMorphLifecycleErrorrender, refresh or target is used after the morph was disposed.

FormulaRenderer ​

ts
interface FormulaRenderer<Opts = unknown> {
  readonly name: string;
  readonly version: string;
  ready?(signal?: AbortSignal): Promise<void>;
  render(container: HTMLElement, state: LatexState, opts: Opts | undefined, signal?: AbortSignal): Promise<RenderedFormula>;
  adopt?(el: Element, signal?: AbortSignal): Promise<RenderedFormula | null>;
  resnapshot(rendered: RenderedFormula): RenderedFormula;
  maskTokens(rendered: RenderedFormula): () => void;
  createGhostLayer(stage: HTMLElement, bounds: Box): GhostLayer;
  createGhost(token: MathToken, rendered: RenderedFormula): Element;
  stylesheet?(): CSSStyleSheet | string;
  loadShapes?(signal?: AbortSignal): Promise<void>;
  createShapeGhost?(source: Element, target: Element, track: Track): ShapeGhost | null;
  watchFrameRate?(minFps: number, onSlow: (fps: number) => void): FrameRateWatch;
}

interface FrameRateWatch {
  touch(): void;
  stop(): void;
}

interface ShapeGhost {
  readonly el: Element;
  draw(mix: number): void;
}

interface GhostLayer {
  readonly root: HTMLElement | SVGElement;
  add(ghost: Element): void;
  place(ghost: Element, frame: GhostFrame, track: Track): void;
  dispose(): void;
}

The contract a renderer implements; see Writing a renderer.

HTML ghost helpers ​

ts
function createHtmlGhostLayer(stage: HTMLElement, bounds: Box): GhostLayer;
function placeHtmlGhost(ghost: HTMLElement, frame: GhostFrame, track: Track): void;
const DEFAULT_DURATION: 800;

A ready-made ghost layer for renderers whose ghosts are HTML elements.

Released under the MIT License.