5 Stimmen

Zeichnen von Formen auf HTML5 Canvas... mit Video

Ich habe ein bisschen gegoogelt, um eine Antwort zu finden, aber ich habe keine endgültige Antwort gefunden, so oder so: Ist es möglich, ein Video mit einer HTML5-Leinwand abzuspielen und dem Benutzer auch zu erlauben, auf diesem Video zu zeichnen? In einem bestimmten Kontext soll ein Video in einer Endlosschleife abgespielt werden, so dass der Benutzer mehrere Kästchen über bestimmte Bereiche ziehen kann, um Regionen von Interesse anzuzeigen.

Als Bonus (:P), wenn ich herausfinden kann, wie dies auf eigene Faust zu tun, irgendwelche Hinweise darauf, wie dies innerhalb Drupal getan werden könnte? Ich bin bereits an der Canvas-Feld-Modul suchen, aber wenn Sie irgendwelche Tipps zu diesem Punkt auch (obwohl die erste ist die Priorität), das wäre großartig!

4voto

Declan Cook Punkte 6052

Sie können HTML5-Videoelemente auf eine Leinwand zeichnen. Die drawImage-Methode akzeptiert ein Video-Element im ersten Parameter, genau wie ein Bild-Element. Sie nimmt das aktuelle "Bild" des Videoelements und rendert es auf die Leinwand. Um eine flüssige Wiedergabe des Videos zu erreichen, müssen Sie das Video wiederholt auf die Leinwand zeichnen.

Sie können dann ganz normal auf der Leinwand zeichnen, wobei Sie darauf achten, dass Sie nach jeder Aktualisierung des Videobildes alles neu zeichnen.

Hier ist eine Demo von Video auf Leinwand

Hier finden Sie einen ausführlichen Einblick in Video und die Leinwand

1voto

paceaux Punkte 1712

Kürzlich erhielt ich von einem Kunden die Anfrage, diese Funktion bereitzustellen, und sie muss CMS-freundlich sein. Die Technik umfasst drei große Ideen

  • eine Zeichenfunktion
  • wiederholter Aufruf der gleichen Zeichenfunktion
  • mit requestAnimationFrame um das nächste Bild zu malen

Wenn Sie bereits ein Videoelement haben, gehen Sie wie folgt vor

  1. Das Videoelement ausblenden
  2. Erstellen Sie ein Canvas-Element, dessen Höhe/Breite mit dem Video-Element übereinstimmt, und speichern Sie es irgendwo
  3. Holen Sie sich den Kontext des Canvas-Elements mit `canvas.getContext('2d') und speichern Sie diesen ebenfalls irgendwo
  4. Erstellen einer Zeichenfunktion
  5. In dieser Zeichenfunktion würden Sie Folgendes verwenden canvas.drawImage(src, x, y) wobei src ist die bearbeitete Version des aktuellen Frames des Videos;
  6. In dieser Zeichenfunktion wird die Rekursion verwendet, um sich selbst erneut aufzurufen

Ich kann Ihnen zwei Beispiele dafür geben, wie dies gemacht wird (und wie es für Content-Management-Systeme verwendet werden kann)

Die erste ist hier: https://jsfiddle.net/yywL381w/19/

Ein Unternehmen namens SDL stellt ein Tool namens Media Manager her, das Videos hostet. Was Sie sehen, ist ein jQuery-Plugin, das seine Parameter von einer data-* eine Anforderung von der Medienmanager-Rest-API, erstellt ein Video und fügt Effekte hinzu, die ausschließlich auf data* Attribute. Dieses Plugin kann leicht so angepasst werden, dass es auch mit Videos funktioniert, die aus anderen Quellen aufgerufen werden. Sie können sich die Repo für weitere Details zur Verwendung.

Ein weiteres Beispiel finden Sie hier: http://codepen.io/paceaux/pen/egLOeR

Dabei handelt es sich nicht um ein jQuery-Plugin, sondern um eine ES6-Klasse. Sie können damit ein Bild/Video erstellen und einen Zuschneideeffekt anwenden:

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

Sie werden feststellen, dass in der ImageCanvasModule Klasse, diese Methode:

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

Die Klasse hat eine zweite Leinwand erstellt, die zum Zeichnen verwendet wird. Diese Leinwand ist nicht sichtbar, sie ist nur dazu da, dem Browser etwas Herzschmerz zu ersparen.

Die "Manipulation", die inhaltlich handhabbar ist, ist this.imageFrames[this.module.dataset.imageFrame](this.backContext);

Der "Frame" ist ein Attribut, das auf dem Bild/Video gespeichert ist (das von einer Vorlage im CMS ausgegeben werden könnte). Dies erhält den Namen des imageFrame und führt ihn als passende Funktion aus. Es sendet auch in den Kontext (so kann ich zwischen Zeichnung auf der Rückseite Leinwand oder Haupt Leinwand umschalten, wenn nötig)

dann this.backContext.drawImage(this.media, x, y, width, this.canvas.height); zeichnet das Bild auf den hinteren Kontext.

Schließlich erscheint dies auf der Hauptleinwand mit this.context.drawImage(this.backCanvas, 0, 0); wo ich die Hintergrundleinwand nehme und sie auf die Hauptleinwand zeichne. So hat die sichtbare Leinwand die geringstmögliche Anzahl von Manipulationen.

Und da es sich um ein Video handelt, wollen wir am Ende ein neues Bild zeichnen. Wir haben also die Funktion selbst aufgerufen:

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

Diese ganze Einrichtung ermöglicht es uns, das CMS zur Ausgabe von data-* Attribute, die die Art des Rahmens enthalten, der um das Bild herum gezeichnet werden soll. Das JavaScript erzeugt dann eine auf die Leinwand vergrößerte Version des Bildes oder Videos. Das Markup-Beispiel könnte wie folgt aussehen:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X