在画布中播放视频的一部分

时间:2016-05-31 13:51:08

标签: javascript html5 canvas html5-video

我想在画布上只播放一半视频,但在对角线上截断。 目前,我可以使用这个小小的javascript在画布上播放我的完整视频:

var video = document.getElementById('video');
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');

var drawFrame = function drawFrame() {
    context.drawImage(video, 0, 0, canvas.width, canvas.height);
    requestAnimationFrame(drawFrame);
};

requestAnimationFrame(drawFrame);

最后,我希望能够同时播放2个视频(我只需要在每个视频上调用drawImage),但每个视频都会在对角线上剪切,以呈现如下内容:

enter image description here

然后我想根据鼠标位置移动分隔符。

1 个答案:

答案 0 :(得分:4)

您可以使用合成来实现此目的。

组合使用alpha通道以各种方式组合非alpha数据,例如" source-in"将绘制源图像/视频,其中存在像素,而#34; destination-over"将现有像素保留在非alpha的位置,并且只绘制有alpha的新像素(这些也称为Porter-Duff or alpha composition。混合属于同一个伞,但目的与合成不同。)

有许多模式,但上面提到的模式将允许我们通过定义一个作为两者掩模的alpha区域来组合它们以获得我们想要的部分。我将包含一个概述,以显示运营商如何为每种模式工作,以便更好地了解他们的工作(来自Wikipedia):

Comp modes
(A =来源,B =目的地)

此案例所需的步骤为:

  • 使用合成模式初始化" source-over"因为我们在循环中使用它
  • 清除画布以确保我们有一个Alpha通道可以使用
  • 相对于鼠标位置绘制对角线的一半
  • 使用" source-in"在顶部绘制视频源2 (将其放在左侧)
  • 使用" destination-over"
  • 在顶部绘制视频源1

工作示例

这将加载两个不同的视频(从here借来的链接),加载时如上所述设置循环(只需加载视频几秒钟):



var ctx = c.getContext("2d"), pos = c.width * 0.5, count = 2;
ctx.fillText("Please wait while videos are loading...", 20, 20);
video1.oncanplay = video2.oncanplay = function() {if (!--count) renderFrame()};

function renderFrame() {
  ctx.globalCompositeOperation = "source-over";
  ctx.clearRect(0, 0, c.width, c.height);     // makes sure we have an alpha channel

  ctx.beginPath();                            // draw diagonal half
  ctx.moveTo(0, 0);
  ctx.lineTo(pos - 50, 0);
  ctx.lineTo(pos + 50, c.height);
  ctx.lineTo(0, c.height);
  ctx.fill();

  // video source 2
  ctx.globalCompositeOperation = "source-in";        // comp in source 2
  ctx.drawImage(video2, 0, 0, c.width, c.height);
  
  // video source 1
  ctx.globalCompositeOperation = "destination-atop"; // comp in source 1
  ctx.drawImage(video1, 0, 0, c.width, c.height);

  requestAnimationFrame(renderFrame)
}

c.onmousemove = function(e) {
  pos = e.clientX - c.getBoundingClientRect().left;
}

video {display:none}

<canvas id=c width=640 height=400></canvas>
<video id=video1 muted autoplay loop src="http://media.w3.org/2010/05/sintel/trailer.mp4"></video>
<video id=video2 muted autoplay loop src="http://media.w3.org/2010/05/video/movie_300.webm"></video>
&#13;
&#13;
&#13;