Select to view content in your preferred language

ArcGIS JS Map Cursor

2024
8
Jump to solution
01-06-2023 06:09 PM
Wade
by
New Contributor III

How to change my cursor style in ArcGIS API for JS 4.25 with setMapCursor() which is applied in 3.X?

0 Kudos
1 Solution

Accepted Solutions
Egge-Jan_Pollé
MVP Regular Contributor

Hmmm... I am using Notepad++ as my favorite text editor. Can you please have a look at the code sample below? In this working example I do add a custom toggle button to the view.ui and when I click this button the cursor changes. I have tested this on my Windows machine in three major browsers (Chrome/Firefox/Edge). It might not work in IE 11, but I take that for granted...

Can you please tell me whether this example works for you?

Cheers,

Egge-Jan

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>ArcGIS JavaScript Example: change cursor in view</title>
  <link rel="stylesheet" href="https://js.arcgis.com/4.25/esri/css/main.css">
  <script src="https://js.arcgis.com/4.25/"></script>
  <style>
    html, body, #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>
  <script>  
      require([
        "esri/Map",
        "esri/geometry/Point",
        "esri/views/MapView"
      ], function(Map, Point, MapView) {

      let myCondition = false;

      let map = new Map({
        basemap: {
          portalItem: {
            id: "0bd3a4a6fd674a90a7d0a9e5f36fb59b" // OS Open Carto
          }
        }
      });

      let view = new MapView({
        spatialReference: 27700, 
        container: "viewDiv",
        map: map,
        center: new Point({x: 500000, y: 500000, spatialReference: 27700}),
        zoom: 7
      });
	  
	  createToggleBtn();
	  view.ui.add(["toggleBtn"], "top-right");

      /*******************************************************************************
       * Start Toggle button
       *******************************************************************************/
      function createToggleBtn() {
        const toggleBtnDiv = document.createElement('div');
		toggleBtnDiv.innerHTML = `
		  <div id="toggleBtn" class="esri-component esri-widget--button esri-widget" role="button">
            <span title="Toggle button" id="toggle-button" class="esri-icon esri-icon-plus-circled"></span>
          </div>`;
        document.body.appendChild(toggleBtnDiv);
      }
      
      let l_toggleButton = document.getElementById("toggleBtn");
      l_toggleButton.addEventListener("click", switchToggleeButton);
      
      function switchToggleeButton(evt) {
        if (myCondition === false) {
          l_toggleButton.style.color = "white";
          l_toggleButton.style.backgroundColor = "#8d8d8d";
          view.cursor = "crosshair";
          myCondition = true;
          view.popup.autoOpenEnabled = false;
        } else {
          l_toggleButton.style.color = "#8d8d8d";
          l_toggleButton.style.backgroundColor = "white";
          view.cursor = "auto";
          myCondition = false;
          view.popup.autoOpenEnabled = true;
          view.popup.close();
        }
      }
      
      view.on("click", function(event){
        if (myCondition) {
          view.popup.open({
            title: "Click",
            content: "<b>You clicked on te map!</b>",
            location: event.mapPoint
          });
        }
        console.log("cursor: " + view.cursor);
      });

      /*******************************************************************************
       * End Toggle button
       *******************************************************************************/

    });
  </script>
</head>
<body>
  <div id="viewDiv"></div>
</body>
</html>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

 

View solution in original post

8 Replies
Egge-Jan_Pollé
MVP Regular Contributor

Version 4.x is a substantial overhaul of the ArcGIS Maps SDK for JavaScript (formerly - until December 2022 - known as the ArcGIS API for JavaScript) and its mapping components.

One major change is the introduction of views (MapViews for 2D and SceneViews for 3D) to separate the map and the way it is displayed:

At 4.0, a Map can be displayed in 2D or 3D. Because of this, the drawing logic was revised. The Map and Layers no longer handle the drawing logic, instead it is now handled by Views.

(see: Migrating from 3.x to 4.25 | ArcGIS Maps SDK for JavaScript 4.25 > Views)

So, your cursor is no longer linked to the map but to the view.

An example of changing the cursor when a certain condition is met would be something like this:

 

if (myCondition) {
  view.cursor = "crosshair";
} else {
  view.cursor = "auto";
}

 

 

HTH,

 

Egge-Jan

0 Kudos
JoelBennett
MVP Regular Contributor

Although the bulk of that is correct, there is no documented "cursor" property for the objects that inherit View, and trying to use it makes no difference for me.  I've always had to use view.container.style.cursor, e.g.:

view.container.style.cursor = "progress";

 

0 Kudos
Egge-Jan_Pollé
MVP Regular Contributor

