我正在尝试重新创建类似于此站点上的悬停效果的效果: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;
任何解释或见解将不胜感激。
谢谢!
答案 0 :(得分:1)
当前,无法在不同的父级中重用Konva.Image
或任何其他Konva.Node
。 Konva.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);