x

OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung


  1. OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung · JueDan (Gast) · 30.09.2012 13:20 · [flux]

    Hallo Forum,

    die OpenLayers-Projekte auf meiner Webseite sind so ziemlich fertig. Was mich allerdings stört und was ich auch unbedingt abstellen möchte, ist das lästige Flackern von Popup-Boxes.

    Das OpenLayers.Features.Vector-Objekt wird wie folgt erzeugt:

    select␣=␣new␣OpenLayers.Control.SelectFeature(vl,␣{
    hover:␣true,
    toggle:␣true,
    id:␣"SELECT_LAYER_KLICK_HUETTEN",
    eventListeners:␣{
    featurehighlighted:␣wk_onFeatureOver_Huette,
    featureunhighlighted:␣wk_onFeatureOut_Huette
    }
    });
    if␣(select)␣{
    map.addLayer(vl);
    map.addControl(select);
    select.activate();
    }
    

    Jedesmal wenn man mit der Maus über dieses Objekt fährt, öffnet sich eine Popupbox. Wenn man nun mit der Maus in die Nähe der Popupbox kommt, fängt diese an zu flackern. Das kann hier ausprobiert werden: http://www.dankoweit.de/cgi-bin/bergtou … ion=&typ=0

    Meine Frage nun, wie stelle ich dieses nervende und unschöne Flackern ab. Tante Google und Onkel Bing haben keine verwertbaren Ergebnisse gebracht.

    Danke schon mal für die Antworten und einen schönen Sonntag

    Jürgen


    • Re: OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung · wambacher (Gast) · 30.09.2012 13:58 · [flux]

      JueDan wrote:

      Meine Frage nun, wie stelle ich dieses nervende und unschöne Flackern ab. Tante Google und Onkel Bing haben keine verwertbaren Ergebnisse gebracht.

      Danke schon mal für die Antworten und einen schönen Sonntag

      Jürgen

      Hi, ich hab leider keine Lösung aber eine diffuse Vermutung:

      Alle Boxes überlappen sich. Eventuell kommt da wer/was durcheinander? Erstelle mal eine Box, die völlig "losgelöst" ist und schau, ob es da immer noch flackert.

      Wirklich nur 'ne vage Idee aber das sollte man als Ursache ausklammern können.

      Gruss
      walter


    • Re: OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung · ikonor (Gast) · 30.09.2012 16:47 · [flux]

      Ich hab das gleiche Problem, hab mich aber noch nicht drum gekümmert.

      Also wenn Du eine Lösung findest, lass es uns bitte wissen.

      Gruß,
      Norbert


    • Re: OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung · JueDan (Gast) · 30.09.2012 20:51 · [flux]

      Hallo Walter,

      wambacher wrote:

      JueDan wrote:

      Meine Frage nun, wie stelle ich dieses nervende und unschöne Flackern ab. Tante Google und Onkel Bing haben keine verwertbaren Ergebnisse gebracht.

      Danke schon mal für die Antworten und einen schönen Sonntag

      Jürgen

      Hi, ich hab leider keine Lösung aber eine diffuse Vermutung:

      Alle Boxes überlappen sich. Eventuell kommt da wer/was durcheinander? Erstelle mal eine Box, die völlig "losgelöst" ist und schau, ob es da immer noch flackert.

      Wirklich nur 'ne vage Idee aber das sollte man als Ursache ausklammern können.

      Gruss
      walter

      Diese Ursache kann man ausklammern. Inzwischen habe ich herausgefunden, warum die Popupbox flackert, wenn man die Maus bewegt.
      Die komplette Popupbox inklusive "Rüssel" wird aus Bitmaps mit transparentem Hintergrund zusammengesetzt - das mache ich nicht in meinem Code, sondern das macht OpenLayers selber. Die gesamte Popupbox bildet so eine große Bitmap. Wenn man nun die Maus in die Nähe der Box bewegt und diese Bitmap erreicht, wird ein beim Feature ein Event "onmouseout" erzeugt, der die Popupbox schließt.

      Nach einigem Grübeln bin ich nun auf die Idee gekommen, dass die Position des "Rüssels" am Rand des Features liegen muss, dann hört das Flackern auf. Aber die Lösung ist nicht trivial.
      Mal sehen, da fällt mir auch noch der passende Code ein:)

      Viele Grüße und schönen Abend

      Jürgen


    • Re: OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung · JueDan (Gast) · 30.09.2012 20:52 · [flux]

      Hallo Norbert,

      ikonor wrote:

      Ich hab das gleiche Problem, hab mich aber noch nicht drum gekümmert.

      Also wenn Du eine Lösung findest, lass es uns bitte wissen.

      Gruß,
      Norbert

      Eh kloar;)

      Grüße

      Jürgen


    • Re: OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung · maxbe (Gast) · 30.09.2012 22:07 · [flux]

      Hi Jürgen,

      schöne Seite, besonders die Darstellung von Zwischenzielen einer Tour finde ich hübsch. Zum Flackerproblem kann ich leider nichts beitragen, ausser die Vermutung mit dem "Rüssel" bestätigen...

      Bei den einzelnen Wanderkarten ist mir aufgefallen, dass Deinen Maßstäben ein geodesic:true gut täte. Bei den eingeblendeten UTM-Gittern fällt das recht stark auf, dass Du so kurze Kilometer hast 😉

      Grüße, Max


    • Re: OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung · JueDan (Gast) · 01.10.2012 12:58 · [flux]

      maxbe wrote:

      Hi Jürgen,
      Bei den eingeblendeten UTM-Gittern fällt das recht stark auf, dass Du so kurze Kilometer hast 😉

      Grüße, Max

      Das ist Bergsteigerpsychologie 😄

      Wird eingebaut, danke für den Hinweis.

      Viele Grüße

      JueDan


    • Re: OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung · ikonor (Gast) · 01.10.2012 13:33 · [flux]

      JueDan wrote:

      Wenn man nun die Maus in die Nähe der Box bewegt und diese Bitmap erreicht, wird ein beim Feature ein Event "onmouseout" erzeugt, der die Popupbox schließt.

      Nach einigem Grübeln bin ich nun auf die Idee gekommen, dass die Position des "Rüssels" am Rand des Features liegen muss, dann hört das Flackern auf. Aber die Lösung ist nicht trivial.

      Ich würde lieber den Event abfangen oder erst gar nicht auslösen wollen. Ist aber evtl. auch nicht ganz einfach.

      Gruß,
      Norbert


    • Re: OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung · JueDan (Gast) · 01.10.2012 15:12 · [flux]

      Hallo ikonor, wambacher, maxbe und Forum

      puuuuuuh, das Problem ist - wenn auch unkonventionell - gelöst. Das Flackern hat ein Ende.

      Die Lösung war der "Rüssel" bei OpenLayers.Popup.FramedCloud und dessen Ankerpunkt anchor, den man im Konstruktur definieren kann und sollte. Man schreibt sich eine Funktion, welche die Position dieses Ankerpunktes so berechnet, dass der "Rüssel" genau auf dem Rand der Boundingbox eines Features ansetzt. Diese Funktion erfordert einiges an Tüftelei, aber das macht nix, weil man so einen tieferen Einblick in OpenLayers erhält 🙂
      Diese Funktion berücksichtigt nicht nur rechteckige, sondern auch runde Features. Zu polygonalen Features und Text-Features ist mir noch nix eingefallen, da sie mein Problem nicht tangieren.

      Schaut hier: Beschreibung

      Viele Grüße und vielleicht hilft es dem Einen oder Anderen weiter.

      Jürgen


    • Re: OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung · ikonor (Gast) · 03.10.2012 10:22 · [flux]

      Danke für die Beschreibung Deiner Lösung. Leider passt das für meinen Fall nicht so ganz, da ich auch Polygone und Linien habe und zudem die Mausposition als Anker verwende.

      Deshalb hab ich noch nach einer anderen Lösung gesucht und bin nach einigem Probieren und Suchen auf eine sehr einfache Lösung gestoßen: es gibt eine CSS Eigenschaft "pointer-events", mit der man für ein Element bestimmen kann, dass es keine Maus-Events bekommt ("none"), die erhält dann das darunterliegene Element. pointer-events für HTML Elemente ist offiziell allerdings erst für CSS4 vorgesehen und nicht in Opera und IE verfügbar (MDN, caniuse.com).

      Bei mir hab ich das nach dem Erzeugen des Popups eingebaut (Popup.div ist kein API-Property!):

      popup.div.style['pointer-events']␣=␣'none';
      

      Gruß,
      Norbert


    • Re: OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung · JueDan (Gast) · 03.10.2012 10:36 · [flux]

      Hallo Norbert,

      ikonor wrote:

      Danke für die Beschreibung Deiner Lösung. Leider passt das für meinen Fall nicht so ganz, da ich auch Polygone und Linien habe und zudem die Mausposition als Anker verwende.

      Schickst Du mir mal einen Link auf Deine Seite/Anwendung. Vielleicht läßt es sich doch anwenden. Schließlich mache ich in meinem Code nichts anderes, als den Ankerpunkt an den Rand eines Features zu verschieben.

      Deshalb hab ich noch nach einer anderen Lösung gesucht und bin nach einigem Probieren und Suchen auf eine sehr einfache Lösung gestoßen: es gibt eine CSS Eigenschaft "pointer-events", mit der man für ein Element bestimmen kann, dass es keine Maus-Events bekommt ("none"), die erhält dann das darunterliegene Element. pointer-events für HTML Elemente ist offiziell allerdings erst für CSS4 vorgesehen und nicht in Opera und IE verfügbar (MDN, caniuse.com).

      Interessant. Kannst Du weiterhin Links in der Popupbox anklicken?

      Viele Grüße

      Jürgen


    • Re: OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung · ikonor (Gast) · 03.10.2012 12:38 · [flux]

      JueDan wrote:

      Schickst Du mir mal einen Link auf Deine Seite/Anwendung. Vielleicht läßt es sich doch anwenden. Schließlich mache ich in meinem Code nichts anderes, als den Ankerpunkt an den Rand eines Features zu verschieben.

      Danke für das Angebot, aber ich denke, ich bin mit der jetzigen Lösung erst mal zufrieden. Die Anwendung ist noch in Entwicklung und noch nicht veröffentlicht, nur eine nicht ganz aktuelle Vorschau. Dort verwende ich noch das übliche feature.geometry.getBounds().getCenterLonLat(). Das hat mir aber nicht gefallen, weil:
      - bei nicht geraden LineStrings das Bounds-Zentrum dann irgendwo liegt, aber nicht auf der Linie
      - der Anker bei hohem Zoom auch außerhalb des Anzeigebereichs liegen kann, wenn die Geometrie nur teilweise innerhalb liegt
      (betrifft auch Deine Lösung - der Popup schiebt sich dann zwar dann in den Anzeigebereich, aber das gefällt mir nicht)

      Das kann man zwar alles lösen, aber nur mit sehr viel Aufwand und ohne Garantie, dass das Ergebnis dann zufriedenstellend ist. Daher nehme ich einfach die Mausposition als Anker - denn da schaut man ja auch gerade hin - hebe das selektierte Feature hervor (ohne Rüssel), und nehme in Kauf, dass das Feature durch den Popup evtl. teilweise verdeckt wird.

      JueDan wrote:

      Interessant. Kannst Du weiterhin Links in der Popupbox anklicken?

      Nein, das geht dann nicht. Da mache ich noch eine Unterscheidung und setze das nur, wenn hover=true.

      Gruß,
      Norbert


    • Re: OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung · JueDan (Gast) · 09.10.2012 08:25 · [flux]

      Hallo Forum,

      bei Features mit Icons oder Images flackert die Popupbox nun auch nicht mehr:
      http://www.dankoweit.de/Projekte/hp_pro … e_Flackern

      Viele Grüße

      Jürgen


    • Re: OpenLayers: Flackern von OpenLayers.Popup bei Mausbewegung · hupe (Gast) · 23.01.2014 20:12 · [flux]

      JueDan wrote:

      http://www.dankoweit.de/Projekte/hp_pro … e_Flackern

      Die URL lautet nun:
      http://www.dankoweit.de/Projekte/hp_pro … ayers.html

      Ich habe diesen Code angewendet, er funktioniert. Es hat mir aber überhaupt nicht gefallen, dass die Popups machmal "in der Gegend rumschwirrten" und keinen direkten Bezug zum Objekt hatten. Deshalb wende ich zumindest für Polygone folgendes an:

      function␣richtung(feature)␣{
      var␣bounds=feature.geometry.bounds;
      var␣quadrant=this.map.getExtent().determineQuadrant(bounds.getCenterLonLat());
      quadrant=OpenLayers.Bounds.oppositeQuadrant(quadrant);
      return␣(quadrant);␣//(“br”␣“tr”␣“tl”␣“bl”)
      }
      
      function␣anker(feature)␣{
      var␣quadrant=richtung(feature);
      var␣bounds=feature.geometry.bounds;
      var␣point;
      if␣(quadrant=="br")␣point␣=␣new␣OpenLayers.Geometry.Point(bounds.right,bounds.bottom);
      if␣(quadrant=="tr")␣point␣=␣new␣OpenLayers.Geometry.Point(bounds.right,bounds.top);
      if␣(quadrant=="tl")␣point␣=␣new␣OpenLayers.Geometry.Point(bounds.left,bounds.top);
      if␣(quadrant=="bl")␣point␣=␣new␣OpenLayers.Geometry.Point(bounds.left,bounds.bottom);
      
      var␣dist=(point.distanceTo(feature.geometry,{details:true}));
      return(new␣OpenLayers.LonLat(dist.x1,dist.y1));
      }
      
      function␣onFeatureOver(event)␣{
      var␣feature␣=␣event.feature;
      var␣pos␣=␣anker(feature);
      var␣content␣=␣"Text";
      feature.popup␣=␣new␣OpenLayers.Popup.FramedCloud(
      "hover",
      pos,
      null,␣content,␣null,␣true,␣null
      );
      feature.popup.calculateRelativePosition␣=␣function␣()␣{
      return␣richtung(feature);
      }
      map.addPopup(feature.popup);
      this.map.div.style.cursor␣=␣'pointer';
      }
      

      Damit befindet sich das Popup unmittelbar am Polygon.

      Viele Grüße.
      Petra