Reputation: 98
I am facing a problem. I am drawing rectangles on click and drag. I am storing these rectangles in array. Whenever I push newly made Rectangle in the array the old stored rectangles gets updated with the last pushed rectangle. For example - suppose my array(named data) contains Rectangles as - [Rectangle 1, Rectangle 2]. Now if I add 3rd rectangle the updated array is like - [rectangle 3, rectangle 3, rectangle 3]. please tell me where i am wrong and help me resolve this problem.
//I am drawing rectangles in handleMouseMove function and updating the array in handleMouseUp. I am using var data = [] to store array
import React from 'react';
var rect = {};
var shape = {};
var data = [];
export default class MyCanvas extends React.Component {
constructor(props) {
super (props);
this.state = {
imageLink : 'some link',
shapes : [],
isDown : false,
};
this.handleClick = this.handleClick.bind (this);
this.hanldeMouseMove = this.hanldeMouseMove.bind (this);
this.handleMouseDown = this.handleMouseDown.bind (this);
this.handleMouseUp = this.handleMouseUp.bind (this);
}
componentDidMount() {
const canvas = this.refs.canvas;
const ctx = canvas.getContext ("2d");
const img = this.refs.image;
canvas.height = img.height;
canvas.width = img.width;
img.onload = () => {
ctx.drawImage (img, 0, 0);
}
var rectX = canvas.offsetLeft;
var rectY = canvas.offsetTop;
canvas.addEventListener ('mousemove', (e) => {this.hanldeMouseMove (e, canvas, img)}, false);
canvas.addEventListener ('mousedown', (e) => {this.handleMouseDown (e)}, false);
canvas.addEventListener ('mouseup', () => {this.handleMouseUp(canvas)}, false);
}
hanldeMouseMove(e, canvas, img) {
if (this.state.isDown) {
rect.w = (e.pageX - canvas.offsetLeft) - rect.startX;
rect.h = (e.pageY - canvas.offsetTop) - rect.startY ;
const ctx = canvas.getContext ("2d");
// Rectangles are drawn here
ctx.clearRect(rect.startX, rect.startY, rect.w, rect.h);
ctx.drawImage(img, 0, 0);
ctx.strokeRect (rect.startX, rect.startY, rect.w, rect.h);
shape = rect;
}
}
handleMouseDown(e) {
rect.startX = e.offsetX;
rect.startY = e.offsetY;
this.setState ({isDown : true});
}
// updating the array here
handleMouseUp(canvas) {
this.setState ({isDown : false});
data.push(shape);
console.log(data);
}
render() {
return (
<div className="container">
<canvas ref = "canvas" />
<img ref = "image" alt = "Link is Broken" src = {this.state.imageLink} className = "d-none" />
</ div>
);
}
}
Upvotes: 0
Views: 828
Reputation: 121
Data object should be in your state and you have to keep in mind that React works with immutable objects.
handleMouseUp(canvas) {
var newDataArray = this.state.data.slice();
newDataArray.push(shape);
this.setState({data:newDataArray})
}
this.state.data.slice() creates a shallow copy of the array, making it immutable
With ES6, you can also use the better way, which is
handleMouseUp(canvas) {
this.setState(previousState => ({
data: [...previousState.data, shape]
}));
}
Upvotes: 0
Reputation: 15292
There is single referance for rect and its getting copied and updated everytime in the array.So,all element in the array show same element.
instead of
shape = rect;
do liek this,
shape = Object.assign({},rect);
Upvotes: 2