LeafletJS animierter Marker mit Video

8

Ich habe die leaflet.animatedmarkerfrom openplans auf GitHub verwendet, um einen Marker zu erstellen, der sich entlang einer Linie bewegt. Ich habe auch ein Video hinzugefügt, das über der Zeile angezeigt wird. Dies spielt gut, wenn sich der Marker bewegt.

Ich möchte in der Lage sein, eine Schaltfläche zu haben, mit der das Video und der Marker gleichzeitig gestartet und angehalten werden können. Ich möchte auch den zusätzlichen Vorteil, dass ich mich im Video und im Marker auf der Linie vor und zurück bewegen kann. Ich frage mich nur, ob dies möglich ist und wie ich vorgehen könnte.

user3579273
quelle
3
Das Posten Ihres Codes (oder eines Links zu Ihrem Code, Ihrer Website oder Ihrer jsfiddle) könnte dazu beitragen, mehr Aufmerksamkeit auf Ihre Frage zu
lenken
Das ist ähnlich. mapbox.com/blog/gopro-video-maps
Gomapping

Antworten:

6

Während Sie den Basiscode für das geschrieben haben L.animatedMarker, werde ich ihn für die weitere Ausbildung detailliert beschreiben. Ich habe einige externe Referenzen verwendet, wie das Mapbox GoPro-Tutorial und eine JSFiddle im StackExchange- Beitrag, in dem Vimeo-Ereignisse beschrieben werden.

Sie können mein Ergebnis auf der folgenden JSFiddle sehen: http://jsfiddle.net/GFarkas/4mo8e9da/ . Leider können Sie den "zusätzlichen Vorteil, sich im Video und in der Markierung auf der Linie vorwärts und rückwärts bewegen zu können" nicht testen. Sie können es jedoch auf einer lokal gehosteten Site testen.

In der ersten 9 Codezeile richten Sie eine grundlegende Mapbox-Karte mit Leaflet ein. Es hat eine Mitte und eine vordefinierte Zoomstufe. Von da an können Sie zur Zeile 638 springen. Dieser lange Code ist nur ein kopierter GeoJSON-Code.

Im nächsten Teil des Codes wird die GeoJSON-Linie als einfache Linienfunktion auf der Karte dargestellt.

var line = L.geoJson(ride, {
    style: {
        weight: 7,
        opacity: 1,
        color: '#0d8709',
        opacity: 0.7
    }
});

Im nächsten Teil musste ich die Koordinaten aus dem GeoJSON-Array extrahieren und die LAN / Lot-Werte wechseln, da das GeoJSON-Format die Lon / Lat-Koordinatenreihenfolge verwendet. Ich habe für diese Aufgabe eine Schleife verwendet.

var raw = [];

for (var i = 0; i < ride.features[0].geometry.coordinates.length; i++) {
    var tmp = [];
    tmp[0] = ride.features[0].geometry.coordinates[i][1];
    tmp[1] = ride.features[0].geometry.coordinates[i][0];
    raw.push(tmp);
}

Nachdem ich ein korrekt geordnetes Koordinatenarray hatte, hätte ich ein Polylinien-Feature erstellen können, das meines Wissens die einzig gültige Eingabe ist L.animatedMarker.

var coords = L.polyline(raw),
    animatedMarker = L.animatedMarker(coords.getLatLngs(), {
        distance: 100,
        interval: 2500,
        autoStart: false
});

Die Optionen distanceund intervaldefinieren die Geschwindigkeit der Markierung auf der Linie. Sie müssen es fein abstimmen, damit Ihr Video gleichzeitig mit Ihrem Marker endet. Ich musste auch die autoStartOption auf setzen false, damit ich später den Marker mit dem Video starten kann.

Von nun an kommt hier der "magische" Teil. Wenn Sie gleichzeitig die Kontrolle über Ihr Video und Ihren Marker haben möchten, müssen Sie neben Leaflet auch die API Ihrer Lieblingsseite verwenden. In diesem Beispiel habe ich das Froogaloop-Framework von Vimeo verwendet. Wenn Sie ein Video von YouTube einbetten möchten, müssen Sie nachschlagen, wie Sie die API für diese Aufgabe verwenden können. Im nächsten Schritt habe ich die L.popupEbene hinzugefügt und sie mit dem Marker verbunden.

