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.
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:
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.