2012-06-02 6 views
14

Estoy tratando de implementar una infoBubble personalizada que tenga la caja abierta al lado de un marcador en lugar de la posición predeterminada de arriba. Esto ha resultado ser más difícil de lo esperado.Google Maps InfoBubble pixelOffset (Moviéndome desde la posición predeterminada arriba del marcador)

Usando la ventana de información normal puede usar pixelOffset. Vea aquí para el documentation

Usando infoBubble esto no parece ser el caso. ¿Hay alguna forma de usar pixelOffset en una infoBubble, o algo que haga lo mismo?

He encontrado esto muy difícil de buscar, como el uso de una búsqueda en Google como este no devolvió resultados relevantes Google Search

A continuación se muestra todos mis recursos he estado utilizando.

  • Ejemplo de infoBubble here.

  • Mi JavaScript para instalar el mapa y infoBubble here.

Y ahora mi javascript aquí, por si acaso, el enlace jsfiddle está roto.

<script type="text/javascript"> 

    $(document).ready(function() { 
     init(); 
    }); 

    function init() { 

     //Setup the map 
     var googleMapOptions = { 
      center: new google.maps.LatLng(53.5167, -1.1333), 
      zoom: 13, 
      mapTypeId: google.maps.MapTypeId.ROADMAP 
     }; 

     //Start the map 
     var map = new google.maps.Map(document.getElementById("map_canvas"), 
     googleMapOptions); 

     var marker = new google.maps.Marker({ 
      position: new google.maps.LatLng(53.5267, -1.1333), 
      title: "Just a test" 
     }); 

     marker.setMap(map); 

     infoBubble = new InfoBubble({ 
      map: map, 
      content: '<div class="phoneytext">Some label</div>', 
      //position: new google.maps.LatLng(-35, 151), 
      shadowStyle: 1, 
      padding: '10px', 
      //backgroundColor: 'rgb(57,57,57)', 
      borderRadius: 5, 
      minWidth: 200, 
      arrowSize: 10, 
      borderWidth: 1, 
      borderColor: '#2c2c2c', 
      disableAutoPan: true, 
      hideCloseButton: false, 
      arrowPosition: 7, 
      backgroundClassName: 'phoney', 
      pixelOffset: new google.maps.Size(130, 120), 
      arrowStyle: 2 
     }); 
     infoBubble.open(map, marker); 

    } 
</script> 

actualización

para ayudar con la respuesta a esta pregunta he armar un caso de prueba aquí . Las líneas importantes son las líneas 38 & 39, que deben especificar dónde colocar la etiqueta.

Actualización 2

Para la generosidad que se concederá lo que necesito para ver un ejemplo de la InfoBubble situado lejos de su posición predeterminada por encima del marcador. Preferiblemente al lado derecho del marcador.

Actualización 3

He quitado el caso de prueba de la actualización 1 porque se encuentra alojada en los servidores de mi antigua empresa.

+0

acaba de lluvia de ideas: si conoce la posición del marcador: (LNG, lat), entonces (GNL + X, lat) debe ser la posición de la burbuja, a la derecha ? – Gavriel

+0

Parece que podría funcionar sí – Undefined

Respuesta

9

Parece que la biblioteca de infoBubble se establece de manera predeterminada en el posicionamiento de la burbuja sobre el marcador al que está vinculado. Eche un vistazo al archivo de muestra que incluyeron en la biblioteca: http://code.google.com/p/google-maps-utility-library-v3/source/browse/trunk/infobubble/examples/example.html. Noten específicamente de la línea 99 a la línea 122 y el uso de las dos infobubbles.El primero está vinculado al marcador, sin embargo, el segundo es independiente y, por lo tanto, si ve la línea 106, puede definir una posición para él. Ahora, basado en este entendimiento, he creado un ejemplo para ti en este violín http://jsfiddle.net/pDFc3/. La barra de información se coloca a la derecha del marcador.

