首页 > 解决方案 > 渲染从道具接收到的画布对象

问题描述

再会!

我是 React 和 html2canvas 的新手。我正在制作一个应用程序,它将使用 html2canvas 对我的 DOM 进行“截图”,然后将其存储到一组截图中,然后这些截图也将呈现在屏幕上。

<canvas>将从 html2canvas 承诺接收到的每个对象存储到一个数组中,然后将其传递给我的ScreenshotsContainer组件,该组件将数组传递给Screenshots组件。然后该Screenshots组件会将对象数组映射<canvas>到各个Screenshot组件。

在 App.js 中,我调用 html2canvas 函数,然后将数组传递给 ScreenshotsContainer 组件

import React, { Component } from 'react';
import ScreenshotsContainer from './containers/ScreenshotsContainer/ScreenshotsContainer'
import html2canvas from 'html2canvas';

import './App.css';

class App extends Component {
  state = {
    canvasArray: []
  }

  getScreenshotHandler = () => {
    console.log("[Canvas Array from state length:]" + this.state.canvasArray.length)
    let canvasArray = this.state.canvasArray;

    html2canvas(document.body).then((canvas) => {
      canvasArray.push(canvas)
    });

    console.log("[Canvas Object value: ]" + canvasArray);
    this.setState({ canvasArray: canvasArray })

  }

  render() {

    return (
      <React.Fragment>
        <button onClick={this.getScreenshotHandler}>Get Screenshot</button>
        <ScreenshotsContainer canvasArray={this.state.canvasArray} />
      </React.Fragment>
    );
  }
}

export default App;

ScreenshotsContainer 组件会将接收到的数组传递给 Screenshots 组件:

    import React, { Component } from 'react';
import './ScreenshotsContainer.css'
import Screenshots from '../../components/Screenshots/Screenshots';

class ScreenshotsContainer extends Component {

    render() {
        return (
            <div className="ScreenshotsContainer">
                <Screenshots canvasArray={this.props.canvasArray} />
            </div>
        );
    }
}
export default ScreenshotsContainer;

Screenshots 组件将映射数组并将每个画布对象传递给 Screenshot 组件:

import React, { Component } from 'react';
import Screenshot from './Screenshot/Screenshot';

class Screenshots extends Component {
    render() {
        const screenshots = this.props.canvasArray.map(canvas => {
            return (
                <Screenshot
                    key={Math.random}
                    canvasObj={canvas}
                />
            )
        })
        return (
            <React.Fragment>
                {screenshots}
            </React.Fragment>
        );
    }
}
export default Screenshots;

这是屏幕截图组件

import React from 'react';
import './Screenshot.css';

const screenshot = (props) => (
    <div className="Screenshot" >
        <canvas ref={props.canvasObj} style={{
            width: '10%',
            height: '10%'
        }} />
    </div>
);

export default screenshot;

按下按钮时我实际得到的:

我的结果的实际截图我 想知道哪一部分出了问题。任何帮助,将不胜感激。

标签: javascriptreactjshtml2canvas

解决方案


这个特定的库以特定的方式工作(看起来它在幕后做了很多“魔术”——你应该在这里更具体地查看源代码,即 src 中的渲染器文件夹)

将画布保存到数组内部的状态(正确的反应做事方式)将是一个问题,因为它将它保存为具有许多方法等的复杂对象......我们无法渲染对象......这个库是没有考虑到 React 编写......

下面的代码示例是 React 中的一个简单实现...

这是一个现场演示:https ://codesandbox.io/s/9y24vwn1py

import React, { Component } from 'react';
import html2canvas from 'html2canvas';

class App extends Component {
  constructor(props) {
    super(props);
    this.captureRef = React.createRef();
    this.displayRef = React.createRef();
  }

  getScreenshotHandler = () => {
    html2canvas(this.captureRef.current).then(canvas =>
      this.displayRef.current.appendChild(canvas),
    );
  };

  render() {
    return (
      <div>
        <div ref={this.captureRef}>
          <h2>This enitre div will be captured and added to the screen</h2>
        </div>
        <button onClick={this.getScreenshotHandler}>Get Screenshot!</button>
        <section>
          <h5>Your screenshots will be availbale below</h5>
          <div ref={this.displayRef} />
        </section>
      </div>
    );
  }
}

export default App;

编辑:根据下面的评论,这里是另一种解决方法:

class App extends Component {
  constructor(props) {
    super(props);
    this.state = { canvasArray: [] };
    this.captureRef = React.createRef();
  }

  getScreenshotHandler = () => {
    html2canvas(this.captureRef.current).then(canvas =>
      this.setState({
        canvasArray: [canvas.toDataURL(), ...this.state.canvasArray],
      }),
    );
  };

  renderCanvas = () => {
    return this.state.canvasArray.map((canvas, i) => {
      return <img key={i} src={canvas} alt="screenshot" />;
    });
  };

  render() {
    return (
      <div className="wrapper">
        <div ref={this.captureRef}>
          <p>This enitre div will be captured</p>
        </div>
        <button onClick={this.getScreenshotHandler}>Get Screenshot!</button>
        <section>
          <h5>Your screenshots will be availbale below:</h5>
          {this.renderCanvas()}
        </section>
      </div>
    );
  }
}

现场演示链接:https ://codesandbox.io/s/1r213057vq


推荐阅读