What is react-konva?
react-konva is a React wrapper for the Konva framework, which is a 2D canvas library for creating complex graphics on the web. It allows developers to use React components to draw shapes, images, and text on the canvas, making it easier to integrate with React applications.
What are react-konva's main functionalities?
Drawing Shapes
This feature allows you to draw basic shapes like rectangles and circles on the canvas. The code sample demonstrates how to create a red rectangle and a green circle using React components.
```jsx
import React from 'react';
import { Stage, Layer, Rect, Circle } from 'react-konva';
const DrawingShapes = () => (
<Stage width={window.innerWidth} height={window.innerHeight}>
<Layer>
<Rect x={20} y={20} width={100} height={100} fill='red' />
<Circle x={200} y={200} radius={50} fill='green' />
</Layer>
</Stage>
);
export default DrawingShapes;
```
Handling Events
This feature allows you to handle user interactions like clicks and drags. The code sample shows how to display an alert when a blue rectangle is clicked.
```jsx
import React from 'react';
import { Stage, Layer, Rect } from 'react-konva';
const HandlingEvents = () => {
const handleClick = () => {
alert('Rectangle clicked!');
};
return (
<Stage width={window.innerWidth} height={window.innerHeight}>
<Layer>
<Rect x={20} y={20} width={100} height={100} fill='blue' onClick={handleClick} />
</Layer>
</Stage>
);
};
export default HandlingEvents;
```
Animating Shapes
This feature allows you to animate shapes on the canvas. The code sample demonstrates how to animate a purple rectangle moving horizontally across the screen.
```jsx
import React, { useRef, useEffect } from 'react';
import { Stage, Layer, Rect } from 'react-konva';
const AnimatingShapes = () => {
const rectRef = useRef(null);
useEffect(() => {
const anim = new Konva.Animation((frame) => {
const rect = rectRef.current;
rect.x((rect.x() + frame.timeDiff * 0.1) % window.innerWidth);
}, rectRef.current.getLayer());
anim.start();
return () => anim.stop();
}, []);
return (
<Stage width={window.innerWidth} height={window.innerHeight}>
<Layer>
<Rect ref={rectRef} x={20} y={20} width={100} height={100} fill='purple' />
</Layer>
</Stage>
);
};
export default AnimatingShapes;
```
Other packages similar to react-konva
react-three-fiber
react-three-fiber is a React renderer for Three.js, a popular 3D graphics library. While react-konva focuses on 2D canvas graphics, react-three-fiber is used for creating 3D scenes and objects. It provides a similar React-based approach to managing graphics but in a 3D context.
react-canvas
react-canvas is another library for drawing graphics using React components, but it is more focused on performance and rendering large lists of items efficiently. It is less feature-rich in terms of drawing complex shapes and animations compared to react-konva.
react-svg
react-svg is a library for integrating SVG graphics into React applications. While it also deals with vector graphics, it uses SVG instead of the HTML5 canvas element. It is more suitable for static or less complex graphics compared to the dynamic and interactive capabilities of react-konva.
React Konva
React Konva is a JavaScript library for drawing complex canvas graphics using React.
It provides declarative and reactive bindings to the Konva Framework.
An attempt to make React work with the HTML5 canvas library. The goal is to have
similar declarative markup as normal React and to have similar data-flow model.
Currently you can use all Konva
components as React components and all Konva
events are supported on them in same way as normal browser events are supported.
You can even inspect the components in React dev tools.
Installation
npm instal react konva react-konva --save
Example
import React from 'react';
import ReactDOM from 'react-dom';
import {Layer, Rect, Stage, Group} from 'react-konva';
class MyRect extends React.Component {
constructor(...args) {
super(...args);
this.state = {
color: 'green'
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({
color: Konva.Util.getRandomColor()
});
}
render() {
return (
<Rect
x={10} y={10} width={50} height={50}
fill={this.state.color}
shadowBlur={10}
onClick={this.handleClick}
/>
);
}
}
function App() {
return (
<Stage width={700} height={700}>
<Layer>
<MyRect/>
</Layer>
</Stage>
);
}
ReactDOM.render(<App/>, document.getElementById('container'));
All react-konva
components correspond to Konva
components of the same
name. All the parameters available for Konva
objects are valid props for
corresponding react-konva
components, unless otherwise noted.
Core shapes are: Rect, Circle, Ellipse, Line, Image, Text, TextPath, Star, Label, SVG Path, RegularPolygon.
Also you can create custom shape.
To get more info about Konva
you can read Konva Overview.
Comparisons
react-konva vs react-canvas
react-canvas is a completely different react plugin. It allows you to draw DOM-like objects (images, texts) on canvas element in very performant way. It is NOT about drawing graphics, but react-konva is exactly for drawing complex graphics on <canvas>
element from React.
react-konva vs react-art
react-art allows you to draw graphics on a page. It also supports SVG for output. But it has no support of events of shapes.
react-konva vs vanilla canvas
Performance is one of the main buzz word in react hype.
I made this plugin not for performance reasons. Using vanilla should be more performant because while using react-konva you have Konva framework on top of and React on top of Konva. But I made this plugin to fight with application complexity. Konva helps here a lot (especially when you need events for objects on canvas, like “click” on shape, it is really hard to do with vanilla canvas). But React helps here much more as it provides very good structure for your codebase and data flow.
Documentation and Examples
Note: you can find a lot of demos and examples of using Konva there: http://konvajs.github.io/
Getting reference to Konva objects
To get reference of Konva
instance of a node you can use ref
property.
class MyShape extends React.Component {
componentDidMount() {
console.log(this.refs.circle);
}
render() {
return (
<Circle ref="circle" radius={50} fill="black"/>
);
}
}
That will work for all nodes except Stage
. To get Stage
instance you have to use:
class App extends React.Component {
componentDidMount() {
console.log(this.refs.stage);
console.log(this.refs.stage.getStage());
}
render() {
return (
<Stage ref="stage" width="300" height="300"/>
);
}
}
Animations
For complex animation I recommend to use React methods. Somethings like:
But for simple cases you can use Konva
methods:
http://jsbin.com/puroji/2/edit?js,output
class MyRect extends React.Component {
changeSize() {
const rect = this.refs.rect;
rect.to({
scaleX: Math.random() + 0.8,
scaleY: Math.random() + 0.8,
duration: 0.2
});
}
render() {
return (
<Group>
<Rect
ref="rect"
width="50"
height="50"
fill="green"
draggable="true"
onDragEnd={this.changeSize.bind(this)}
onDragStart={this.changeSize.bind(this)}
/>
</Group>
);
}
}