Exporting
Exporting in textmode.js is provided by the official add-on library textmode.export.js. (╯✧▽✧)╯
Install the export plugin alongside textmode.js, then add ExportPlugin to your sketch:
import { textmode } from "textmode.js";
import { ExportPlugin } from "textmode.export.js";
const t = textmode.create({
width: 800,
height: 600,
fontSize: 16,
plugins: [ExportPlugin],
});Once installed, the plugin adds runtime export helpers directly to your Textmodifier instance.
What can be exported
textmode.export.js covers six export targets:
- plain text via
toString()andsaveStrings() - structured document data via
toJSON(),toJSONString(), andsaveJSON() - SVG via
toSVG()andsaveSVG() - raster images via
saveCanvas()andcopyCanvas() - animated GIF via
saveGIF() - MP4 and WebM video via
saveVideo()
Two export models
textmode.export.js has two different export paths, and the distinction matters:
Canvas capture exports the final presented canvas exactly as it appears on screen. This includes layering, compositing, shaders, filters, and post-processing. Use this for:
Layer data export reads layer draw framebuffer data and converts it into another representation. TXT and SVG export one selected layer. JSON exports one selected layer by default, or the full descriptive layer stack with
target: 'all'. Use this for:
If your sketch depends on layer compositing and you need the exact final composition, use raster or video export rather than TXT, SVG, or JSON.
Overlay
The plugin also mounts an export overlay UI automatically. It gives you quick access to all supported formats without writing custom UI code.
Control it at runtime through t.exportOverlay:
t.exportOverlay.hide();
t.exportOverlay.show();
t.exportOverlay.toggle();The overlay supports clipboard export for:
- text
- JSON
- SVG
- raster images
For TXT, SVG, and selected-layer JSON export, the overlay shows a layer selector populated from the current layer stack. For JSON export, the target selector switches between selected layer and all layers; all layers ignores the layer selector and exports the full descriptive layer stack.
Text export
Use text export when you want plain character output.
const text = t.toString();
console.log(text);
t.saveStrings({
filename: "frame",
});You can customize whitespace handling:
const text = t.toString({
layer: t.layers.base,
preserveTrailingSpaces: true,
emptyCharacter: ".",
});Available TXTExportOptions:
filenamelayerpreserveTrailingSpacesemptyCharacter
Text export comes from the selected layer grid. It does not export the final composited canvas.
JSON export
JSON export is useful when you want structured document data for tooling, storage, or further processing.
const documentData = t.toJSON();
const jsonString = t.toJSONString();
t.saveJSON({
filename: "frame",
});By default, the exported document is a TextmodeSelectedDocumentJSON object with format: "textmode.document", formatVersion: "2.0.0", target: "selected", and:
- canvas dimensions
- grid dimensions
- selected-layer cell data
- per-cell character, foreground, background, and transform state
- optional metadata about export time and generator version
Example with explicit formatting options:
t.saveJSON({
filename: "frame",
layer: t.layers.base,
pretty: true,
colorMode: "hex",
includeMetadata: true,
});To export the base layer plus every user-created layer, use target: 'all':
const stackData = t.toJSON({ target: "all" });
t.saveJSON({
target: "all",
filename: "layer-stack",
});All-layer JSON exports use TextmodeAllDocumentJSON with format: "textmode.document", formatVersion: "2.0.0", and target: "all". They include hidden layers and preserve each layer's visible, opacity, blendMode, offsetX, offsetY, and rotationZ values. This is descriptive layer data, not a flattened composite.
Available JSONExportOptions:
filenametargetlayerprettycolorModeincludeMetadata
toJSON() returns the structured object. toJSONString() returns serialized JSON text.
Like TXT export, JSON export reads layer data rather than the final presented canvas.
SVG export
SVG export turns the selected layer into vector paths.
const svg = t.toSVG();
t.saveSVG({
filename: "poster",
});You can control whether cell background rectangles are included and whether glyphs are filled or stroked:
t.saveSVG({
filename: "outline",
layer: t.layers.base,
includeBackgroundRectangles: true,
drawMode: "stroke",
strokeWidth: 1.5,
});Available SVGExportOptions:
filenamelayerincludeBackgroundRectanglesdrawModestrokeWidth
SVG export is path-based and uses glyph outline data from the selected layer font. In practice, this is the right export path for sketches using TextmodeFont. If you need exact bitmap tileset output, use image, GIF, or video export instead.
Image export
Use saveCanvas() when you want a raster export of the final presented canvas.
await t.saveCanvas({
filename: "still",
format: "png",
});Supported image formats:
pngjpgwebp
You can also scale the export:
await t.saveCanvas({
filename: "still-2x",
format: "png",
scale: 2,
});Available ImageExportOptions:
filenameformatscale
To copy the current raster result to the clipboard instead of downloading it:
await t.copyCanvas({
format: "png",
scale: 2,
});This path captures the final browser canvas, so it is the correct choice when you want the exact visual result of a layered or filtered sketch.
GIF export
Use saveGIF() to record a sequence of future frames and encode them as an animated GIF.
await t.saveGIF({
filename: "loop",
frameCount: 180,
frameRate: 30,
});You can scale the captured frames and control loop behavior:
await t.saveGIF({
filename: "loop-2x",
frameCount: 240,
frameRate: 60,
scale: 2,
repeat: 0,
onProgress(progress) {
console.log(progress.state, progress.frameIndex, progress.totalFrames);
},
});Available GIFExportOptions:
filenameframeCountframeRatescalerepeatonProgress
GIF export works by registering a post-draw hook and capturing the next rendered frames from the canvas. It does not export frames retroactively.
Video export
Use saveVideo() to record future frames from the final presented canvas and save them as video.
MP4 is the default format:
await t.saveVideo({
filename: "capture",
frameCount: 240,
frameRate: 60,
});This saves capture.mp4. The exporter uses the browser's native WebCodecs encoder, so MP4 support depends on an available H.264 encoder in the current browser/device.
To export WebM instead, pass format: "webm":
await t.saveVideo({
filename: "capture-webm",
format: "webm",
frameCount: 240,
frameRate: 60,
bitrate: "high",
});You can control bitrate, encoder scheduling, key frames, export pixel density, hardware acceleration preference, and progress reporting:
await t.saveVideo({
filename: "poster-loop",
format: "mp4",
frameCount: 360,
frameRate: 60,
bitrate: 8_000_000,
bitrateMode: "variable",
latencyMode: "quality",
hardwareAcceleration: "no-preference",
keyFrameInterval: 2,
pixelDensity: 2,
onProgress(progress) {
console.log(progress.phase, progress.frame, progress.totalFrames);
},
});Available VideoExportOptions:
filenameformatframeCountframeRatebitratebitrateModelatencyModehardwareAccelerationkeyFrameIntervalpixelDensitysignaltransparentonProgressdebugLogging
Video export captures upcoming frames through a post-draw hook, so the animation needs to keep rendering while the export runs. Defaults are format: "mp4", frameCount: 300, frameRate: 60, bitrate: "medium", bitrateMode: "variable", latencyMode: "quality", hardwareAcceleration: "no-preference", keyFrameInterval: 2, and pixelDensity: 1.
Use transparent: true only with WebM. MP4/H.264 does not provide portable alpha support, so transparent MP4 exports are rejected.
Related APIs
textmode.export.jsExportPluginTextmodeExportAPIExportOverlayControllerLayerExportOptionsImageExportOptionsTXTExportOptionsJSONExportOptionsJSONExportTargetTextmodeSelectedDocumentJSONTextmodeAllDocumentJSONTextmodeDocumentJSONSVGExportOptionsGIFExportOptionsGIFExportProgressVideoExportOptionsVideoExportFormatVideoBitratePresetVideoBitrateModeVideoLatencyModeVideoHardwareAccelerationVideoExportProgress