gpt4 book ai didi

reactjs - React-konva 上传后如何更改图像?

转载 作者:行者123 更新时间:2023-12-01 01:34:57 37 4
gpt4 key购买 nike

我正在开发一个小项目,允许用户上传图像,然后图像将显示在 Canvas 上。

我正在使用react-konva为此。

我有一个名为 DesignPage 的容器组件,它管理状态并将事件处理程序传递给其子组件。

在这个 DesignPage 组件中,我还有另外 2 个组件:工具 - Canvas

当我使用Tools组件上传图像时,图像应该显示在Canvas组件上。

我正在使用react-dropzone工具组件内处理文件上传

在这个Canvas组件中,有一个名为DesignImage的子组件,它只是用于显示图像。

但问题是,当我上传时,它并没有改变 Canvas 上的图像。

我该如何解决这个问题?

这是我的代码:

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;

Canvas 组件:

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 获得新图像时,您需要编写代码来更新图像。

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 Hook 来简化图像加载:

import useImage from 'use-image';

const DesignImage = ({ image }) => {
const imgElement = useImage(image);
return <Image image={imgElement} draggable={true}/>;
}

关于reactjs - React-konva 上传后如何更改图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49736475/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com