MapView.scale doesn't change correctly when we set constraints.snapToZoom = false

907
3
Jump to solution
01-07-2020 07:45 AM
MichailMarinakis1
Occasional Contributor

Hi all, 

we have noticed a strange behavior. 

  1. We set in a MapView the constraints.snapToZoom = false.
  2. We watch the scale to get the new value of it.

When we zoom with the mouse wheel, then the scale doesn't always change. After any other interaction e.g. pan, then the event is firing and the scale adapts. This behavior doesn't occur when we zoom in/out with the zoom widget and it doesn't occur either when we set the constraints.snapToZoom = true. 

Sample of code below (taken from here). Just switch the snapToZoom (line 102) from true/false and vice versa, zoom, pan to notice the behavior. Please let us know about any feedback.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>Event explorer / watch properties - 4.14</title>
    <style>
      html,
      body {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }

      #viewDiv {
        position: absolute;
        left: 0;
        right: 250px;
        top: 0;
        bottom: 0;
        height: 100%;
      }

      #panel {
        background-color: #f5f5f5;
        position: absolute;
        right: 0;
        height: 100%;
        width: 250px;
        font-size: 12px;
      }

      #events {
        color: black;
      }

      #properties {
        color: blue;
      }

      .title {
        font-weight: bold;
      }

      .container {
        background-color: white;
        color: #323232;
        margin: 10px;
        padding: 5px;
        border-bottom: 1px solid rgba(50, 50, 50, 0.25);
      }

      .event {
        transition: background-color 0.5s ease-out;
        padding-bottom: 2px;
        opacity: 0.2;
      }

      .property {
        transition: background-color 0.5s ease-out;
        padding-bottom: 2px;
        opacity: 0.2;
      }

      .active {
        opacity: 1;
        background-color: #99ccff;
      }

      .inactive {
        opacity: 1;
        background-color: white;
      }
    </style>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.14/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.14/"></script>

    <script>
      require([
        "esri/Map",
        "esri/views/SceneView",
        "esri/views/MapView"
      ], function(Map, SceneView, MapView) {
        const map = new Map({
          basemap: "streets",
          ground: "world-elevation"
        });

        const view = new MapView({
          container: "viewDiv",
          map: map,
          constraints: {

          snapToZoom: false,

         }
        });
        view.pixelratio = 2;

        const events = [
          "pointer-enter",
          "pointer-leave",
          "pointer-move",
          "pointer-down",
          "pointer-up",
          "immediate-click",
          "click",
          "double-click",
          "mouse-wheel",
          "drag",
          "hold",
          "key-down",
          "key-up",
          "focus",
          "blur",
          "resize"
          // the following events are commented out for space reason, comment in if you would like to see them
          // "layerview-create", "layerview-destroy"
        ];
        const properties = [
          "focused",
          "interacting",
          "updating",
          "ready",
          "resolution",
          "scale",
          "zoom",
          "stationary"
          // the following properties are commented out for space reason, comment in if you would like to see them
          // "resizing", "height", "width", "size"
          // "allLayerViews", "animation", "container", "spatialReference", "type",
          // "declaredClass", "graphics", "groundView",  "input",
          // "layerViews", "map", "navigation", "padding", "popup",
          // "suspended",  "ui"
        ];

        // Dynamically create the table of events and properties from the defined array
        function createTables() {
          const eventsTable = document.getElementById("events");
          let content = eventsTable.innerHTML;
          for (let i = 0; i < events.length; i++) {
            content += '<div class="event" id="' + events[i] + '">' + events[i];
            content += "</div>";
          }
          eventsTable.innerHTML = content;
          const propertiesTable = document.getElementById("properties");
          content = propertiesTable.innerHTML;
          for (let i = 0; i < properties.length; i++) {
            content +=
              '<div class="property" id="' +
              properties[i] +
              '">' +
              properties[i] +
              " = </div>";
          }
          propertiesTable.innerHTML = content;
        }

        function setupEventListener(view, name) {
          const eventRow = document.getElementById(name);
          view.on(name, function(value) {
            eventRow.className = "event active";
            if (eventRow.highlightTimeout) {
              clearTimeout(eventRow.highlightTimeout);
            }
            eventRow.highlightTimeout = setTimeout(function() {
              // after a timeout of one second disable the highlight
              eventRow.className = "event inactive";
            }, 1000);
          });
        }

        function setupPropertiesListener(view, name) {
          const propertiesRow = document.getElementById(name);
          view.watch(name, function(value) {
            propertiesRow.className = "property active";
            propertiesRow.innerHTML = propertiesRow.innerHTML.substring(
              0,
              propertiesRow.innerHTML.indexOf(" = ")
            );
            // set the text to the received value
            propertiesRow.innerHTML += " = " + JSON.stringify(value);
            if (propertiesRow.highlightTimeout) {
              clearTimeout(propertiesRow.highlightTimeout);
            }
            propertiesRow.highlightTimeout = setTimeout(function() {
              // after a timeout of one second disable the highlight
              propertiesRow.className = "property inactive";
            }, 1000);
          });
        }

        // create the tables for the events and properties
        createTables();

        // Setup all view events defined in the array
        for (let i = 0; i < events.length; i++) {
          setupEventListener(view, events[i]);
        }
        // Setup all watch properties defined in the array
        for (let i = 0; i < properties.length; i++) {
          setupPropertiesListener(view, properties[i]);
        }
      });
    </script>
  </head>

  <body>
    <div id="main" class claro>
      <div id="viewDiv"></div>
      <div id="panel" class="esri-widget">
        <div id="events" class="container">
          <a
            class="title"
            href="https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View.html#events-summary"
            target="_blank"
            >Class View Events:</a
          >
        </div>
        <div id="properties" class="container">
          <a
            class="title"
            href="https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View.html#properties-summary"
            target="_blank"
            >Class View Properties:</a
          >
        </div>
      </div>
    </div>
  </body>
</html>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

UPDATE:

ok, so after some investigation, similar behavior is happening when we execute:

view.goTo({ scale: 500 }, { animate: false });

If we execute a second time, then the scale changes correctly!

If we execute it with animate: true, then the scale changes correctly from the first time!

My question at the end is: Is there a table where we can monitor when different properties of the MapView are changing based on certain events? In other words, when are certain events triggered and what properties are impacted from these events?

0 Kudos
1 Solution

Accepted Solutions
AnneFitz
Esri Contributor

Hi, I just wanted to update you that this will be fixed in the 4.15 release of the ArcGIS API for JavaScript (which is coming very soon!) Thanks again for reporting this bug.

View solution in original post

3 Replies
AnneFitz
Esri Contributor

Hi Michail,

Thank you for reporting this issue! We will work on getting this fixed and will keep you updated with our progress.

Thanks,

Anne

AnneFitz
Esri Contributor

Hi, I just wanted to update you that this will be fixed in the 4.15 release of the ArcGIS API for JavaScript (which is coming very soon!) Thanks again for reporting this bug.

MichailMarinakis1
Occasional Contributor

Perfect! Thank you for your response and the fast fix!

0 Kudos