在React-Konva中克隆节点并附加到单独的图层

时间:2018-10-23 22:06:47

标签: reactjs html5-canvas konvajs

我正在尝试重新创建类似于此站点上的悬停效果的效果:http://tabotabo.com

当前,我正在做的是在具有第二个按比例放大的图层的层上播放视频,并且还使用附加的destination-in合成操作在文本对象上播放视频。目前,这已经足够好了,但是我很好奇是否会有一种更有效的方法来实现这一目标,方法是缓存或克隆第一层并将其发送到第二层,而不是让两个单独的视频对象串联运行。 >

这是相关的代码,如果有帮助的话。

主渲染:

<Stage width={width} height={height} ref={ref => (this.stage = ref)}>
  <Layer hitGraphEnabled={false}>
    <CanvasVideo
      src={this.state.background} 
      settings={{id: 'main', width: width, height: height }}
      ref={(el) => this.main = el }
    />
  </Layer>

  <Layer hitGraphEnabled={false} scaleX={hoverScale} scaleY={hoverScale} x={scaleOffsetX} y={scaleOffsetY}>
    <CanvasVideo
      src={this.state.background} 
      settings={{id: 'main2', width: width, height: height }}
      ref={(el) => this.main2 = el }
    />

    <Text 
      id="hoverText"
      text={this.state.menu.hoverText}
      globalCompositeOperation='destination-in'
      fontSize={200}
      fill="white"
      opacity={hoverOpacity} 
      height={height}
      width={width}
      align="center"
      verticalAlign='middle'
    />
  </Layer>
</Stage>

视频容器类:

import React, { Component } from 'react';
import Konva from 'konva';
import { render } from 'react-dom';
import { Stage, Layer, Image } from 'react-konva';

class CanvasVideo extends Component {
    constructor(props) {
      super(props);

      const video = document.createElement('video');
      video.muted = true;
      video.autoplay = false;
      video.loop = true;
      video.src = props.src;
      this.state = {
        video: video
      };
      video.addEventListener('canplay', () => {
        video.play();
        this.image.getLayer().batchDraw();
        this.requestUpdate();
      });

    }

    requestUpdate = () => {
      this.image.getLayer().batchDraw();
      requestAnimationFrame(this.requestUpdate);
    }
    render() {
      let { settings } = this.props
        return (
            <Image
              {...settings}
              image={this.state.video}
              ref={node => { this.image = node; }}
            />
        );
    }
}

CanvasVideo.defaultProps = {
  settings: null,
};

export default CanvasVideo;

任何解释或见解将不胜感激。

谢谢!

1 个答案:

答案 0 :(得分:1)

当前,无法在不同的父级中重用Konva.Image或任何其他Konva.NodeKonva.Node只能有一个父母。

我看到的唯一一种优化是重用您在<video>组件中创建的CanvasVideo元素。可能是这样的:

const cache = {};

function createVideo(url) {
   if (cache[url]) {
      return cache[url];
   }
   const video = document.createElement('video');
   video.src = url;
   cache[url] = video;
   return video;
}

const video = createVideo(props.src);