LeafletJS動画付きマーカー


8

leaflet.animatedmarkerGitHub のfrom openplans を使用して、線に沿って移動するマーカーを作成しました。また、ラインの上にポップアップするビデオを追加しました。これは、マーカーを動かしてもうまくいきます。

私ができることは、ビデオとマーカーを同時に開始および一時停止できるボタンを用意することです。また、ビデオとライン上のマーカーを前後に移動できるという追加の利点も必要です。私はこれが可能かどうか疑問に思っています、そして私はそれについてどうしたらいいですか?


3
コード(またはコード、ウェブサイト、jsfiddleへのリンク)を投稿すると、質問への注目が高まる可能性があります
sfletche

これは似ています。mapbox.com/blog/gopro-video-maps
gomapping

回答:


6

の基本的なコードを記述しましたがL.animatedMarker、詳細については後で詳しく説明します。Viboxのイベントについて説明しているStackExchangeの投稿で、Mapbox GoProチュートリアルJSFiddleなどの外部参照を使用しました。

次のJSFiddleで私の結果を確認できます:http ://jsfiddle.net/GFarkas/4mo8e9da/ 。残念ながら、「ビデオとライン上のマーカーで前後に移動できるという追加の利点」をテストすることはできません。ただし、ローカルでホストされているサイトでテストできます。

コードの最初の9行で、Leafletを使用して基本的なMapboxマップを設定しました。中心と定義済みのズームレベルがあります。その後、行638にスキップできます。その長いコードは、コピー貼り付けされたGeoJSONコードにすぎません。

コードの次の部分では、GeoJSONラインを単純なラインフィーチャとしてマップにレンダリングします。

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

次のパートでは、GeoJSON形式がlon / lat座標順序を使用するため、GeoJSON配列から座標を抽出し、lan / lot値を切り替える必要がありました。このタスクにはループを使用しました。

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

正しく配列された座標の配列を取得したので、ポリラインフィーチャを作成することができましたL.animatedMarker。これは、私の知る限りでは有効な唯一の入力です。

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

distanceおよびintervalオプションは、ライン上のマーカーの速度を定義します。あなたはそれを微調整する必要があるので、あなたのビデオはあなたのマーカーと同時に終了します。また、autoStartオプションをに設定する必要falseがあったので、後でビデオからマーカーを開始できます。

これからは、「魔法」の部分です。ビデオとマーカーを同時に制御したい場合は、Leaflet以外にお気に入りのサイトのAPIを使用する必要があります。この例では、VimeoのFroogaloopフレームワークを使用しました。YouTubeから動画を埋め込む場合は、このタスクにAPIを使用する方法を調べる必要があります。次のステップでは、L.popupレイヤーを追加してマーカーに結合しました。

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

このオブジェクトで最も重要なオプションはコンテンツです。iframeタグにIDを追加し、それを動画のリンクにも含める必要があります&player_id=player1。また、でVimeoのAPIを使用するためのリクエストを含める必要があります&api=1

サンプルコードを使用して、ビデオのイベントリスナーを記述しました。サンプルコードではJQueryを使用したので、コードのカスタマイズされた部分についてのみ詳しく説明します。

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

ビデオから4つのイベントが必要です。一時停止しているか(pause)、終了しているか(finish)、再生中か()、playまたはビデオにジャンプしたか()を確認する必要がありseekます。注意:playProgressイベントをにバインドしanimatedMarker.start()ないでください。マーカーが制御不能に加速します。次に、イベントに適切な関数を作成します。

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

最初の3つのイベントは、ビデオが開始または停止されている場合、ライン上のマーカーを開始または停止する関数を返します。4番目のイベントは少し異なります。ビデオと一緒にマップ上のマーカーを移動するには、式を使用して、マップ上のマーカーの新しい場所を設定する必要があります。変数が呼び出されたmarker._i場合、マーカーの現在の場所(ポリラインの頂点)が属性に格納されます。幸いなことにL.animatedMarkermarkerseekイベントは、ビデオの再生時間、位置、再生されたパーセンテージ(0〜1のスケール)を持つオブジェクトを返します。頂点の数にビデオの必要なパーセンテージを掛けた値に最も近い頂点を返し、それを最も近い整数に丸めると、ビデオの必要な瞬間におけるライン上のマーカーの位置が適切な近似値で取得されます。マーカーの移動時間をビデオと同じくらい長くし、多くのポイントを操作することで、この方法の精度を最適化できます(もちろん、頂点が線上に均等に分布している場合にのみ正常に機能します)。

この答えが私の悪い英語を助けてすみません。

更新:

動画が一時停止したときにマーカーが指示に追従するようにしたい場合は、を使用できませんL.animatedMarker.update()。あなたは使用する必要がありますL.animatedMarker.start()し、L.animatedMarker.stop()頂点を飛び越えるためにマーカーを引き起こすであろう。残念ながら、これによりアニメーションの精度が低下しますが、これはインタラクティブなマップに支払う必要のある代金です(作成者がL.animatedMarker.update()関数を修正するまで)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.