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
- Das Videoelement ausblenden
- Erstellen Sie ein Canvas-Element, dessen Höhe/Breite mit dem Video-Element übereinstimmt, und speichern Sie es irgendwo
- Holen Sie sich den Kontext des Canvas-Elements mit `canvas.getContext('2d') und speichern Sie diesen ebenfalls irgendwo
- Erstellen einer Zeichenfunktion
- In dieser Zeichenfunktion würden Sie Folgendes verwenden
canvas.drawImage(src, x, y)
wobei src
ist die bearbeitete Version des aktuellen Frames des Videos;
- 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">