在React中渲染画布“子元素”

时间:2017-05-18 17:12:25

标签: reactjs html5-canvas

我正在尝试为一些React组件设置一个画布渲染系统(它们也可以在SVG中渲染,具体取决于它们的属性)。我还没有确定如何最好地做到这一点,但我目前采取的方法是在子组件上使用CanvasManager组件和canvasContents方法结合使用上下文并绘制它们预期内容。这样设置如下:

export default class CanvasManager extends React.Component {
  constructor(...args) {
    super(...args);

    this.childElements = [];
    this.canvasRender = this.canvasRender.bind(this);
  }

  componentDidMount(...args) {
    super.componentDidMount && super.componentDidMount(...args);
    this.canvasRender();
  }

  componentDidUpdate(...args) {
    super.componentDidMount && super.componentDidMount(...args);
    this.canvasRender();
  }

  canvasRender() {
    const ctx = this.canvas.getContext('2d');
    const { width, height } = this.props;

    ctx.clearRect(0, 0, width, height);
    this.childElements.forEach((child) => {
      child.canvasContents(ctx);
    });
  }

  render() {
    const { width, height, positionStyle, children } = this.props;

    const canvasChildren = React.Children.map(
      children,
      (child) => {
        const props = extend({}, child.props, {
          ref: (el) => {
            if (el) { this.childElements.push(el); }
          },
        });
        return extend({}, child, { props });
      },
    );

    return (<div style={ positionStyle }>
      <canvas
        ref={ (canvas) => { this.canvas = canvas; } }
        height={ height }
        width={ width }
      />
      { canvasChildren }
    </div>);
  }
}

这里的想法是CanvasManager将允许我根据需要处理画布的完全重绘,因此任何一个孩子获得新属性时,他们可以在{{1}上调用forceRender并根据需要清除并重绘整个画布。

但是,孩子们的ref函数似乎永远不会触发,CanvasManager总是一个空数组。 (由于我不理解的原因,它有时会触发this.childElements,因此会发出el=null语句。)如何在{{{{}}中访问我的子元素上的if方法1}}?

(或者,如果有更好和完全不同的方式,我非常愿意接受这些想法。)

0 个答案:

没有答案