This project is no longer maintained. Issues or PR may not be resolved. Use carefully.
React/EaselJS bindings with React Reconciler
easeljs-react is a JavaScript library for drawing complex canvas graphics using React. It provides declarative and reactive bindings to the EaselJS Framework. This project is partially forked from react-konva project and re-designed for EaselJS.
npm install easeljs-react
or
yarn add easeljs-react
Currently easeljs-react depends on react-reconciler that is used in React Fiber. So dependencies below are required.
- react ^16.8.2
- react-dom ^16.8.2
- react-reconciler ^0.18.0
import React from "react";
import {
StageComponent, BitmapComponent, ContainerComponent, ShapeComponent, TextComponent
} from "easeljs-react";
import Graphics = createjs.Graphics;
import Stage = createjs.Stage;
import Container = createjs.Container;
class CanvasComponent extends React.Component {
stage;
textContainer;
constructor(props) {
super(props);
state = {
image: null,
bitmapX: 100,
bitmapY: 100,
graphics: new Graphics(),
text: "hello world!"
};
// Note: make reference setters and event handlers idendified.
// avoid passing anonymous function props to Component.
this.onMouseDown = ev => this.handleMouseDown(ev);
this.onPressUp = ev => this.handlePressUp(ev);
this.setStageRef = n => this.stage = n.stage;
this.setTextContainerRef = n => this.textContainer = n;
}
handleMouseDown(ev) {
console.log(`down: ${ev.stageX},${ev.stageY}`);
}
handlePressUp(ev) {
console.log(`up: ${ev.stageX},${ev.stageY}`);
}
componentDidMount() {
const image = new Image();
image.src = "/img/logo.png";
image.onload = () => {
this.setState({image});
}
}
render() {
return (
<StageComponent
autoClear={true}
width={1024} height={768}
ref={this.setStageRef}>
<BitmapComponent image={this.state.image}
x={this.state.bitmapX}
y={this.state.bitmapY}
onMouseDown={this.onMouseDown}
onPressUp={this.onPressUp} />
<ShapeComponent graphics={this.state.graphics}
bounds={new Rectangle(0,0,100,100)}/>
<ContainerComponent
x={100} y={200} ref={this.setTextContainerRef} >
<TextComponent
font={"20pt Arial"}
color={"white"}
text={this.state.text}/>
</ContainerComponent>
</StageComponent>
)
}
}yarn install && yarn start && open http://localhost:5000
You can see EaselJS component tree in your React Developer Tools
EaselJS Classes that inherits from DisplayObject are virtually bound on React Components. Naming conventions are as follows:
- Stage -> StageComponent
- Container -> ContainerComponent
- Shape -> ShapeComponent
- ...
When using components in your jsx or tsx source code, you must import it.
import {StageComponent} from "easeljs-react"In module resolution phase, bound components and easeljs's objects (xxxComponent and xxx) are recognized as different. But actually all components except StageComponent are identical to easeljs object.
So you can use bound components as easeljs object:
class CanvasComponent extends React.Component {
stage;
shape;
setStageRef = n => this.stage = n.stage;
setShapeRef = n => this.shape = n;
render() {
<StageComponent
width={640} height={480} ref={this.setStageRef}>
<ShapeComponent ref={this.setShapeRef} />
</StageComponent>
}
}Unfortunatelly, direct reference between bound components and easeljs object doesn't work in TypeScript. This comes from type definition for React.Comopnent<P,S>. ref property for React.Component is defined as Component<any>|Element so that code below cannnot be resolved.
So just call getPublicInstance() method for getting reference to easeljs object:
class CanvasComponent extends React.Component {
stage: Stage;
shape: Shape;
setStageRef = n => this.stage = n.stage;
setShapeRef = n => this.shape = n.getPublicInstance();
render() {
<StageComponent
width={640} height={480} ref={this.setStageRef}>
<ShapeComponent ref={this.setShapeRef} />
</StageComponent>
}
}PR or issues may not be resolved.
We are using TypeScript as primary development language. codes under src directory are active source code and lib are generated codes for publishing, keep it untouch.
