问题描述
我正在开发一个应用程序,用户可以从提供的图像列表中选择图像。当用户单击列表中的图像时,所选图像应作为背景显示在画布上。我正在使用reactjs,redux和fabricjs开发它。
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.
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);
现在我可以显示默认图像,但是当列表中的图像时不能更改画布中的背景图像但是,当我将 console.log('image selected',this.props.getSelectedImage.image.image);
放入内部渲染函数时,我得到了所选图像,但可以没有在setBackgroundImage上设置此项,这样我就可以在画布上显示所选的图像。
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.
我该怎么做?
已使用v15.4.2版本
react v15.4.2 has been used
更新
componentDidUpdate() {
console.log('componentDidUpdate');
const canvas = new fabric.Canvas('canvas');
this.setCanvasBackground(this.props.getSelectedImage.selectedImage, canvas);
}
如果我使用componentDidUpdate生命周期方法,它可以工作,但我得到以下结果。如此多的画布被重新创建,我知道它是因为我已经在componentDidUpdate中创建了一个画布对象来更新画布。我如何清楚地做到这一点?
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?
推荐答案
我看到了两种可能的解决方案:
I see two potential solutions to this:
- 从DOM删除旧画布(因此您只有新画布):
componentDidUpdate() {
console.log('componentDidUpdate');
// Get the old canvas and remove it
var oldCanvas = document.getElementById('canvas');
oldCanvas = null;
// Add your completely new canvas
const canvas = new fabric.Canvas('canvas');
this.setCanvasBackground(this.props.getSelectedImage.selectedImage, canvas);
}
- 在重新绘制新画布之前,请清除旧画布:
要清除画布,您需要执行上述链接中提到的操作。如果您使用的是这种方法,请确保不要在componentDidUpdate()中向页面添加新的画布。
To clear the canvas you need to do what was mentioned in the above link. If you are using this approach make sure not to add a new canvas to the page in componentDidUpdate().
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, 500, 500);
第二个解决方案的链接特别提到,如果不清除画布,绘制的元素将堆栈。
The link for the second solution specifically mentions that if you don't clear your canvas the drawn elements will stack.
这篇关于所选图像未显示在画布上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!