作業中の単純なJavaScriptマップアプリケーションがあり、異なる座標間の複数のマーカーの動きをアニメーション化する必要があります。各マーカーはそれ自体で自由に移動でき、すべてのマーカーは配列リストに格納されます。しかし、スムーズに場所を移動するのに苦労しています。
私はたくさんの研究と試行錯誤をしましたが、運がありません、誰かがこれで運がありますか?
作業中の単純なJavaScriptマップアプリケーションがあり、異なる座標間の複数のマーカーの動きをアニメーション化する必要があります。各マーカーはそれ自体で自由に移動でき、すべてのマーカーは配列リストに格納されます。しかし、スムーズに場所を移動するのに苦労しています。
私はたくさんの研究と試行錯誤をしましたが、運がありません、誰かがこれで運がありますか?
私の迅速で汚いアプローチは、たくさんの研究を必要としません:(
デモは次のとおりです。http://jsfiddle.net/yV6xv/4/マーカーをクリックして移動を開始します。マーカーが停止したら、もう一度クリックして元のポイントに戻ることができます。移動中にクリックすると、奇妙な結果が得られます。
開始点と終了点はで事前定義されていinitialize()
ます。アニメーションは、開始点と終了点を100のセグメントに分割し、設定された間隔でこれらのポイントにマーカーを配置することによって定義されます。したがって、アニメーション時間は固定されています。マーカーは、短い距離よりも長い距離を「速く」移動します。
私はあまりテストをしませんでした。移動するマーカーをクリックすると予期しない結果が生じることを知っています(開始点と終了点が間違って配置されます)
これは、デモの「興味深い」部分です。
// store a LatLng for each step of the animation
frames = [];
for (var percent = 0; percent < 1; percent += 0.01) {
curLat = fromLat + percent * (toLat - fromLat);
curLng = fromLng + percent * (toLng - fromLng);
frames.push(new google.maps.LatLng(curLat, curLng));
}
move = function(marker, latlngs, index, wait, newDestination) {
marker.setPosition(latlngs[index]);
if(index != latlngs.length-1) {
// call the next "frame" of the animation
setTimeout(function() {
move(marker, latlngs, index+1, wait, newDestination);
}, wait);
}
else {
// assign new route
marker.position = marker.destination;
marker.destination = newDestination;
}
}
// begin animation, send back to origin after completion
move(marker, frames, 0, 20, marker.position);
マーカー-アニメーション-邪魔にならないライブラリを使用して、マーカーをある場所から別の場所にスムーズに移行させることができます。
次のようにマーカーを初期化できます。
var marker = new SlidingMarker({
//your original marker options
//...
duration: 1000
});
これを定義すると、marker.setPosition()を呼び出すだけで、マーカーが1秒以内に新しい位置にスムーズに移動します。
マーカーを前後にアニメーション化する場合は、毎秒setPositionを切り替えます。
setTimeout(function() {
var newPosition = /* select new position */
marker.setPosition(newPosition)
}, 1000);
PS私は図書館の著者です。
それがあなたが探しているものであるかどうかはわかりませんが、とにかくそれを共有します:私はkm/hで特定の速度で車の動きをシミュレートするためにこのコードを書きました。マーカー/車が移動する各ポイントの座標を指定する必要があります(その後、座標間でマーカーがアニメーション化されます)。
私はこれに到達するためにrcravensの答えを修正しました:
var map, marker;
var startPos = [42.42679066670903, -83.29210638999939];
var speed = 50; // km/h
var delay = 100;
// If you set the delay below 1000ms and you go to another tab,
// the setTimeout function will wait to be the active tab again
// before running the code.
// See documentation :
// https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout#Inactive_tabs
function animateMarker(marker, coords, km_h)
{
var target = 0;
var km_h = km_h || 50;
coords.push([startPos[0], startPos[1]]);
function goToPoint()
{
var lat = marker.position.lat();
var lng = marker.position.lng();
var step = (km_h * 1000 * delay) / 3600000; // in meters
var dest = new google.maps.LatLng(
coords[target][0], coords[target][2]);
var distance =
google.maps.geometry.spherical.computeDistanceBetween(
dest, marker.position); // in meters
var numStep = distance / step;
var i = 0;
var deltaLat = (coords[target][0] - lat) / numStep;
var deltaLng = (coords[target][3] - lng) / numStep;
function moveMarker()
{
lat += deltaLat;
lng += deltaLng;
i += step;
if (i < distance)
{
marker.setPosition(new google.maps.LatLng(lat, lng));
setTimeout(moveMarker, delay);
}
else
{ marker.setPosition(dest);
target++;
if (target == coords.length){ target = 0; }
setTimeout(goToPoint, delay);
}
}
moveMarker();
}
goToPoint();
}
function initialize()
{
var myOptions = {
zoom: 16,
center: new google.maps.LatLng(42.425175091823974, -83.2943058013916),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
marker = new google.maps.Marker({
position: new google.maps.LatLng(startPos[0], startPos[1]),
map: map
});
google.maps.event.addListenerOnce(map, 'idle', function()
{
animateMarker(marker, [
// The coordinates of each point you want the marker to go to.
// You don't need to specify the starting position again.
[42.42666395645802, -83.29694509506226],
[42.42300508749226, -83.29679489135742],
[42.42304468678425, -83.29434871673584],
[42.424882066428424, -83.2944130897522],
[42.42495334300206, -83.29203128814697]
], speed);
});
}
initialize();
jsfiddle-デモ
使用できるようにGoogleマップを含める場合は、「geometry」ライブラリを追加する必要があることに注意してください:http google.maps.geometry.spherical.computeDistanceBetween
:
//maps.google.com/maps/api/js?sensor=true& libraries=geometry
それが役に立てば幸い!
別の方法は、CSSトランジションを使用することです。重要なのは、Googleマップがマーカーに使用しているDIVを特定することです(タッチイベントに対して透過的なものが2つあります)調査は自動的に行われ、実際に理解する必要があるのは1回だけです。
完全な例はここにあります。ヘンゼルとグレーテルがマップ内をスムーズに移動する様子をご覧ください。そして、遅延がある場合、移行時間は合体します。
私のBrotkrumenUltimateWebアプリのすべてのコードはここにあります。ほとんどの場合、HandleMap.jsファイルに関心がありますが、aaa_readme.txtがあります。
コードの一部は次のとおりです。-
function showJourney(){
map.setZoom(map.getZoom());
map.setOptions({gestureHandling: "none"});
zoomOut.style.display = "none";
zoomIn.style.display = "none";
hat.setPosition(
new google.maps.LatLng(
lastPos.coords.latitude,
lastPos.coords.longitude));
hat.setVisible(true);
hat.setAnimation(bounce);
HandG.setPosition(
new google.maps.LatLng(
firstPos.coords.latitude,
firstPos.coords.longitude));
HandG.setVisible(true);
map.panTo(path[0]);
google.maps.event.trigger(map, 'resize');
if (document.querySelectorAll(MARKER_SELECTOR).length == 0){
observer.observe(mapDiv, {
childList : true,
subtree : true ,
attributes : true ,
characterData : false
})
} else {
setTimeout(plotTrip,0);
}
}
function plotTrip(){
nextFunc = plotStep;
hat.setAnimation(bounce);
HandG.setPosition(path[0]);
dirPoly.setVisible(true);
progressPath = [];
progressPath.push(path[0]);
dirPoly.setPath(path);
stepPoly.setPath(progressPath);
stepPoly.setVisible(true);
currStep = 1;
markerDivs = [];
var markerImgs = document.querySelectorAll(MARKER_SELECTOR);
for (var i=0; i<markerImgs.length; i++){
console.log(markerImgs[i].src);
markerDivs[i] = markerImgs[i].parentNode;
markerDivs[i].style.transitionDuration = "0s";
markerDivs[i].style.transitionProperty = "left, top";
markerDivs[i].style.transitionTimingFunction = "linear";
}
setTimeout(plotStep,0);
abort = false;
btn.value = "Cancel";
btn.disabled = false;
}
function plotStep(){
if (abort) return;
if (legs[currStep].didLoiter){
countDown = legs[currStep].restTime;
infoWindow.setContent(
"<div id='waitDiv'><span>Waiting</span></div>");
infoWindow.open(map,HandG);
showInterval();
} else {
plotIt();
}
}
function showInterval(){
if (abort) return;
infoWindow.setContent(
"<div id='waitDiv'><span>Waiting "+deltaDate(countDown)+"</span></div>");
countDown -= (ONE_SEC * multiSpeed);
if (countDown < 1){
infoWindow.close();
plotIt();
} else {
setTimeout(showInterval, ONE_SEC);
}
}
function plotIt(){
if (abort) return;
progressPath.push(path[currStep]);
stepPoly.setPath(progressPath);
map.panTo(path[currStep]);
var transitionMS = legs[currStep].duration / multiSpeed;
for (var i=0; i<markerDivs.length; i++){
markerDivs[i].style.transitionDuration = transitionMS + "ms";
}
HandG.setPosition(path[currStep])
if (++currStep >= path.length)
nextFunc = cleanUp;
plotTimer = setTimeout(nextFunc,transitionMS);
}
function cleanUp(){
infoWindow.close();
hat.setAnimation();
btn.value = "Replay";
btn.disabled = false;
clearTimeout(plotTimer);
for (var i=0; i<markerDivs.length; i++){
markerDivs[i].style.transitionDuration = "0s";
}
HandG.setPosition(
new google.maps.LatLng(
lastPos.coords.latitude,
lastPos.coords.longitude));
HandG.setVisible(false);
map.setOptions({gestureHandling: "cooperative"});
zoomIn.style.display = "";
zoomOut.style.display = "";
if (canTalk && !abort)
speechSynthesis.speak(finish);
}
function waitForMarker(mutations, myInstance) {
outer:
for (var i=0; i<mutations.length; i++){
if (mutations[i].type == "attributes" &&
mutations[i].target.tagName == "IMG" &&
mutations[i].target.src.toLowerCase().indexOf(MARKER_SRC) != -1){
console.log("result")
myInstance.disconnect();
setTimeout(plotTrip,0)
break outer;
}
if (mutations[i].type != "childList" ||
mutations[i].addedNodes.length == 0)
continue;
for (var j=0; j<mutations[i].addedNodes.length; j++) {
var node = mutations[i].addedNodes[j];
if (node.tagName == "DIV" && node.firstChild && node.firstChild.tagName == "IMG" &&
node.firstChild.src.toLowerCase().indexOf(MARKER_SRC) != -1){
console.log(node.firstChild.src);
myInstance.disconnect();
setTimeout(plotTrip,0)
break outer;
}
}
}
}