Marcador animado LeafletJS com vídeo


8

Eu usei o leaflet.animatedmarkerde openplans no GitHub para criar um marcador que se move ao longo de uma linha. Também adicionei um vídeo que aparecerá acima da linha. Isso funciona bem com o marcador em movimento.

O que eu quero fazer é ter um botão capaz de iniciar e pausar o vídeo e o marcador ao mesmo tempo. Eu também gostaria do benefício adicional de poder recuar e avançar no vídeo e no marcador na linha. Eu só estou me perguntando se isso é possível, e como eu posso fazer isso?


3
postando seu código (ou um link para o seu código, site ou jsFiddle) pode ajudar a obter mais atenção à sua pergunta
sfletche

Respostas:


6

Enquanto você tiver escrito o código básico para o L.animatedMarker, detalharei-o para obter mais educação. Eu usei algumas referências externas, como o tutorial do Mapbox GoPro e um JSFiddle na postagem StackExchange que descreve os eventos do Vimeo.

Você pode ver meu resultado no JSFiddle a seguir: http://jsfiddle.net/GFarkas/4mo8e9da/ . Infelizmente, você não pode testar o "benefício adicional de poder recuar e avançar no vídeo e no marcador na linha". No entanto, você pode testá-lo em um site hospedado local.

Nas primeiras 9 linhas de código, você configurou um mapa básico do Mapbox com o Leaflet. Possui um centro e um nível de zoom predefinido. A partir daí, você pode pular para a linha 638, esse código longo é apenas um código GeoJSON copiado e colado.

A próxima parte do código renderiza a linha GeoJSON no mapa como um recurso simples de linha.

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

Na próxima parte, tive que extrair as coordenadas da matriz GeoJSON e mudar os valores de lan / lot, porque o formato GeoJSON usa a ordem de coordenadas long / lat. Eu usei um loop para esta tarefa.

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

Agora que eu tinha uma matriz de coordenadas ordenada corretamente, eu poderia criar um recurso de polilinha, que é a única entrada válida L.animatedMarkeraté onde eu sei.

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

As opções distancee intervaldefinem a velocidade do marcador na linha. Você precisa ajustá-lo para que seu vídeo termine ao mesmo tempo que o seu marcador. Eu também tive que definir a autoStartopção para false, depois poder iniciar o marcador com o vídeo.

A partir de agora, aqui vem a parte "mágica". Se você deseja ter controle sobre seu vídeo e seu marcador simultaneamente, use a API do seu site favorito além do Leaflet. Neste exemplo, usei a estrutura Froogaloop do Vimeo. Se você deseja incorporar um vídeo do YouTube, precisa procurar como pode usar sua API para esta tarefa. Na próxima etapa, adicionei a L.popupcamada e a colei no marcador.

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

A opção mais importante nesse objeto é o conteúdo. Você precisa adicionar um ID à iframetag e incluí-lo no link do vídeo, também como solicitação &player_id=player1. Você também precisa incluir uma solicitação para usar a API do Vimeo &api=1.

Usei um código de amostra para escrever os ouvintes do evento para os vídeos. O código de amostra usou o JQuery, assim como eu e eu detalharemos apenas a parte personalizada do código.

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

Vamos precisar de quatro eventos do vídeo. Temos que saber se está pausado ( pause), se está finalizado ( finish), se está sendo reproduzido ( play) ou se pulamos no vídeo ( seek). Cuidado: não use o playProgressevento para vinculá-lo animatedMarker.start(), pois o marcador será acelerado incontrolavelmente. Agora, para criar as funções apropriadas para os eventos.

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

Os três primeiros eventos retornarão uma função para iniciar ou parar o marcador na linha se o vídeo tiver sido iniciado ou parado. O quarto evento é um pouco diferente. Para mover o marcador no mapa com o vídeo, precisamos usar uma fórmula para configurar o novo local do marcador no mapa. O local atual do marcador (vértice na polilinha) é armazenado no marker._iatributo se a L.animatedMarkervariável da sua for chamada marker. Felizmente oseekO evento retorna um objeto com a duração, posição e porcentagem de reprodução do vídeo (em uma escala entre 0 e 1). Se retornarmos o vértice mais próximo ao número de vértices multiplicado pela porcentagem desejada do vídeo e arredondá-lo para o número inteiro mais próximo, obteremos a posição do marcador na linha no momento desejado do vídeo com uma boa aproximação. Você pode otimizar a precisão desse método aumentando a duração do movimento do marcador enquanto o vídeo e trabalhando com muitos pontos (é claro que só funciona bem se os vértices estiverem igualmente distribuídos na linha).

Espero que esta resposta ajude e desculpe pelo meu inglês ruim.

ATUALIZAR:

Se você deseja que seu marcador siga suas instruções quando o vídeo estiver em pausa, não será possível usá-lo L.animatedMarker.update(). Você precisa usar L.animatedMarker.start()e o L.animatedMarker.stop()que fará com que o marcador salte sobre um vértice. Infelizmente, isso reduzirá a precisão da animação, mas esse é o preço que você deve pagar por um mapa interativo (até que o (s) autor (es) conserte a L.animatedMarker.update()função).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.