Fragmented HTML5 Video

Avatar of Virgil Spruit
Virgil Spruit am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Ich habe verschiedene Implementierungen des Voronoi-Diagramms gesehen. Vielleicht haben Sie eines gesehen, ohne zu wissen, was es ist. Es sieht fast aus wie zufälliges Buntglas

Wikipedia

In der Mathematik ist ein Voronoi-Diagramm eine Unterteilung einer Ebene in Regionen, die auf der Entfernung zu Punkten in einer bestimmten Teilmenge der Ebene basiert.

Man kann sogar ein Voronoi-Diagramm von Hand erstellen, wie es eLVirus88 dokumentiert hat.

Ich wollte es ausprobieren.

Die Idee

Meine Idee ist, ein Video in fragmentierte Teile (Zellen genannt) zu zerlegen und sie in den 3D-Raum auf einer leicht unterschiedlichen Z-Achse zu platzieren. Dann würde durch die Mausbewegung das gesamte Erlebnis gedreht, sodass man die Zellen in unterschiedlichen Tiefen sieht.

The Code

Aufbauend auf Raymond Hills und Larix Kortbeeks JavaScript-Implementierung, war das erste, was ich tun musste, die Zellen aufzuteilen.

Ich habe mich für das <canvas>-Element entschieden und jede der Zellen auf einer anderen Leinwand auf einer anderen 3D-Ebene durch CSS platziert.

Die Voronoi-Bibliothek kümmert sich um die Berechnung aller Standorte zu Zellen und die Erstellung von Objekten mit den Scheitelpunkten und Kanten, mit denen wir arbeiten können.

Zellen zu Leinwänden

Zuerst erstellen wir die Leinwände entsprechend der Anzahl der Voronoi-Zellen. Diese werden im DOM gerendert. Die Leinwände und ihre jeweiligen Kontexte werden in einem Array gespeichert.

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'));

Maskierung

Alle Leinwände sind nun eine Kopie des Videos.

Der gewünschte Effekt ist, eine Zelle pro Leinwand anzuzeigen. Die Voronoi-Bibliothek stellt uns eine compute-Funktion zur Verfügung. Wenn wir die Standorte mit den Grenzen angeben, erhalten wir ein detailliertes Objekt, aus dem wir alle Kanten der Zellen extrahieren. Diese werden verwendet, um mit dem globalCompositeOperation einen Ausschnitt für jeden Bereich zu erstellen.

// 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();

Hinzufügen von Video

Das Anzeigen von Video auf der Leinwand erfordert nur wenige Codezeilen. Dies wird bei requestAnimationFrame ausgeführt.

v = document.getElementById('video');
ctx.drawImage(v,0,0,960,540);

Es ist auch möglich, eine Video-Eingangsquelle (wie eine Webcam) zu verwenden, aber das Ergebnis hat mir für diese Demo nicht so gut gefallen. Wenn Sie wissen möchten, wie Sie die Webcam zum Zeichnen auf Leinwand mit der getUserMedia()-Methode verwenden können, können Sie hier mehr darüber erfahren.

Um die Leistung beim Zeichnen von Videos zu optimieren, überspringen Sie einige Frames zwischen den requestAnimationFrame-Aufrufen. Videos für das Web sind normalerweise mit einer Bildrate von nicht mehr als 30 fps kodiert.

Siehe den Pen Fragmentiertes HTML5-Video – Demo 1 von virgilspruit (@Virgilspruit) auf CodePen.

Fazit

Demos wie diese sind meine Lieblingsbeschäftigung. Zu sehen, was es da draußen gibt, und seine eigene Ebene der Interaktivität hinzuzufügen. Ich freue mich darauf zu sehen, was andere Leute mit diesem schönen visuellen Algorithmus machen werden.

Siehe den Pen Fragmentiertes HTML5-Video – Demo 2 von virgilspruit (@Virgilspruit) auf CodePen.

Siehe den Pen Fragmentiertes HTML5-Video – Demo 3 von virgilspruit (@Virgilspruit) auf CodePen.

Demos anzeigen GitHub Repo