Custom renderer

Draw shapes with your own 2d canvas renderer instead of tldraw's DOM rendering.

import { TLComponents, Tldraw } from 'tldraw'
import 'tldraw/tldraw.css'
import { CustomRenderer } from './CustomRenderer'
import './custom-renderer.css'

// There's a guide at the bottom of this file!

// [1]
const components: TLComponents = {
	Background: CustomRenderer,
}

export default function CustomRendererExample() {
	return (
		// [2]
		<div className="tldraw__editor custom-renderer">
			<Tldraw persistenceKey="custom-renderer-example" components={components} />
		</div>
	)
}

/*
The shapes are drawn to a 2d canvas from the editor's shape data instead of being rendered by
React.

[1]
We replace the `Background` component with our custom renderer (see `CustomRenderer.tsx`). It
reads the rendering shapes from the editor on every animation frame and draws them itself. Even
though the DOM shapes are hidden, tldraw still does the work of figuring out which shapes to
render. In a real app you might set the `Canvas` component to null and render everything yourself.

[2]
The `.custom-renderer` class hides tldraw's regular shapes layer via CSS (see
`custom-renderer.css`) so only our canvas rendering is visible. Selection, handles, and the
rest of the UI still work as normal.
*/

The Background component is replaced with a component that reads editor.getRenderingShapes() on every animation frame and draws draw and geo shapes to a 2d canvas, using getColorValue to look up theme colors. tldraw's regular shapes layer is hidden with CSS, while selection, handles, and the rest of the UI keep working.

This is a sketch of the approach rather than a complete renderer: it handles draw and geo shapes and draws a bounding box for everything else. Try drawing a few shapes and moving them around.

Is this page helpful?
Prev
Custom translations and overrides
Next
Inset editor