web-dev-qa-db-fra.com

Faites rebondir une épingle dans Google Maps une fois

Je veux faire rebondir une épingle sur une carte Google une fois. Le code suivant fera rebondir le marqueur mais il continue à aller de l'avant ...

myPin.setAnimation(google.maps.Animation.BOUNCE);

Puis en appelant 

myPin.setAnimation(null);

arrête l'animation. La définition d'un délai d'attente fonctionne, mais la durée d'un rebond ne ressemble pas à un nombre rond.

  setTimeout(function(){ myPin.setAnimation(null); }, 1000);

Faites que l’animation de rebond se termine prématurément et ait un aspect terrible.

Est-ce que quelqu'un connaît un meilleur moyen d'accomplir cela?

25
Patrick Arlt

Un peu d’une approche simple: L’animation de rebond de Google semble prendre exactement 750 ms pour un cycle. Ainsi, il suffit de définir le délai d’attente sur 750 ms et l’animation s’arrêtera exactement à la fin du premier rebond. Fonctionne pour moi sur FF 7, Chrome 14 et IE 8:

    marker.setAnimation(google.maps.Animation.BOUNCE);
    setTimeout(function(){ marker.setAnimation(null); }, 750);
30
Simon Steinberger

D'accord, aucune des autres réponses n'a assez bien fonctionné compte tenu des limites de l'API. Alors voici ce que j'ai trouvé.

  • Chaque rebond correspond à environ 700 ms à partir de la version js?v=3.13 de Google Maps.
  • L'appel de marker.setAnimation(null) empêche le marqueur de rebondir uniquement après avoir terminé le rebond en cours. Ainsi, si vous attendez que 710ms aient expiré dans la séquence de rebond et que vous définissiez ensuite marker.setAnimation(null), l'API continuera à effectuer un rebond supplémentaire sans interrompre sa séquence de rebond actuelle. 
  • Cependant, si vous appelez immédiatement à nouveau setAnimation(700) sur ce même marqueur , cela interrompra la séquence de rebonds en cours. Pas vraiment jolie.
  • Notez également que si vous décorez le marqueur avec une superposition quelconque, il ne renverra pas ces éléments car ils ne sont pas attachés au marqueur.

Cas simple (comme on le voit dans les autres réponses):

marker.setAnimation(google.maps.Animation.BOUNCE);
setTimeout(function () {
    marker.setAnimation(null);
}, 700); // current maps duration of one bounce (v3.13)

En admettant que:

  1. le rebond se produit à partir de l'interaction de l'utilisateur
  2. et vous ne voulez pas tronquer une séquence de rebonds en cours lorsque l'utilisateur en déclenche une autre sur le même objet
  3. et vous ne voulez pas ignorer cette requête pour effectuer une autre séquence de rebond,

vous pouvez utiliser setTimout en conjonction avec la méthode .queue de jquery pour empêcher une nouvelle demande de rebond d'interrompre la requête actuelle, tout en la mettant en file d'attente pour exécuter la séquence de rebond après la requête en cours est terminée. (note: j'ai utilisé deux rebonds au lieu d'un, donc msec est réglé sur 1400).

cas plus réaliste:

// bounce markers on hover of img
$('#myImage').hover(function () {
    // mouseenter
    var marker = goGetMarker();
    function bounceMarker()
    {
        marker.setAnimation(google.maps.Animation.BOUNCE);
        setTimeout(function ()
        {
            marker.setAnimation(null);
            $(marker).dequeue();
        }, 1400); // timeout value lets marker bounce twice before deactivating
    }

    // use jquery queue
    if ($(marker).queue().length <= 1) // I'm only queuing up 1 extra bounce
        $(marker).queue(bounceMarker);
}, function () {
    // mouseleave
    var marker = goGetMarker();
    marker.setAnimation(null);
});
6
johntrepreneur

utilisez ce code:

animation:google.maps.Animation.DROP
5
Saeed sdns

