在ReactJs中使用鼠标事件在画布上绘制直线

时间:2018-09-04 15:02:47

标签: reactjs

我想画一条直线。当我在画布上单击并移动光标时,我实现了绘制点的功能,并且当我释放鼠标按钮时它也停止了绘制。

但是我需要画直线。我在stackoverflow上找到了解决方案,但是它们在Jquery和Javascript中。我不想使用JQuery。

一些解决方案建议为存储线创建2个画布1,为画布上的绘制线创建1。

但是我知道可以通过单个画布来实现,而且我非常接近实现这一目标。

以下是我的代码。

export default class CanvasComponent extends React.Component{
constructor(props) {
    super(props);
    this.state={
        isDown: false
    }
    this.handleMouseDown = this.handleMouseDown.bind(this);
    this.handleMouseMove = this.handleMouseMove.bind(this);
    this.handleMouseUp = this.handleMouseUp.bind(this);
}
render() {
    return (
        <div>

            <canvas id="canvas" ref="canvas"
                    width={640}
                    height={425}
                    onMouseDown={
                        e => {
                            let nativeEvent = e.nativeEvent;
                            this.handleMouseDown(nativeEvent);
                        }}
                    onMouseMove={
                        e => {
                            let nativeEvent = e.nativeEvent;
                            this.handleMouseMove(nativeEvent);
                        }}



                    onMouseUp={
                        e => {
                            let nativeEvent = e.nativeEvent;
                            this.handleMouseUp(nativeEvent);
                        }}
            />
        </div>


    );
}

handleMouseDown(event){
    console.log(event);

    this.setState({
        isDown: true
    },()=>{

        const canvas = ReactDOM.findDOMNode(this.refs.canvas);

        var x = event.offsetX;
        var y = event.offsetY;
        var ctx = canvas.getContext("2d");
        console.log(x,y);
        ctx.moveTo(x,y);
        ctx.lineTo(x+1,y+1);
        ctx.stroke();
    })
}
handleMouseMove(event){
    if(this.state.isDown){
        const canvas = ReactDOM.findDOMNode(this.refs.canvas);
        var x = event.offsetX;
        var y = event.offsetY;
        var ctx = canvas.getContext("2d");

        ctx.moveTo(x,y);
        ctx.lineTo(x+1,y+1);
        ctx.stroke();
        ctx.closePath();
    }

}
handleMouseUp(){
    this.setState({
        isDown: false
    })
}
componentDidMount() {
    const canvas = ReactDOM.findDOMNode(this.refs.canvas);
    const ctx = canvas.getContext("2d");
    ctx.fillStyle = 'rgb(200,255,255)';
    ctx.fillRect(0, 0, 640, 425);
}

}

2 个答案:

答案 0 :(得分:0)

将第一个坐标保留为全局变量或类变量,因此可以在第二次单击时画线。

光标移动时是否需要显示临时行?然后添加第二层,您在每次鼠标移动时在其上绘制一条具有相同坐标的线(重绘前清除该层!)

答案 1 :(得分:0)

您需要存储上一个点的状态。在handleMouseUp(即OnMouseUp)事件中,您需要绘制前一点与当前点之间的线。这是更改后的代码:

    import React, {Component} from 'react';
import ReactDOM from 'react-dom';

export default class canvas extends React.Component{
    constructor(props) {
        super(props);
        //added state 
        this.state={
            isDown: false,
            previousPointX:'',
            previousPointY:''
        }
        this.handleMouseDown = this.handleMouseDown.bind(this);
        this.handleMouseMove = this.handleMouseMove.bind(this);
        this.handleMouseUp = this.handleMouseUp.bind(this);
    }
    render() {
        return (
            <div>    
                <canvas id="canvas" ref="canvas"
                        width={640}
                        height={425}
                        onMouseDown={
                            e => {
                                let nativeEvent = e.nativeEvent;
                                this.handleMouseDown(nativeEvent);
                            }}
                        onMouseMove={
                            e => {
                                let nativeEvent = e.nativeEvent;
                                this.handleMouseMove(nativeEvent);
                            }}    
                        onMouseUp={
                            e => {
                                let nativeEvent = e.nativeEvent;
                                this.handleMouseUp(nativeEvent);
                            }}
                />
            </div>    
        );
    }

    handleMouseDown(event){ //added code here
        console.log(event);    
        this.setState({
            isDown: true,
            previousPointX:event.offsetX,
            previousPointY:event.offsetY
        },()=>{    
            const canvas = ReactDOM.findDOMNode(this.refs.canvas);    
            var x = event.offsetX;
            var y = event.offsetY;
            var ctx = canvas.getContext("2d");
            console.log(x,y);
            ctx.moveTo(x,y);
            ctx.lineTo(x+1,y+1);
            ctx.stroke();
        })
    }
    handleMouseMove(event){

    }
    handleMouseUp(event){
        this.setState({
            isDown: false
        });
        //if(this.state.isDown){
            const canvas = ReactDOM.findDOMNode(this.refs.canvas);
            var x = event.offsetX;
            var y = event.offsetY;
            var ctx = canvas.getContext("2d");

            ctx.moveTo(this.state.previousPointX,this.state.previousPointY);
            ctx.lineTo(x,y);
            ctx.stroke();
            ctx.closePath();
        //}
    }
    componentDidMount() {
        const canvas = ReactDOM.findDOMNode(this.refs.canvas);
        const ctx = canvas.getContext("2d");
        ctx.fillStyle = 'rgb(200,255,255)';
        ctx.fillRect(0, 0, 640, 425);
    }
}