react-canvas — React.js rendering to canvas

React Canvas — render React components to canvas

React.js is known for its virtual DOM, but as Facebook’s software engineer Bill Fisher said, the virtual DOM is only an implementation detail.

Last week we saw Facebook releasing React Native, which renders native OS components instead of DOM elements. Today Flipboard released React Canvas, a high performance React renderer for <canvas>.

Why render to canvas?

Flipboard mentions slow DOM on mobile devices as a motivation for this project:

Having a long history of building interfaces geared toward mobile devices, we found that the reason mobile web apps feel slow when compared to native apps is the DOM. CSS animations and transitions are the fastest path to smooth animations on the web, but they have several limitations. React Canvas leverages the fact that most modern mobile browsers now have hardware accelerated canvas.

At first it seems strange to render to <canvas>, however it has been done before, for example, in Mozilla’s Bespin/Skywriter text editor, although for different reasons. React Canvas does it to improve performance for some applications.

What react-canvas provides

Just like React Native, react-canvas replaces primitive DOM elements, which you normally use with React.js, with its own components:

  • Text — for text, including multiline truncation.
  • Image — for images, with ability to hide them until fully loaded.
  • ListView — for rendering lists of elements.
  • Group — for grouping child components.
  • Layer — a base component, which can be styled.
  • Surface — a top-level component on which you place other components.

React Canvas implements the same event model as React’s DOM components, however some of events are not available yet.

How to use React Canvas

Here’s an example from README. It renders text below image:

var React = require('react');
var ReactCanvas = require('react-canvas');

var Surface = ReactCanvas.Surface;
var Image = ReactCanvas.Image;
var Text = ReactCanvas.Text;

var MyComponent = React.createClass({

  render: function () {
    var surfaceWidth = window.innerWidth;
    var surfaceHeight = window.innerHeight;
    var imageStyle = this.getImageStyle();
    var textStyle = this.getTextStyle();

    return (
      <Surface width={surfaceWidth} height={surfaceHeight} left={0} top={0}>
        <Image style={imageStyle} src='...' />
        <Text style={textStyle}>
          Here is some text below an image.
        </Text>
      </Surface>
    );
  },

  getImageHeight: function () {
    return Math.round(window.innerHeight / 2);
  },

  getImageStyle: function () {
    return {
      top: 0,
      left: 0,
      width: window.innerWidth,
      height: this.getImageHeight()
    };
  },

  getTextStyle: function () {
    return {
      top: this.getImageHeight() + 10,
      left: 0,
      width: window.innerWidth,
      height: 20,
      lineHeight: 20,
      fontSize: 12
    };
  }

});

Summary

React Canvas is an interesting new project, which may be useful for mobile development. It also shows the power of React.js, and that virtual DOM is really just an implementation detail of it. I’ll be following the development of react-canvas and share with your new information on its progress.

Read Flipboard’s post 60fps on the mobile web for more information.

Source code and license

GitHub: https://github.com/Flipboard/react-canvas
License: BSD-like

Learn React

Developing a React Edge: The JavaScript Library for User Interfaces

2 thoughts on “React Canvas — render React components to canvas”

  1. Using the window global in the react render method results in a ‘window is not defined’ error and I can’t run anything. Any thoughts on what might be happening?

Leave a Reply

Your email address will not be published. Required fields are marked *