I am developing an app where user will get to choose image from the list of images that are provided. When user clicks on the image from the list, the selected image should be shown on canvas as a background. I am developing this using reactjs, redux and fabricjs.
i dont get selected image when i do this.props.getSelectedImage.image.image so i can update in setCanvasBackground.
image-list.js
class Images extends React.Component {
renderImages() {
const { images, selectImage } = this.props;
return _.map(images, (image, key) =>
<li key={key}>
<img
src={image.image}
alt={image.id}
className="responsive-img default-images"
width="400px"
onClick={() => selectImage(image)}
/>
</li>
);
}
render() {
return (
<ul className="image-list">
{this.renderImages()}
</ul>
);
}
}
const mapStateToProps = (state) => {
return {
images: state.images
}
};
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({ selectImage: selectImage }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(Images);
actions.js
export function selectImage(image) {
return {
type: 'SELECT_IMAGE',
payload: image
}
}
reducers.js
const initialState = {
selectedImage: require('./img/image1.jpg')
};
export function getSelectedImage(state = initialState, action) {
switch (action.type) {
case 'SELECT_IMAGE':
return Object.assign({}, state, { selectedImage: action.payload.image })
default:
return state;
}
}
image-board.js
class ImageBoard extends React.Component {
constructor() {
super();
this.state = {
canvas: undefined,
selected: undefined
};
}
componentDidMount() {
const canvas = new fabric.Canvas('canvas');
this.setCanvasBackground(this.props.getSelectedImage.selectedImage, canvas);
}
setCanvasBackground(image, canvas) {
canvas.setBackgroundImage(image, function(e) {
let iw = canvas.backgroundImage.width,
ih = canvas.backgroundImage.height,
cw = canvas.getWidth(),
ch = canvas.getHeight();
let iar = iw/ih,
car = cw/ch;
let nw = cw,
nh = ch;
if (iar > car){
nh = ch;
nw = nh * iar;
}
else if (iar < car){
nw = cw;
nh = cw/iar;
}
canvas.backgroundImage.width = nw;
canvas.backgroundImage.height = nh;
canvas.renderAll();
}.bind(this));
}
render() {
return(
<div className="image-board">
<canvas
id="canvas"
className="z-depth-1"
width={600}
height={400}
/>
</div>
);
}
}
const mapStateToProps = (state) => {
console.log('state', state);
return {
images: state.images,
getSelectedImage: state.getSelectedImage
}
};
export default connect(mapStateToProps)(ImageBoard);
Right now i could show the default image but could not change the background image in canvas when image from list is clicked.However when i put console.log('image selected', this.props.getSelectedImage.image.image);
inside render function i get the selected image but could not set this on setBackgroundImage so i can show the selected image on canvas.
How can i do so?
react v15.4.2 has been used
UPDATE
componentDidUpdate() {
console.log('componentDidUpdate');
const canvas = new fabric.Canvas('canvas');
this.setCanvasBackground(this.props.getSelectedImage.selectedImage, canvas);
}
if i use componentDidUpdate lifecycle method, it works but i get the following result. So many canvas are re-created and i know its because i have created an object of canvas in componentDidUpdate to update the canvas. How can i do this in clear way?