react-konva上传后如何更改图像? [英] react-konva How to change image after uploading?

查看:186
本文介绍了react-konva上传后如何更改图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个小项目,允许用户上传图像,然后图像将显示在画布上.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