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

jbu*_*s0n 3 html javascript canvas html5-video

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

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);
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

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

小智 5

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

合成使用 Alpha 通道以各种方式组合非 Alpha 数据,例如“source-in”将在存在像素的位置绘制源图像/视频,而“destination-over”将保留存在非 Alpha 的现有像素,并且只在有 alpha 的地方绘制新的(这些也称为Porter-Duff 或 alpha 合成。混合属于同一范畴,但与合成具有不同的目的)。

有很多模式,但上面提到的模式将允许我们将它们组合起来,只需定义一个用作两者遮罩的 alpha 区域即可获得我们想要的部分。我将提供一个概述来展示操作员如何在每种模式下工作,以便更好地理解他们的作用(来自维基百科):

补偿模式
(A = 来源,B = 目的地)

在这种情况下所需的步骤是:

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

工作示例

这将加载两个不同的视频(从此处借用的链接),并在加载时设置如上所述的循环(只需给视频几秒钟的加载时间):

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;
}
Run Code Online (Sandbox Code Playgroud)
video {display:none}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)