我正在开发一个应用程序,用户可以从提供的图像列表中选择图像。当用户单击列表中的图像时,所选图像应作为背景显示在画布上。我正在使用reactjs,redux和fabricjs开发它。
当我这样做时,我不会选择图像 this.props.getSelectedImage.image.image所以我可以更新 setCanvasBackground。
图片-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;
}
}
图片-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所以我可以在画布上显示所选图像。
我该怎么办?
反应v15.4.2已被使用
更新
componentDidUpdate() {
console.log('componentDidUpdate');
const canvas = new fabric.Canvas('canvas');
this.setCanvasBackground(this.props.getSelectedImage.selectedImage, canvas);
}
如果我使用componentDidUpdate生命周期方法,它可以工作,但我得到以下结果。这么多画布都被重新创建了,我知道它,因为我在componentDidUpdate中创建了一个canvas对象来更新画布。我怎么能以明确的方式做到这一点?
答案 0 :(得分:0)
我看到两个可能的解决方案:
How to destroy / reload the canvas in html 5?
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);
}
Redrawing Canvas in HTML5 using Javascript
要清除画布,您需要执行上述链接中提到的操作。如果您使用此方法,请确保不要在componentDidUpdate()中向页面添加新画布。
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, 500, 500);
第二个解决方案的链接特别提到,如果不清除画布,绘制的元素将叠加。