How could we load a local image on a canvas?

时间秒杀一切 提交于 2021-01-28 08:01:04

问题


Hello and thank you for your time reading this question:

I was trying to do an excercise to learn React, and because of I recently did a code in JS to load a file from local, an image, into a canvas, and then when user clicks on it circles are drawn; I tryed to do the same in React.

Here is the JS excercise: https://codereview.stackexchange.com/questions/186526/read-an-image-file-into-a-canvas-and-display-click-coordinates

I have created a canvas in Canvas' component's render(), and after that I call make_base function which gets the context and loads the image into it.

Here is the code:

import React from 'react';


class Canvas extends React.Component {
    //A canvas to display images with a title


    constructor(props) {
        super(props);

        this.state = {x: 0, y: 0, inside: ''};

        this.handleClick = this.handleClick.bind(this);
        this.make_base = this.make_base.bind(this);
    }

    _onMouseMove(e) {
        this.setState({x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY});
    }

    componentDidMount() {
        document.addEventListener('click', this.handleClick);
    }

    componentWillUnmount() {
        document.removeEventListener('click', this.handleClick);
    }

    handleClick(e) {
        e.stopPropagation();
        console.log('INSIDE');
        this.setState({inside: 'inside'});
    }

    make_base(image) {
        const context = this.refs.canvas.getContext('2d');
        let base_image = new Image();
        base_image.src = image;
        base_image.onload = function () {
            context.drawImage(base_image, 0, 0);
        }
    }


    render() {

        const {x, y, inside} = this.state;

        return (
            <div className="previewComponent">
                <div className="imgPreview">
                    {this.props.title}

                    <canvas ref="canvas" width={300} height={300}></canvas>
                    {this.make_base(this.props.image)}

                    <img src={this.props.image} alt="" onMouseMove={this._onMouseMove.bind(this)}
                         onClick={this.handleClick.bind(this)}/>

                    <h1>Mouse coordinates: {x} {y}</h1>
                    <h2>Inside?: {inside}</h2>
                </div>
            </div>
        )
    }
}

export {Canvas};

The console tell us:

TypeError: Cannot read property 'getContext' of undefined
Canvas.make_base
C:/Users/YonePC/WebstormProjects/prototipo/src/components/animals/Canvas.js:36
  33 |    }
  34 | 
  35 |    make_base(image) {
> 36 |        const context = this.refs.canvas.getContext('2d');
  37 |        let base_image = new Image();
  38 |        base_image.src = image;
  39 |        base_image.onload = function () {
View compiled
Canvas.render
C:/Users/YonePC/WebstormProjects/prototipo/src/components/animals/Canvas.js:55
  52 |                    {this.props.title}
  53 | 
  54 |                    <canvas ref="canvas" width={300} height={300}></canvas>
> 55 |                    {this.make_base(this.props.image)}
  56 | 
  57 |                    <img src={this.props.image} alt="" onMouseMove={this._onMouseMove.bind(this)}
  58 |                         onClick={this.handleClick.bind(this)}/>

I do not understand why getContext() gets undefined if it is supposed that we have already created the canvas in render() method.

In addition I have studied:

How to access canvas context in React

https://blog.lavrton.com/using-react-with-html5-canvas-871d07d8d753

How to add image to canvas

EDIT:

I have tried the proposed answer and the console stills telling us:

TypeError: Cannot read property 'getContext' of undefined
Canvas.make_base
C:/Users/YonePC/WebstormProjects/prototipo/src/components/animals/Canvas.js:36
  33 |    }
  34 | 
  35 |    make_base(image) {
> 36 |        const context = this.canvas.getContext('2d');
  37 |        let base_image = new Image();
  38 |        base_image.src = image;
  39 |        base_image.onload = function () {
View compiled
Canvas.render
C:/Users/YonePC/WebstormProjects/prototipo/src/components/animals/Canvas.js:55
  52 |                    {this.props.title}
  53 | 
  54 |                    <canvas ref={(canvas) => this.canvas = canvas} width={300} height={300}></canvas>
> 55 |                    {this.make_base(this.props.image)}
  56 | 
  57 |                    <img src={this.props.image} alt="" onMouseMove={this._onMouseMove.bind(this)}
  58 |                         onClick={this.handleClick.bind(this)}/>
View compiled

If we comment the lines where context is being written we see the two empty canvas:

Maybe the canvas should not be created in render method because it is still being not accesible by outside methods?

EDIT2: The given answer works well:

However we would like to draw on mouse click where the cursor is instead of a button, so that is the question, how could we get the coordinates and associate them to draw in the canvas?

Thank you for your help.


回答1:


You are using refs wrong.

You have to set the ref to a class variable as in this.canvas

class App extends React.Component {
  constructor(props) {
    super(props);
    this.makeBase = this.makeBase.bind(this);
    this.recordMouse = this.recordMouse.bind(this);
  }
  recordMouse(event) {
    const ctx = this.canvas.getContext('2d');
    ctx.beginPath();
    ctx.fillRect(event.nativeEvent.offsetX,event.nativeEvent.offsetY,3,3);
    ctx.stroke();
  }
  makeBase() {
    const ctx = this.canvas.getContext('2d');
    ctx.beginPath();
    ctx.arc(95,50,40,0,2*Math.PI);
    ctx.stroke();
  }
  render() {
    return (
      <div>
        <canvas ref={(canvas)=>this.canvas=canvas} width="200" height="100" onMouseMove={this.recordMouse} />
        <button onClick={this.makeBase}>Make Base</button>
      </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

https://reactjs.org/docs/refs-and-the-dom.html



来源:https://stackoverflow.com/questions/49197893/how-could-we-load-a-local-image-on-a-canvas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!