Marqueur animé LeafletJS avec vidéo

8

J'ai utilisé les leaflet.animatedmarkerplans ouverts de GitHub pour créer un marqueur qui se déplace le long d'une ligne. J'ai également ajouté une vidéo qui apparaîtra au-dessus de la ligne. Cela fonctionne bien lorsque le marqueur bouge.

Ce que je veux pouvoir faire, c'est avoir un bouton qui puisse démarrer et mettre en pause la vidéo et le marqueur en même temps. J'aimerais également avoir l'avantage supplémentaire de pouvoir avancer et reculer dans la vidéo et le marqueur sur la ligne. Je me demande simplement si cela est possible et comment je pourrais m'y prendre?

user3579273
la source
3
publier votre code (ou un lien vers votre code, site Web ou jsfiddle) pourrait aider à attirer davantage l'attention sur votre question
sfletche
C'est pareil. mapbox.com/blog/gopro-video-maps
gomapping

Réponses:

6

Pendant que vous avez écrit le code de base de la L.animatedMarker, je vais le détailler pour poursuivre mes études. J'ai utilisé des références externes, comme le tutoriel Mapbox GoPro et un JSFiddle dans le post StackExchange décrivant les événements Vimeo.

Vous pouvez voir mon résultat sur le JSFiddle suivant: http://jsfiddle.net/GFarkas/4mo8e9da/ . Malheureusement, vous ne pouvez pas tester «l'avantage supplémentaire de pouvoir avancer et reculer dans la vidéo et le marqueur sur la ligne». Cependant, vous pouvez le tester sur un site hébergé local.

Sur les 9 premières lignes de code, vous configurez une carte Mapbox de base avec Leaflet. Il a un centre et un niveau de zoom prédéfini. À partir de là, vous pouvez passer à la ligne 638, ce code long n'est qu'un code GeoJSON copié-collé.

La partie suivante du code rend la ligne GeoJSON à la carte comme une entité linéaire simple.

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

Dans la partie suivante, j'ai dû extraire les coordonnées du tableau GeoJSON et changer les valeurs lan / lot, car le format GeoJSON utilise l'ordre des coordonnées lon / lat. J'ai utilisé une boucle pour cette tâche.

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

Maintenant que j'avais un tableau de coordonnées correctement ordonné, j'aurais pu créer une entité polyligne, qui est la seule entrée valide L.animatedMarkerpour autant que je sache.

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

Les options distanceet intervaldéfinissent la vitesse du marqueur sur la ligne. Vous devez le régler avec précision, afin que votre vidéo se termine en même temps que votre marqueur. J'ai également dû définir l' autoStartoption sur false, afin que plus tard, je puisse démarrer le marqueur avec la vidéo.

A partir de maintenant, voici la partie "magique". Si vous souhaitez contrôler simultanément votre vidéo et votre marqueur, vous devez utiliser l'API de votre site préféré en plus de Leaflet. Dans cet exemple, j'ai utilisé le framework Froogaloop de Vimeo. Si vous souhaitez intégrer une vidéo à partir de YouTube, vous devez rechercher comment utiliser son API pour cette tâche. Dans l'étape suivante, j'ai ajouté le L.popupcalque et le coller sur le marqueur.

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

L'option la plus importante dans cet objet est le contenu. Vous devez ajouter un identifiant à la iframebalise et l'inclure dans le lien de la vidéo, également en tant que demande avec &player_id=player1. Vous devez également inclure une demande d'utilisation de l'API de Vimeo avec &api=1.

J'ai utilisé un exemple de code pour écrire les écouteurs d'événements pour les vidéos. L'exemple de code utilisé JQuery, moi aussi et je ne détaillerai que la partie personnalisée du code.

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

Nous aurons besoin de quatre événements de la vidéo. Nous devons savoir s'il est en pause ( pause), s'il est terminé ( finish), s'il est en cours de lecture ( play) ou si nous avons sauté dans la vidéo ( seek). Attention: n'utilisez pas l' playProgressévénement pour le lier animatedMarker.start(), cela entraînera une accélération incontrôlable du marqueur. Maintenant, pour créer les fonctions appropriées pour les événements.

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

Les trois premiers événements renverront une fonction pour démarrer ou arrêter le marqueur sur la ligne si la vidéo a été démarrée ou arrêtée. Le quatrième événement est un peu différent. Pour déplacer le marqueur sur la carte avec la vidéo, nous devons utiliser une formule pour définir le nouvel emplacement du marqueur sur la carte. La position actuelle du marqueur (sommet dans la polyligne) est stockée dans l' marker._iattribut si la L.animatedMarkervariable de votre est appelée marker. Heureusement,seekL'événement renvoie un objet avec la durée, la position et le pourcentage de lecture de la vidéo (sur une échelle comprise entre 0 et 1). Si nous renvoyons le sommet le plus proche du nombre de sommets multiplié par le pourcentage souhaité de la vidéo et l'arrondissons à l'entier le plus proche, nous obtenons la position du marqueur sur la ligne au moment souhaité de la vidéo avec une bonne approximation. Vous pouvez optimiser la précision de cette méthode en rendant la durée du mouvement du marqueur aussi longue que la vidéo et en travaillant avec de nombreux points (bien sûr, cela ne fonctionne bien que si les sommets sont également répartis sur la ligne).

J'espère que cette réponse vous aidera et désolé pour mon mauvais anglais.

MISE À JOUR:

Si vous souhaitez que votre marqueur suive vos instructions lorsque la vidéo est en pause, vous ne pourrez pas l'utiliser L.animatedMarker.update(). Vous devez utiliser L.animatedMarker.start()et L.animatedMarker.stop()qui fera sauter le marqueur sur un sommet. Malheureusement, cela réduira la précision de l'animation, mais c'est le prix à payer pour une carte interactive (jusqu'à ce que les auteurs corrigent la L.animatedMarker.update()fonction).

Gabor Farkas
la source