将HTML5画布(视频)元素分割成若干块

Slitting HTML5 canvas (video) element into pieces

本文关键字:分割 元素 HTML5 画布 视频      更新时间:2023-09-26

我是画布新手,我已经在谷歌上搜索了几个小时,但我被卡住了。

我想做的是在画布元素上渲染视频,将其分割并设置片段的动画。我已经到了一半(参见:http://jsbin.com/riduxadazi/edit?html,css,js,控制台,输出),但我有几个问题:

  1. 我做的事情是对的,还是效率极低
  2. 我想使用视频全屏。无论我尝试什么,画布网格+视频的大小似乎都不匹配
  3. 我想把视频片段制作成动画,但我不知道该如何处理。我可以得到某种数组并一个接一个地设置片段的动画吗

我的JS是这样的。我试图在最重要的部分添加评论。至少我认为是最重要的部分;)

var video = document.getElementById('video'); // Get the video
var ctx = canvas.getContext('2d'), 
    columns = 6,
    rows = 4,
    w, h, tileWidth, tileHeight;
// Start video and add it to canvas
video.addEventListener('play', function() {
    var $this = this; //cache
    (function loop() {
      if (!$this.paused && !$this.ended) {
        ctx.drawImage($this, 0, 0,window.innerWidth,window.innerHeight); 
        calcSize(); // Divide video
        setTimeout(loop, 1000 / 30); // drawing at 30fps
      }
    })();
  }, 0);  
function calcSize() {
    video.width = w = window.innerWidth;
    video.height = h = window.innerHeight;
    tileWidth = w / columns;
    tileHeight = h / rows;
    ctx.strokeStyle = '#000';
    render();
}
function render() {
    for(var x = 0; x < columns; x++) {
        ctx.moveTo(x * tileWidth, 0);
        ctx.lineTo(x * tileWidth, h);
    }
    for(var y = 0; y < rows; y++) {
        ctx.moveTo(0, y * tileHeight);
        ctx.lineTo(w, y * tileHeight);
    }
    ctx.stroke();
}

您可能会考虑:

  • 使用requestAnimationFrame更新循环。这允许与监视器更新速率完美同步,并且比setTimeout/setInterval更高效。您可以通过使用一个交替的简单布尔标志来调节它,使其仅每1/30帧更新一次,以匹配视频速率
  • 视频元素不需要插入到DOM中。此外,实际的视频位图大小是通过属性videoWidthvideoHeight读取的,不过,在提供的代码中,您应该使用画布的属性widthheight,因为这决定了目标大小。要按比例绘制,您可以使用这个答案
  • 如果你想分割内容,使用drawImage()和剪辑参数将是在画布上绘制视频的更有效的方法
  • 您可以使用数学方法分割视频(请参阅此答案),也可以使用允许您定义源区域并具有单独属性(如位置、旋转、缩放等)的对象。以防您不得不考虑目的地位置以适应画布的当前大小