在 HTML5 Canvas 上绘制形状...带视频

Posted

技术标签:

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

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

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

【问题讨论】:

【参考方案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 绘制下一帧

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

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

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

第一个在这里: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"> 

【讨论】:

以上是关于在 HTML5 Canvas 上绘制形状...带视频的主要内容,如果未能解决你的问题,请参考以下文章

CreateJs Canvas 形状在 Windows Phone 上失去坐标

如何使用canvas HTML5绘制一个星?

如何在 html5 画布中绘制椭圆?

Canvas在Flyme主题的应用实践

确定绘制到画布中的形状/图形的边界

可拖动图像上的画布绘图