Yes, you are right: I couldn’t find anything about this  cursor-and-view in the docs either. But I can assure you that the above code snippet works for me, and it already does do so for a longtime: if myCondition is met, I get the crosshairs cursor and in all other circumstances the default cursor is showing.

How come? I don’t know. It just works for me, really. Is there someone at the ArcGIS Maps SDK for JavaScript team who can explain?

0 Kudos
JoelBennett
MVP Regular Contributor

Hmm...I'm writing directly in JavaScript with AMD; are you using a different approach?

0 Kudos
Egge-Jan_Pollé
MVP Regular Contributor

Hmmm... I am using Notepad++ as my favorite text editor. Can you please have a look at the code sample below? In this working example I do add a custom toggle button to the view.ui and when I click this button the cursor changes. I have tested this on my Windows machine in three major browsers (Chrome/Firefox/Edge). It might not work in IE 11, but I take that for granted...

Can you please tell me whether this example works for you?

Cheers,

Egge-Jan

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>ArcGIS JavaScript Example: change cursor in view</title>
  <link rel="stylesheet" href="https://js.arcgis.com/4.25/esri/css/main.css">
  <script src="https://js.arcgis.com/4.25/"></script>
  <style>
    html, body, #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>
  <script>  
      require([
        "esri/Map",
        "esri/geometry/Point",
        "esri/views/MapView"
      ], function(Map, Point, MapView) {

      let myCondition = false;

      let map = new Map({
        basemap: {
          portalItem: {
            id: "0bd3a4a6fd674a90a7d0a9e5f36fb59b" // OS Open Carto
          }
        }
      });

      let view = new MapView({
        spatialReference: 27700, 
        container: "viewDiv",
        map: map,
        center: new Point({x: 500000, y: 500000, spatialReference: 27700}),
        zoom: 7
      });
	  
	  createToggleBtn();
	  view.ui.add(["toggleBtn"], "top-right");

      /*******************************************************************************
       * Start Toggle button
       *******************************************************************************/
      function createToggleBtn() {
        const toggleBtnDiv = document.createElement('div');
		toggleBtnDiv.innerHTML = `
		  <div id="toggleBtn" class="esri-component esri-widget--button esri-widget" role="button">
            <span title="Toggle button" id="toggle-button" class="esri-icon esri-icon-plus-circled"></span>
          </div>`;
        document.body.appendChild(toggleBtnDiv);
      }
      
      let l_toggleButton = document.getElementById("toggleBtn");
      l_toggleButton.addEventListener("click", switchToggleeButton);
      
      function switchToggleeButton(evt) {
        if (myCondition === false) {
          l_toggleButton.style.color = "white";
          l_toggleButton.style.backgroundColor = "#8d8d8d";
          view.cursor = "crosshair";
          myCondition = true;
          view.popup.autoOpenEnabled = false;
        } else {
          l_toggleButton.style.color = "#8d8d8d";
          l_toggleButton.style.backgroundColor = "white";
          view.cursor = "auto";
          myCondition = false;
          view.popup.autoOpenEnabled = true;
          view.popup.close();
        }
      }
      
      view.on("click", function(event){
        if (myCondition) {
          view.popup.open({
            title: "Click",
            content: "<b>You clicked on te map!</b>",
            location: event.mapPoint
          });
        }
        console.log("cursor: " + view.cursor);
      });

      /*******************************************************************************
       * End Toggle button
       *******************************************************************************/

    });
  </script>
</head>
<body>
  <div id="viewDiv"></div>
</body>
</html>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

 

JoelBennett
MVP Regular Contributor

Thanks for going through the trouble of creating and posting that.  It turns out it works just fine for me, so I went back to the example I tried before my first post, and found it working, so I was a bit dumbfounded.  But then I realized I used a different cursor on this try (progress) than previously (wait).  So then I tried it with the "wait" cursor, and it doesn't work in my example or yours.

So in your example, if you change it to:

view.cursor = "wait";

it doesn't work, but if you change it to:

view.container.style.cursor = "wait";

it does work.  It makes me wonder how many cursors behave like this?  I don't really have the bandwidth to figure it out though, so I'll probably just stick with the latter approach...

Egge-Jan_Pollé
MVP Regular Contributor

Yeah, that's what we started with: this 'cursor' property of the view is an undocumented feature. (I do not remember how I found out about it... Most probably I copied it from an example by someone else a few years ago...)

But happy to see that my answer is (at least partly) true (for some cursors).

0 Kudos
JoelBennett
MVP Regular Contributor

Actually, it wasn't terribly difficult to find out which ones aren't supported.  The following CSS cursors don't work with view.cursor, but do with view.container.style.cursor:

Most of those nobody would probably ever use, but four of those (one being the url-based) are found in my applications.