React.js + <canvas>

react+canvas

我們有React,它可以幫助我們處理大量的可變DOM。

但想描述一種使用React的方法,它可以幫助您處理“<canvas>元素?是的,這聽起來很奇怪。但它運作得很好。

動機

使用了很多<canvas>元素。我製作了幾個使用<canvas>作為主要視圖組件的複雜應用程序。canvas對於復雜的應用程序製作上來說非常困難。所以開始使用canvas框架Konva 2d。

Konva幫助了很多,但現在還不如想要的那麼好。此外,開始在應用程序中使用React,並且非常喜歡使用它。如何使用React在畫布上繪製圖形。

React中的<canvas>

非常簡單的在React component中訪問<canvas>並繪製任何圖形:

class CanvasComponent extends React.Component {
    componentDidMount() {
        this.updateCanvas();
    }
    updateCanvas() {
        const ctx = this.refs.canvas.getContext('2d');
        ctx.fillRect(0,0, 100, 100);
    }
    render() {
        return (
            <canvas ref="canvas" width={300} height={300}/>
        );
    }   
}
ReactDOM.render(<CanvasComponent/>, document.getElementById('container'));

Demo: http://jsbin.com/xituko/edit?js,output

它適用於簡單的例子。但對於復雜的應用程序,這種方法並不好,因為我們無法使用可重用的React component的全部功能。

// “reusable component”
function rect(props) {
    const {ctx, x, y, width, height} = props;
    ctx.fillRect(x, y, width, height);
}
class CanvasComponent extends React.Component {
    componentDidMount() {
        this.updateCanvas();
    }
    componentDidUpdate() {
        this.updateCanvas();
    }
    updateCanvas() {
        const ctx = this.refs.canvas.getContext('2d');
        ctx.clearRect(0,0, 300, 300);
        // draw children “components”
        rect({ctx, x: 10, y: 10, width: 50, height: 50});
        rect({ctx, x: 110, y: 110, width: 50, height: 50});
    }
    render() {
        return (
            <canvas ref="canvas" width={300} height={300}/>
        );
    }
}
ReactDOM.render(<CanvasComponent/>, document.getElementById('container')); 

React的生命週期方法(如shouldComponentUpdate等)和“渲染函數內部的所有表示”呢?

履行

React方法來構建應用程序,綁定Konva對象繪製不同圖形的畫布到舞台,並將其用於我的React應用程序。

npm install react konva react-konva --save

然後

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'));

Demo: http://jsbin.com/camene/8/edit?html,js,output

比較

react-konva vs react-canvas

react-canvas是一個完全不同的反應插件。它允許您以非常高效的方式在畫布元素上繪製DOM類對象(圖像,文本)。它不是關於繪製圖形,而是react-konva正好用於從React繪製<canvas>元素上的複雜圖形。

react-konva vs react-art

react-art允許您在頁面上繪製圖形。它也支持SVG輸出。但它不支持形狀事件。

特徵

Konva因此它具有所有核心圖形支持:圓形,矩形,橢圓,直線,雪碧,圖像,文字,TextPath,星型,環,弧,標籤,SVG路徑,找到RegularPolygon,箭,你可以創建您自己的自定義形狀。此外,您還可以使用內置拖放支持,補間,動畫,過濾器,緩存系統,桌面和移動事件(鼠標,點擊,dblclick,dragstart,dragmove,dragend,tap,dbltap等)等等。

自定義形狀範例

// custom shape example
function MyShape() {
return (
    <Shape fill=”#00D2FF” draggable
        sceneFunc={function (ctx) {
            ctx.beginPath();
            ctx.moveTo(20, 50);
            ctx.lineTo(220, 80);
            ctx.quadraticCurveTo(150, 100, 260, 170);
            ctx.closePath();
            // Konva specific method
            ctx.fillStrokeShape(this);
        }}
    />
);
}

Demo: http://jsbin.com/gakadi/4/edit?html,js,output

事件範例

class MyCircle extends React.Component {
    constructor(…args) {
        super(…args);
        this.state = { isMouseInside: false};
        this.handleMouseEnter = this.handleMouseEnter.bind(this);
        this.handleMouseLeave = this.handleMouseLeave.bind(this);
    }
    handleMouseEnter() {
        this.setState({ isMouseInside: true});
    }
    handleMouseLeave() {
        this.setState({ isMouseInside: false});
    }
    render() {
        return (
            <Circle
                x={100} y={60} radius={50}
                fill=”yellow” stroke=”black”
                strokeWidth={this.state.isMouseInside ? 5 : 1}
                onMouseEnter={this.handleMouseEnter}
                onMouseLeave={this.handleMouseLeave}
            />
        );
    }
}

Demo: http://jsbin.com/tekopu/3/edit?js,output

翻譯來源:Using React with canvas element

您也可能喜歡這些文章

Copyright © 2018 ucamc