var popup = L.popup({
    keepInView: false,
    autoPan: false,
    closeButton: false,
    closeOnClick: false,
    maxWidth: 1000
}).setContent('<iframe id="player1" src="https://player.vimeo.com/video/69426498?title=0&amp;byline=0&amp;portrait=0&amp;autoplay=0&amp;api=1&amp;player_id=player1" width="200" height="150" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>');

animatedMarker.bindPopup(popup).openPopup();

Die wichtigste Option in diesem Objekt ist der Inhalt. Sie müssen dem iframeTag eine ID hinzufügen und diese auch als Anfrage mit in den Link des Videos aufnehmen &player_id=player1. Sie müssen auch eine Anfrage zur Verwendung der Vimeo-API mit einschließen &api=1.

Ich habe einen Beispielcode verwendet, um die Ereignis-Listener für die Videos zu schreiben. Der Beispielcode verwendete JQuery, daher werden ich und ich nur den benutzerdefinierten Teil des Codes detailliert beschreiben.

player.addEvent('ready', function() {
    player.addEvent('pause', onPause);
    player.addEvent('finish', onFinish);
    player.addEvent('play', onPlay);
    player.addEvent('seek', onSeek);
});

Wir brauchen vier Events aus dem Video. Wir müssen wissen, ob es angehalten ist ( pause), ob es fertig ist ( finish), ob es abgespielt wird ( play) oder ob wir in das Video gesprungen sind ( seek). Achtung: Verwenden Sie das playProgressEreignis nicht zum Binden animatedMarker.start(), da sich der Marker sonst unkontrolliert beschleunigt. Nun erstellen Sie die richtigen Funktionen für die Ereignisse.

function onPause(id) {
    animatedMarker.stop();
}

function onFinish(id) {
    animatedMarker.stop();
}

function onPlay(id) {
    animatedMarker.start();
}

function onSeek(data, id) {
    animatedMarker._i = Math.round(data.percent*raw.length);
}

Die ersten drei Ereignisse geben eine Funktion zum Starten oder Stoppen der Markierung in der Zeile zurück, wenn das Video gestartet oder gestoppt wurde. Die vierte Veranstaltung ist etwas anders. Um die Markierung auf der Karte mit dem Video zu verschieben, müssen wir eine Formel verwenden, um die neue Position der Markierung auf der Karte festzulegen. Die aktuelle Position des Markers (Scheitelpunkt in der Polylinie) wird im marker._iAttribut gespeichert , wenn die L.animatedMarkerVariable Ihrer Marke aufgerufen wird marker. Zum Glück dieseekDas Ereignis gibt ein Objekt mit der Dauer, Position und dem Prozentsatz der Wiedergabe des Videos zurück (auf einer Skala zwischen 0 und 1). Wenn wir den Scheitelpunkt zurückgeben, der der Anzahl der Scheitelpunkte multipliziert mit dem gewünschten Prozentsatz des Videos am nächsten liegt, und ihn auf die nächste Ganzzahl runden, erhalten wir die Position des Markers auf der Linie im gewünschten Moment des Videos mit einer guten Annäherung. Sie können die Genauigkeit dieser Methode optimieren, indem Sie die Bewegungsdauer des Markers so lang wie das Video machen und mit vielen Punkten arbeiten (natürlich funktioniert dies nur, wenn die Scheitelpunkte gleichmäßig auf der Linie verteilt sind).

Ich hoffe, diese Antwort hilft und entschuldige mein schlechtes Englisch.

AKTUALISIEREN:

Wenn Sie möchten, dass Ihr Marker Ihren Anweisungen folgt, wenn das Video angehalten wird, können Sie ihn nicht verwenden L.animatedMarker.update(). Sie müssen verwenden L.animatedMarker.start()und L.animatedMarker.stop()was bewirkt, dass der Marker über einen Scheitelpunkt springt. Leider verringert dies die Genauigkeit der Animation, aber dies ist der Preis, den Sie für eine interaktive Karte zahlen müssen (bis die Autoren die L.animatedMarker.update()Funktion korrigieren ).

Gabor Farkas
quelle