react-konva上传后如何更改图像? [英] react-konva How to change image after uploading?
问题描述
我正在做一个小项目,允许用户上传图像,然后图像将显示在画布上.
I'm working on a small project that allows user to upload image and then the image will be displayed on a canvas.
为此,我正在使用反应-konva .
我有一个名为DesignPage的容器组件,它可以管理状态,并将事件处理程序传递给其子级.
I have a container component called DesignPage, which manages the state and pass event handlers to its children.
在此DesignPage组件内,我还有两个其他组件:工具-画布
Inside this DesignPage component, I have 2 other components: Tools - Canvas
当我使用工具组件上载图像时,该图像应显示在 Canvas 组件上.
When I upload an image using Tools component, the image should be displayed on Canvas component.
我正在工具中使用 react-dropzone >处理文件上传的组件
I'm using react-dropzone inside Tools component to handle file upload
在此 Canvas 组件内部,有一个名为 DesignImage 的子组件,该子组件仅用于显示图像.
Inside this Canvas component, there is a child component called DesignImage, which is just for displaying the image.
但是问题是,当我上传时,它只是不会改变画布上的图像.
But the thing is, it just doesn't change the image on canvas when I upload.
我该如何解决?
How can I fix that?
这是我的代码:
DesignPage 组件:
import React, {Component} from 'react';
import {
Row,
Col
} from 'reactstrap';
import Tools from "../components/DesignPage/Tools";
import Canvas from "../components/DesignPage/Canvas";
import Styles from "../components/DesignPage/Styles";
class DesignPage extends Component {
state = {
text: '',
image: '',
files: []
};
static propTypes = {};
handleTextChange = e => {
this.setState({text: e.target.value});
};
handleFileDrop = files => {
this.setState({
files,
image: files[0].preview
});
};
render() {
return <Row>
<Col xs={12} md={4}>
<Tools
files={this.state.files}
onTextChange={this.handleTextChange}
onFileDrop={this.handleFileDrop}/>
</Col>
<Col xs={12} md={5}>
<Canvas
text={this.state.text}
image={this.state.image}/>
</Col>
<Col xs={12} md={3}>
<Styles/>
</Col>
</Row>;
}
}
export default DesignPage;
工具组件:
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {
TabContent,
TabPane,
Nav,
NavItem,
NavLink,
Row,
Col,
FormGroup,
Label
} from 'reactstrap';
import classnames from 'classnames';
import Dropzone from 'react-dropzone';
class Tools extends Component {
state = {
activeTab: '1'
};
toggle = (tab) => {
if (this.state.activeTab !== tab) {
this.setState({
activeTab: tab
});
}
};
render() {
return <Row>
<Col xs={12}>
<div>
<Nav tabs justified>
<NavItem>
<NavLink
className={classnames({active: this.state.activeTab === '1'})}
onClick={() => {
this.toggle('1');
}}
>
Text
</NavLink>
</NavItem>
<NavItem>
<NavLink
className={classnames({active: this.state.activeTab === '2'})}
onClick={() => {
this.toggle('2');
}}
>
Art
</NavLink>
</NavItem>
</Nav>
<TabContent activeTab={this.state.activeTab}>
<TabPane tabId="1">
<Row>
<Col sm="12">
<FormGroup>
<Label for={"custom-text"}>Enter text below</Label>
<textarea
className={"form-control"}
id={"custom-text"}
onChange={this.props.onTextChange}/>
</FormGroup>
<FormGroup>
<Label for={"font-select"}>Choose a font</Label>
</FormGroup>
</Col>
</Row>
</TabPane>
<TabPane tabId="2">
<Row>
<Col sm="12">
<FormGroup>
<div className="dropzone-container">
<Dropzone onDrop={this.props.onFileDrop}>
<p>Drop a design here, or click to select design to upload.</p>
</Dropzone>
</div>
</FormGroup>
</Col>
</Row>
</TabPane>
</TabContent>
</div>
</Col>
</Row>;
}
}
Tools.propTypes = {
files: PropTypes.array.isRequired,
onTextChange: PropTypes.func.isRequired,
onFileDrop: PropTypes.func.isRequired
};
export default Tools;
画布组件:
import React from 'react';
import PropTypes from 'prop-types';
import {
Row,
Col
} from 'reactstrap';
import {Stage, Layer} from 'react-konva';
import UserText from "./Canvas/UserText";
import DesignImage from "./Canvas/DesignImage";
const Canvas = props => {
return <Row>
<Col xs={12} className={"canvas-container"}>
<div className={"object-container"}>
<img className={"object-img"} src={"images/iPhone5A.png"} alt={"iPhone5A"}/>
<div className="drawing-area">
<Stage width={window.innerWidth} height={window.innerHeight}>
<Layer>
<UserText text={props.text}/>
<DesignImage image={props.image}/>
</Layer>
</Stage>
</div>
</div>
</Col>
</Row>;
};
Canvas.propTypes = {
text: PropTypes.string.isRequired,
image: PropTypes.string.isRequired
};
export default Canvas;
DesignImage 组件:
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {Image} from 'react-konva';
class DesignImage extends Component {
state = {
image: null
};
static propTypes = {
image: PropTypes.string.isRequired
};
componentDidMount() {
const image = new window.Image();
image.src = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRYTULZCGUVEQJEXt9iB8PU4Kb2FMS9Z6ufR1FnQTdrEl5uBOl52Q';
image.onload = () => {
// setState will redraw layer
// because "image" property is changed
this.setState({
image: image
});
};
}
render() {
return <Image image={this.props.image} draggable={true}/>;
}
}
export default DesignImage;
推荐答案
当组件具有props中的新图像时,您需要编写代码来更新图像.
You need write a code to update the image when the component has a new image from props.
class DesignImage extends Component {
state = {
image: null
};
static propTypes = {
image: PropTypes.string.isRequired
};
componentDidMount() {
this.updateImage();
}
componentDidUpdate() {
this.updateImage();
}
updateImage() {
const image = new window.Image();
image.src = this.props.image;
image.onload = () => {
this.setState({
image: image
});
};
}
render() {
return <Image image={this.state.image} draggable={true}/>;
}
}
更新:
您可以使用use-image
挂钩来简化图像加载:
You can use use-image
hook for simpler image loading:
import useImage from 'use-image';
const DesignImage = ({ image }) => {
const imgElement = useImage(image);
return <Image image={imgElement} draggable={true}/>;
}
这篇关于react-konva上传后如何更改图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!