我见过各种 Voronoi 图的实现。也许你见过一些,但不知道它是什么。它看起来几乎像随机的彩色玻璃。

在数学中,Voronoi 图是将平面划分为区域,这些区域基于到平面上特定子集中的点的距离。
甚至可以 手绘 Voronoi 图,正如 eLVirus88 所记录的那样。

我想尝试一下。
想法
我的想法是将视频分割成碎片(称为单元格),并将它们放在 3D 空间中稍微不同的 z 轴上。然后,通过移动鼠标,您可以旋转整个体验,从而在不同的深度看到这些单元格。
代码
基于 Raymond Hill 和 Larix Kortbeek 的 JavaScript 实现,我需要做的第一件事是分割单元格。
我选择使用<canvas>
元素,并将每个单元格放在不同的画布上,通过 CSS 位于不同的 3D 平面上。
Voronoi 库负责计算所有站点到单元格,并为我们创建带有顶点和边的对象。

单元格到画布
首先,我们创建与 Voronoi 单元格数量匹配的画布。这些将呈现到 DOM 中。画布及其相应的上下文将保存到数组中。
var canv = document.createElement('canvas');
canv.id = 'mirror-'+i;
canv.width = canvasWidth;
canv.height = canvasHeight;
// Append to DOM
document.body.appendChild(canv);
document.getElementById('container-mirrors').appendChild(canv);
// Push to array
canvasArray.push(canv);
contextArray.push(canv.getContext('2d'));
蒙版
所有画布现在都是视频的副本。
所需的效果是在每个画布上显示一个单元格。 Voronoi 库 为我们提供了compute
函数。当使用边界提供站点时,我们得到一个详细的对象,从中提取所有单元格的边。这些将用于使用 globalCompositeOperation 创建每个部分的剪切。
// Compute
diagram = voronoi.compute(sites, bounds);
// Find cell
for (i=0;i<sites.length;i++) {
if (!found) {
cell = diagram.cells[i];
if (sites[j].voronoiId === cell.site.voronoiId) {
found = 1;
}
}
}
// Create mask to only show the current cell
ctx.globalCompositeOperation = 'destination-in';
ctx.globalAlpha = 1;
ctx.beginPath();
var halfedges = cell.halfedges,
nHalfedges = halfedges.length,
v = halfedges[0].getStartpoint();
ctx.moveTo(v.x,v.y);
for (var iHalfedge=0; iHalfedge<nHalfedges; iHalfedge++) {
v = halfedges[iHalfedge].getEndpoint();
ctx.lineTo(v.x,v.y);
}
ctx.fillStyle = sites[j].c;
ctx.fill();

添加视频
将视频显示到画布上只需要几行代码。这将在requestAnimationFrame
上执行。
v = document.getElementById('video');
ctx.drawImage(v,0,0,960,540);
也可以使用视频输入源(如网络摄像头),但我并不喜欢此演示的结果。如果您想了解如何使用网络摄像头通过getUserMedia()
方法绘制到画布,您可以阅读 此处的信息。
为了优化视频绘制性能,在requestAnimationFrame
之间跳过几帧。Web 的视频通常以不高于 30 fps 的帧速率进行编码。
查看 CodePen 上 virgilspruit (@Virgilspruit) 编写的 分块 HTML5 视频 - 演示 1。
结论
像这样的演示是我最喜欢做的事情。看看有什么,并添加自己的互动层。我期待着看到其他人将如何使用这个漂亮的视觉算法。
查看 CodePen 上 virgilspruit (@Virgilspruit) 编写的 分块 HTML5 视频 - 演示 2。
查看 CodePen 上 virgilspruit (@Virgilspruit) 编写的 分块 HTML5 视频 - 演示 3。