C’est une question difficile qui n’a pas encore de réponse parfaite car, bien que 750 ms fonctionne bien pour un navigateur d’ordinateur de bureau, elle a l’air d’être rabougrie sur un appareil mobile. Google n'a pas vraiment ajouté grand chose à l'API d'animation, il n'y a donc pas de solution via l'API.

Le mieux que j'ai pu faire est de définir la valeur du délai d'attente sur 900 ms; le résultat est identique sur le bureau, car il exploite le délai de 150 ms pendant lequel l'icône se met en pause entre chaque rebond et donne un espace de respiration supplémentaire à l'animation d'un appareil mobile temps.

Edit: Ma solution a cessé de fonctionner pour moi tout d'un coup. Oops. Si vous le faites sur mobile, il vaudrait peut-être mieux ne pas vous soucier du rebond.

2
Rob Porter

Merci, pour la bonne réponse, je viens d'intégrer en ajoutant un peu de millisenconds

function toggleBounce(currentIcon) {
 currentIcon.setAnimation(null);

if (currentIcon.getAnimation() != null) {
  currentIcon.setAnimation(null);
 } else {
   currentIcon.setAnimation(google.maps.Animation.BOUNCE);
   setTimeout(function(){ currentIcon.setAnimation(null); }, 900);
 }
};
2
asael2

J'ai constaté que pour qu'une épingle cesse de s'animer après un rebond, vous devez la rendre déplaçable. La meilleure façon de procéder consiste à utiliser deux délais d'expiration:

  1. pour supprimer l'animation avant la fin du premier rebond.
  2. rendre le marqueur non déplaçable après la fin du premier rebond.

Les animations s’arrêteront une fois que vous aurez rendu un marqueur non déplaçable. J'ai créé un plunker pour montrer ce que je veux dire: http://plnkr.co/edit/Gcns3DMklly6UoEJ63FP?p=preview

Le HTML

    <div id="map-canvas"></div>
    <p>
      Bounce marker
      <select id="bounceNumber">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
        <option value="5">5</option>
        <option value="6">6</option>
      </select>
      times.
      <button onclick="bounceMarker()">Go!</button>
    </p>

Le JavaScript

var marker = null,
    toBounce = null,
    toDrag = null;

function initialize() {
    var mapOptions = {
        zoom: 4,
        center: new google.maps.LatLng(-25.363882, 131.044922)
    };
    var map = new google.maps.Map(document.getElementById('map-canvas'),
        mapOptions);
    marker = new google.maps.Marker({
        position: new google.maps.LatLng(-25.363882, 131.044922),
        map: map
    });
}

function bounceMarker() {
    var select = document.getElementById("bounceNumber"),
        bounces = parseInt(select.options[select.selectedIndex].value),
        animationTO = (bounces - 1) * 700 + 350,
        dragTO = animationTO + 1000;

    // Bounce the marker once
    if (marker.getAnimation() !== null) {
        marker.setAnimation(null);
        clearTimeout(toBounce);
        clearTimeout(toDrag);
        setTimeout(function () {
            marker.setDraggable(false);
        }, 750);
    } else {
        // Workaround to make marker bounce once.
        // The api will finish the current bounce if a marker is set to draggable.
        // So use two timeouts:
        // 1. to remove the animation before the first bounce is complete.
        // 2. to make the marker not draggable after the first bounce is complete.
        // Animations will stop once you make a marker not draggable.
        marker.setDraggable(true);
        marker.setAnimation(google.maps.Animation.BOUNCE);
        toBounce = setTimeout(function () {
            marker.setAnimation(null);
        }, animationTO);
        toDrag = setTimeout(function () {
            marker.setDraggable(false);
        }, dragTO);
    }
}


google.maps.event.addDomListener(window, 'load', initialize);

Pour autant que je sache, cela fonctionne avec plusieurs navigateurs. J'ai testé en chrome, firefox, safari et opéra. Je n'ai pas encore testé cela dans Internet Explorer.

1
thuijssoon
  marker.setAnimation(google.maps.Animation.BOUNCE);
        setTimeout(function() {
             marker.setAnimation(null)
        }, 6000);
0
Nikit Barochiya