Es extraño, porque la biblioteca InfoBubble js tiene una función para setPosition (http://code.google.com/p/google-maps-utility-library-v3/source/browse/trunk/infobubble/src/infobubble.js?r=206) Véase Línea 1027. Sin embargo, por alguna razón, después de esperar a que el DOM para cargar y tratar de cambiar la posición yendo infoBubble.setPosition(newLatLng); que no funciona . Por el contrario, declarar infoBubble.getPosition(); después de que el DOM se carga me da la posición actual del marcador al que está vinculada la infoBubble. Así que setPosition() puede tener un error en la biblioteca js, porque creo que todavía está siendo procesado (podría estar equivocado, tal vez solo tenga errores).


he fijado mi jsFiddle para resolver su problema para cuando el zoom dentro y fuera, y el posicionamiento de la InfoBubble en consecuencia (http://jsfiddle.net/pDFc3/). Déjame explicar la lógica primero. En primer lugar, el nivel de zoom máximo en Google Maps para el tipo de mapa de ruta es 21; este valor es inconsistente para las imágenes satelitales, pero el zoom máximo al que puede llegar el usuario es 21. A partir del 21, cada vez que aleje las diferencias entre dos puntos puede mantenido constante "en la pantalla", basada en la siguiente lógica:

consitent_screen_dist = initial_dist * (2^(21 - zoomlevel)) 

en nuestro caso, el valor razonable para la distancia inicial fue 0.00003 grados (entre el marcador y InfoBubble). Así, con base en esta lógica que añade la siguiente pieza para encontrar la distancia longitudinal inicial entre el marcador y InfoBubble:

var newlong = marker.getPosition().lng() + (0.00003 * Math.pow(2, (21 - map.getZoom()))); 

Del mismo modo, para asegurar la distancia se mantiene constante en cada cambio de nivel de zoom simplemente declaramos una nueva longitud a medida que escuchar a un cambio en el nivel de zoom:

google.maps.event.addListener(map, "zoom_changed", function() { 
     newlong = marker.getPosition().lng() + (0.00003 * Math.pow(2, (21 - map.getZoom()))); 
     infoBubble.setPosition(new google.maps.LatLng(marker.getPosition().lat(), newlong));     
    }); 

Tenga en cuenta que usted puede hacer que el código mucho más eficiente al declarar variables para marker.getPosition y otros valores que se llama a través de métodos. Para que las llamadas al método no se repitan y reduzcan la velocidad de su código.

+0

Eso es lo que estoy buscando, una cuestión es que cuando se acerca o aleja el marcador se mueve en relación con el marcador, a veces ocultándolo por completo. ¿Crees que esto es algo que se puede resolver? – Undefined

+0

Eso es cierto, es porque estamos configurando la posición de la infoBubble en relación con el marcador en un nivel de zoom específico. Pero una vez que cambia el nivel de zoom, la distancia entre el marcador y la barra de información (diferencia entre las coordenadas lat/long de ambos) no cambia. Entonces cuando alejas, esa diferencia es tan pequeña que ves la barra de información en la parte superior del marcador. –

+0

Aunque hay una solución a este problema, he descubierto que si no vincula el infoBubble al fabricante, entonces puede usar el método infoBubble.setPosition (latlng). Esto significa que podemos escuchar los cambios de zoom usando el oyente de eventos google maps 'zoom_changed' y luego usar la función' getZoom() 'para determinar las clases de cómo colocar la infoBubble en relación con el marcador en función de los niveles de zoom. Actualizaré mi jsfiddle con esta posible solución, pero no dude en experimentar basado en este principio. –

1

Desafortunadamente, no existe una opción como pixelOffset en InfoBubble. Pero si solo desea mover Burbuja arriba del marcador en su ejemplo, no debe establecer el parámetro en la inicialización de la burbuja. Consideremos el siguiente violín (i fijo en su caso):

http://jsfiddle.net/ssrP9/5/


P. S. Su violín no funcionó porque no había agregado los recursos correctamente http://doc.jsfiddle.net/basic/introduction.html#add-resources

+0

Se olvidó de mencionar. Mi respuesta se basa en el análisis de fuentes. Así que si realmente necesita establecer un desplazamiento personalizado relativo a un marcador, hay dos formas: 1. Obtenga los orígenes de esta biblioteca y agregue la funcionalidad necesaria 2. [bastante raro] Coloque el marcador invisible con el desplazamiento necesario desde el original y el cuadro abierto eso. –

+0

Gracias por eso jsfiddle lo incluiré en mi pregunta. Lamentablemente estoy buscando colocar la infoBubble en una posición diferente desde arriba del marcador – Undefined

1

Me acabo de encontrar el mismo problema pero no he podido encontrar una respuesta en ningún lado. A través de un pequeño ensayo y error lo resolví.

Utilizará el archivo Google JS para "infoBubble". Entra en este archivo y búsqueda de ...

InfoBubble.prototype.buildDom_ = function() { 

Para mí, esto es en la línea 203 (pero que podría ser el resultado de barajar anterior y ediciones).

Dentro de esa función, verá la declaración de la posición "absoluta". En una nueva línea, puede agregar marginTop, marginRight, marginBottom y marginLeft. Esto empujará la burbuja desde su posición predeterminada (que también depende de la declaración de posición de flecha en su configuración) ...

Este es mi código de ajuste en el archivo burbuja JS que coloca la burbuja sobre la parte superior del marcador (debido a una característica de diseño) ...

var bubble = this.bubble_ = document.createElement('DIV'); 
bubble.style['position'] = 'absolute'; 
bubble.style['marginTop'] = this.px(21); 
bubble.style['marginLeft'] = this.px(1); 
bubble.style['zIndex'] = this.baseZIndex_; 

Espero que ayude.

0

En la función InfoBubble buildDom, añadir:

bubble.className = 'bubble-container'; 

Ahora usted tiene una clase CSS para cada InfoBubble, se puede cambiar usando margen de CSS.

8

Esta es mi solución.

En InfoBubble biblioteca

reemplazar método

toda InfoBubble.prototype.draw

con

/* 
* Sets InfoBubble Position 
* */ 
InfoBubble.prototype.setBubbleOffset = function(xOffset, yOffset) { 
    this.bubbleOffsetX = parseInt(xOffset); 
    this.bubbleOffsetY = parseInt(yOffset); 
} 


/* 
* Gets InfoBubble Position 
* */ 
InfoBubble.prototype.getBubbleOffset = function() { 
    return { 
    x: this.bubbleOffsetX || 0, 
    y: this.bubbleOffsetY || 0 
    } 
} 

/** 
* Draw the InfoBubble 
* Implementing the OverlayView interface 
*/ 
InfoBubble.prototype.draw = function() { 
    var projection = this.getProjection(); 

    if (!projection) { 
    // The map projection is not ready yet so do nothing 
    return; 
    } 

    var latLng = /** @type {google.maps.LatLng} */ (this.get('position')); 

    if (!latLng) { 
    this.close(); 
    return; 
    } 

    var tabHeight = 0; 

    if (this.activeTab_) { 
    tabHeight = this.activeTab_.offsetHeight; 
    } 

    var anchorHeight = this.getAnchorHeight_(); 
    var arrowSize = this.getArrowSize_(); 
    var arrowPosition = this.getArrowPosition_(); 

    arrowPosition = arrowPosition/100; 

    var pos = projection.fromLatLngToDivPixel(latLng); 
    var width = this.contentContainer_.offsetWidth; 
    var height = this.bubble_.offsetHeight; 

    if (!width) { 
    return; 
    } 

    // Adjust for the height of the info bubble 
    var top = pos.y - (height + arrowSize) + this.getBubbleOffset().y; 

    if (anchorHeight) { 
    // If there is an anchor then include the height 
    top -= anchorHeight; 
    } 

    var left = pos.x - (width * arrowPosition) + this.getBubbleOffset().x; 

    this.bubble_.style['top'] = this.px(top); 
    this.bubble_.style['left'] = this.px(left); 

    var shadowStyle = parseInt(this.get('shadowStyle'), 10); 

    switch (shadowStyle) { 
    case 1: 
     // Shadow is behind 
     this.bubbleShadow_.style['top'] = this.px(top + tabHeight - 1); 
     this.bubbleShadow_.style['left'] = this.px(left); 
     this.bubbleShadow_.style['width'] = this.px(width); 
     this.bubbleShadow_.style['height'] = 
     this.px(this.contentContainer_.offsetHeight - arrowSize); 
     break; 
    case 2: 
     // Shadow is below 
     width = width * 0.8; 
     if (anchorHeight) { 
     this.bubbleShadow_.style['top'] = this.px(pos.y); 
     } else { 
     this.bubbleShadow_.style['top'] = this.px(pos.y + arrowSize); 
     } 
     this.bubbleShadow_.style['left'] = this.px(pos.x - width * arrowPosition); 

     this.bubbleShadow_.style['width'] = this.px(width); 
     this.bubbleShadow_.style['height'] = this.px(2); 
     break; 
    } 
}; 

y entonces usted puede utilizar esto

var infoBubble = new InfoBubble({ 
    map: map, 
    content: "My Content", 
    position: new google.maps.LatLng(1, 1), 
    shadowStyle: 1, 
    padding: 0, 
    backgroundColor: 'transparent', 
    borderRadius: 7, 
    arrowSize: 10, 
    borderWidth: 1, 
    borderColor: '#2c2c2c', 
    disableAutoPan: true, 
    hideCloseButton: true, 
    arrowPosition: 50, 
    backgroundClassName: 'infoBubbleBackground', 
    arrowStyle: 2 

}); 

Entonces, finalmente, tenemos que utilizar este método para establecer la posición setBubbleOffset(x,y); InfoBubble

infoBubble.setBubbleOffset(0,-32); 
1

También puede utilizar una altura de anclaje definida;

var anchorHeight = YOURNUMBER; 

línea 874 infobubble.js

Cuestiones relacionadas