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