简体   繁体   English

如何设置自定义大小以在 react-konva 中导出图像?

[英]How to set a custom Size to exporting image in react-konva?

I have created a responsive stage using react-konva, but I cannot find a way to set a custom size to export the image.我使用 react-konva 创建了一个响应阶段,但我找不到设置自定义大小以导出图像的方法。 usually, right-click and saving the image is working as the size in the window at that time has.通常情况下,右击保存图片是window当时的大小。 I wanted to add a button to download the image, but I couldn't set up a way to do that because I'm new to react hooks, I couldn't find a way to set up the data URL. please kindly refer to this我想添加一个按钮来下载图像,但我无法设置这样做的方法,因为我是反应钩子的新手,我找不到设置数据 URL 的方法。请参阅这个

    import React, { Component, useState, useRef, useCallback } from "react";
    import { render } from "react-dom";
    import { Stage, Layer, Text, Image, Rect, Transformer, Circle, Line } from "react-konva";
    import card01 from "../images/01.jpg"
    import useImage from "use-image";
    import "./styless.css";
    import Button from '@mui/material/Button';
    
    const WIDTH = 875;
    const HEIGHT = 500;
    const ZOOM = 1;
    
    class Canvas extends Component {
      state = {
        stageWidth: WIDTH,
        zoom: 1,
      };
    
      render() {
        
        const { containerWidth } = this.props;
        var scale = (containerWidth / WIDTH) * ZOOM;
        let width = WIDTH * scale;
        let height = HEIGHT * scale;
        console.log({ containerWidth, width, height, scale });
    
        const LionImage = () => {
            const [image] = useImage(card01);
            return <Image image={image} width={width} height={height} scale={scale}/>;
          };
    
        return (
          <div style={{ width: `100%`, border: "1px solid grey" }}>
          
            <Stage width={width} height={height} scale={scale}>
              <Layer>
              <LionImage />
              <Text
                x={containerWidth / 10}
                y={scale*35}
                text="Some text"
                fontSize={28}
                fontFamily="Poppins"
                fill="gray"
                scaleX={scale}
                scaleY={scale}
    
                width={width}
                height={height}
              />
              </Layer>
            </Stage>
          </div>
        );
      }
    }
    
    class App extends Component {
      state = {
        zoom: 1
      };
      componentDidMount() {
        this.checkSize();
        window.addEventListener("resize", this.checkSize);
      }
    
      componentWillUnmount() {
        window.removeEventListener("resize", this.checkSize);
      }
    
      checkSize = () => {
    
        const containerWidth = this.container.offsetWidth;
        const containerHeight = this.container.offsetHeight;
        this.setState({ ...this.state, containerWidth, containerHeight });
    
      };
    
      render() {
        const pWidht = this.state.containerWidth
          ? `${this.state.containerWidth * this.state.zoom}px`
          : "100%";
    
        return (
            <>
          
            <div
                style={{ width: "80%", height: "100%", left: "10%", position: "absolute" }}
                ref={(node) => {
                    this.container = node;
                } }
            >
                <div style={{ overflow: "auto;", width: `${pWidht}` }}>
                    <div>
                        <Button color="inherit" size="small" variant="outlined" sx={{boxShadow:3}} style={{marginTop:"20px",marginRight:"10px",marginBottom:"10px", fontSize:"12pt", color:"white"}}
                            type="button"
                            value="+"
                            onClick={() => this.setState({ ...this.state, zoom: this.state.zoom + 0.2 })}> + </Button>
                        <Button color="inherit" size="small" variant="outlined" sx={{boxShadow:3}} style={{marginTop:"20px",marginRight:"10px",marginBottom:"10px", fontSize:"12pt", color:"white"}}
                            type="button"
                            value="-"
                            onClick={() => this.setState({ ...this.state, zoom: this.state.zoom - 0.2 })} > - </Button>
                    </div>
                    <Canvas containerWidth={pWidht.replace("px", "")} />
                </div>
            </div>
      
            </>
        );
      }
    }
    
    const X = () => {
      return <App />;
    };
    
    render(<X />, document.getElementById("root"));
    export default App;

You need to use a ref to the Stage and get the image URL and download it.您需要使用Stageref并获取图像 URL 并下载它。

  1. In your Canvas component create a ref using createRef .在您的 Canvas 组件中使用createRef创建一个ref
  constructor(props) {
    super(props);
    this.stageRef = createRef(null);
  }
  1. Add the stageRef to your Stage .stageRef添加到您的Stage
<Stage  ... ref={this.stageRef}>
        ...
        ...
</Stage>
  1. Add two following utility functions, downloadURI to download image as a file and handleExport to get the data URI from the ref .添加以下两个实用函数, downloadURI将图像下载为文件, handleExportref获取数据 URI。
  downloadURI = (uri, name) => {
    var link = document.createElement("a");
    link.download = name;
    link.href = uri;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  };

  handleExport = () => {
    const uri = this.stageRef.current.toDataURL();
    this.downloadURI(uri, "stage.png");
  };
  1. Add a new button with the click handler set to handleExport function.添加一个新按钮,点击处理程序设置为handleExport function。
<button onClick={this.handleExport}>Download</button>

Working example:工作示例:

编辑 practical-elgamal-evik50

Manually setting the image size手动设置图像大小

Use the following utility function which will change the image width and height using the data URI received from the Stage ref .使用以下实用程序 function,它将使用从 Stage ref接收到的数据 URI 更改图像的widthheight

resizeImage = (url, width, height, callback) => {
  var sourceImage = new Image();

  sourceImage.onload = function () {
    var canvas = document.createElement("canvas");
    canvas.width = width;
    canvas.height = height;
    canvas.getContext("2d").drawImage(sourceImage, 0, 0, width, height);
    callback(canvas.toDataURL());
  };

  sourceImage.src = url;
};

// fixed the image size to 200px by 200px before download
handleExport = () => {
  const uri = this.stageRef.current.toDataURL();
  this.resizeImage(uri, 200, 200, (sizeUpdatedDataURL) => {
    this.downloadURI(sizeUpdatedDataURL, "stage.png");
  });
};

编辑 blissful-bose-5fw3kl

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM