Javascript 将HTML5画布(视频)元素分割成碎片

Javascript 将HTML5画布(视频)元素分割成碎片,javascript,jquery,canvas,html5-canvas,html5-video,Javascript,Jquery,Canvas,Html5 Canvas,Html5 Video,我是画布新手,我在谷歌上搜索了几个小时,但我被卡住了 我想做的是在画布元素上渲染视频,将其分割并设置片段动画。我已经完成了一半(见:),但我有几个问题: 我做得对吗,还是效率极低 我想使用全屏视频。无论我怎么尝试,画布网格+视频似乎与大小不匹配 我想动画的视频片段,但我不知道我应该如何解决他们。我可以得到某种数组并一个接一个地制作动画吗 我的JS看起来像这样。我试图在最重要的部分添加评论。至少我认为最重要的部分;) var video=document.getElementById('video

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

我想做的是在画布元素上渲染视频,将其分割并设置片段动画。我已经完成了一半(见:),但我有几个问题:

  • 我做得对吗,还是效率极低
  • 我想使用全屏视频。无论我怎么尝试,画布网格+视频似乎与大小不匹配
  • 我想动画的视频片段,但我不知道我应该如何解决他们。我可以得到某种数组并一个接一个地制作动画吗
  • 我的JS看起来像这样。我试图在最重要的部分添加评论。至少我认为最重要的部分;)

    var video=document.getElementById('video');//获取视频
    var ctx=canvas.getContext('2d'),
    列=6,
    行=4,
    w、 h,tileWidth,tileHeight;
    //启动视频并将其添加到画布
    video.addEventListener('play',function(){
    var$this=this;//缓存
    (函数循环(){
    如果(!$this.paused&!$this.end){
    drawImage($this,0,0,window.innerWidth,window.innerHeight);
    calcSize();//分割视频
    setTimeout(循环,1000/30);//以30fps的速度绘制
    }
    })();
    }, 0);  
    函数calcSize(){
    video.width=w=window.innerWidth;
    video.height=h=window.innerHeight;
    tileWidth=w/列;
    tileHeight=h/行;
    ctx.strokeStyle='#000';
    render();
    }
    函数render(){
    对于(变量x=0;x
    您可能会考虑:

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

    所以现在你只是在视频上画一个网格,对吗?您必须使用单元格坐标和的裁剪选项来实际分割视频。
    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();
    }