【问题标题】:Draw shapes on HTML5 Canvas...with video在 HTML5 Canvas 上绘制形状...带视频
【发布时间】:2012-03-13 09:23:06
【问题描述】:

我在谷歌上搜索了一些答案,但都没有找到明确的答案:是否可以使用 HTML5 画布播放视频,并允许用户在此视频上绘图? 在某些情况下,用例是无限循环播放视频,以便用户可以在特定区域上绘制多个框以指示感兴趣的区域。

作为奖励 (:P),如果我能自己弄清楚如何做到这一点,关于如何在 Drupal 中做到这一点的任何提示?我已经在看 Canvas Field 模块了,但是如果你对这一点也有任何提示(尽管第一个是优先级),那就太棒了!

【问题讨论】:

    标签: html drupal canvas html5-video html5-canvas


    【解决方案1】:

    您可以在画布上绘制 html5 视频元素。 drawImage 方法在第一个参数中接受一个视频元素,就像一个图像元素一样。这将获取视频元素的当前“帧”并将其渲染到画布上。要获得流畅的视频播放,您需要反复将视频绘制到画布上。

    然后您可以在画布上正常绘图,确保在每次更新视频帧后重新绘制所有内容。

    Here is a demo of video on canvas

    here is a in-depth look into video and the canvas

    【讨论】:

      【解决方案2】:

      我最近收到一位客户提出的提供此功能的请求,它必须是 CMS 友好的。该技术涉及三大理念

      • 绘图功能
      • 重复调用同一个绘图函数
      • 使用requestAnimationFrame 绘制下一帧

      假设您已经有一个视频元素,您将采取以下步骤

      1. 隐藏视频元素
      2. 创建一个高度/宽度与视频元素匹配的画布元素,并将其存储在某处
      3. 使用 `canvas.getContext('2d') 获取画布元素的上下文并将其存储在某处
      4. 创建绘图函数
      5. 在该绘图函数中,您可以使用canvas.drawImage(src, x, y),其中src 是视频当前帧的编辑版本;
      6. 在该绘图函数中,使用递归再次调用自身

      我可以给你两个例子来说明这一点(并且可用于内容管理系统)

      第一个在这里:https://jsfiddle.net/yywL381w/19/

      一家名为 SDL 的公司开发了一种名为 Media Manager 的工具来托管视频。您看到的是一个 jQuery 插件,它从 data-* 获取其参数,从 Media Manager Rest API 发出请求,创建视频,并完全基于 data* 属性添加效果。该插件可以轻松调整以处理从其他来源调用的视频。您可以查看repo 以获取有关使用的更多详细信息。

      另一个例子在这里:http://codepen.io/paceaux/pen/egLOeR

      那不是 jQuery 插件;它是一个 ES6 类。您可以使用以下方法创建图像/视频并应用裁剪效果:

      let imageModule = new ImageCanvasModule(module);
      imageModule.createCanvas();
      imageModule.drawOnCanvas();
      imageModule.hideOriginal();
      

      您将在 ImageCanvasModule 类中观察到这个方法:

      drawFrame () {
          if (this.isVideo && this.media.paused) return false;
      
          let x = 0;
          let width = this.media.offsetWidth;
          let y = 0;
      
          this.imageFrames[this.module.dataset.imageFrame](this.backContext);
          this.backContext.drawImage(this.media, x, y, width, this.canvas.height);
      
          this.context.drawImage(this.backCanvas, 0, 0);
      
          if (this.isVideo) {
              window.requestAnimationFrame(()=>{
                  this.drawFrame();
              });
          }
      }
      

      该类创建了第二个画布,用于绘图。该画布是不可见的,这只是他们为浏览器节省了一些心痛。

      内容可管理的“操纵”是this.imageFrames[this.module.dataset.imageFrame](this.backContext);

      “帧”是存储在图像/视频上的属性(可以通过 CMS 中的模板输出)。这将获取 imageFrame 的名称,并将其作为匹配函数运行。它还会在上下文中发送(因此如果需要,我可以在背面画布或主画布上的绘图之间切换)

      然后this.backContext.drawImage(this.media, x, y, width, this.canvas.height); 在后面的上下文中绘制图像。

      最后,这出现在带有this.context.drawImage(this.backCanvas, 0, 0); 的主画布上,我在其中取出后画布,并将其绘制到主画布上。因此可见的画布具有最少的操作量。

      最后,因为这是一个视频,我们要绘制一个新帧。所以我们有函数调用本身:

              if (this.isVideo) {
              window.requestAnimationFrame(()=>{
                  this.drawFrame();
              });
      

      整个设置允许我们使用 CMS 输出 data-* 属性,其中包含用户想要在图像周围绘制的框架类型。 JavaScript 然后生成该图像或视频的画布版本。示例标记可能如下所示:

      <video muted loop autoplay data-image-frame="wedgeTop"> 
      

      【讨论】:

        猜你喜欢
        • 2013-11-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-18
        • 2016-02-23
        • 1970-01-01
        • 2018-07-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多