Как сделать снимок экрана с компонента React, не монтируя его в DOM? - PullRequest
0 голосов
/ 30 января 2019

Мой пример использования: у меня есть редактор веб-сайта и список доступных веб-страниц для пользователей.Каждая страница в этом списке представлена ​​миниатюрой.Каждый раз, когда пользователь вносит изменения в страницу с помощью редактора, эскиз соответствующего сайта должен обновляться, чтобы отразить это изменение.Я делаю это, монтируя компонент ThumbnailSandbox на странице, передавая реквизиты из хранилища Redux, а затем используя dom-to-png, чтобы создать скриншот и использовать его в списке.Но я хотел сделать это, не устанавливая компонент на странице, потому что я думаю, что это было бы более чистое решение и с меньшими шансами быть затронутым другими взаимодействиями, происходящими.Итак, я создал CodeSanbox , чтобы проиллюстрировать, чего я пытаюсь достичь.

Моя логика такова:

import React from "react";
import ReactDOMServer from "react-dom/server";
import html2canvas from "html2canvas";
import MyComp from "./component.jsx";

export const createScrenshot = () => {
  const el = (
    <div>
      test component <MyComp />
    </div>
  );

  const markup = ReactDOMServer.renderToString(el);
  let doc = new DOMParser().parseFromString(markup, "text/html");
  let target = doc.body.getElementsByClassName("my-comp")[0];

  console.log(markup, target);

  html2canvas(target, {
    useCORS: true,
    allowTaint: true,
    scale: 1,
    width: 500,
    height: 500,
    x: 0,
    y: 0,
    logging: true,
    windowWidth: 500,
    windowHeight: 500
  })
    .then(function(canvas) {
      console.log(">> ", canvas);
    })
    .catch(error => {
      console.log(error);
    });
};

Итак, я передаю компонент в ReactDOM, затем создаю узел DOM, используя строку из первого шага, и передаю узел в html2canvas.Но в этот момент я получаю ошибку Uncaught TypeError: Cannot read property 'pageXOffset' of null.Поскольку ownerDocument элемента, передаваемого в html2canvas, имеет значение null и не имеет свойств: devicePixelRation, innerWidth, innerHeight, pageYOffset и pageXOffset.Как я понимаю, это потому, что элемент узла не является частью DOM.

Теперь мои вопросы:

1) Есть ли способ решить эту проблему с помощью html2canvas?

2) Есть ли другой способ сделать скриншотРеагировать на компонент, в браузере, без монтирования компонента в DOM?

Заранее спасибо !!

1 Ответ

0 голосов
/ 30 января 2019

Для точки 1:

Почему бы вам не смонтировать компонент, а затем после обработки удалить компонент в ссылке?(может быть сделано и в ComponentDidMount, но ref должен предшествовать DidMount) Это наиболее стандартное решение для загрузки (создайте тег, нажмите, а затем удалите его)

Это пример непроверенного кода с использованием ref-вызованазад

export class CreateScrenshot extends React.Component {
    constructor() {
        super() {
            this._reactRef = this._reactRef.bind(this);
            this.state = {
                removeNode: false
            };
        }
    }

    _reactRef(node) {
        if(node) {
            // your html2Canvas handling and in the returned promise remove the node by
            this.setState({removeNode: true});
        }
    }

    render() {
        let childComponent = null;
        if(!this.state.removeNode) {
            {/*pass the ref of the child node to the parent component using the ref callback*/}
            childComponent =  (
                <div>
                    test component <MyComp refCallBack={this._reactRef}/>
                </div>
            );
        }
        return childComponent;
    }
}

однако ограничение заключается в том, что это будет асинхронным и может вызвать мерцание.Поэтому, если это возможно, попробуйте использовать библиотеку синхронизации, чтобы узел мог быть удален при следующем рендеринге.

Для точки 2: https://reactjs.org/docs/react-component.html#componentdidmount

Из раздела doc реагирования componentDidMount (): «Это можеттем не менее, это необходимо для случаев, таких как модалы и всплывающие подсказки, когда вам нужно измерить узел DOM перед рендерингом чего-либо, зависящего от его размера или положения. "

Это дает понять, что вы можете получить только измерения узловпосле того, как это было установлено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...