Search code examples
javascriptjquerykendo-uiarcgisarcgis-js-api

arcgis-JS polyline path to follow a div on DRAG


I have this almost working; but instead of it following the kendo modal when dragged, it's following the mouse pointer at all times...

So, currently it's following the mouse pointer and so is the modal; but this is horrible for usability so would just like to stay with and follow the modal on the standard click and drag.

attempt A.) Below is the JavaScript, here is the live demo CodePen. The line should always be with the modal for point B, which it's doing; but the modal should only be movable on drag.

require([
      "esri/Map",
      "esri/views/MapView",
      "esri/Graphic",
      "esri/layers/GraphicsLayer",
      "esri/geometry/support/webMercatorUtils",
      "dojo/dom",
    ], 

  function init (Map, MapView, Graphic, GraphicsLayer, webMercatorUtils, dom) {
    var map = new Map({
      basemap: "topo-vector"     
    });
    var view = new MapView({
      container: "viewDiv",             
      map: map,
      center: [-80.96135253906438, 35.9411934679851],
      zoom: 3
    });

    var graphicsLayer = new GraphicsLayer();
    map.add(graphicsLayer);  

    var simpleLineSymbol = {
       type: "simple-line",
       color: [13,121,190, .9],
       style: "short-dash",
       width: 3
     };
    var coordinatesAx;
    var coordinatesAy;  
    var coordinatesBx ;
    var coordinatesBy;

    var moveAlong = false;
    var windowElem;

    view.when(function(){
        view.on("pointer-move", showCoordinates);
    });

    // NEW: Stop/start moving the modal along with the pointer by map click
    view.when(function(){
        view.on("click", function () { moveAlong = !moveAlong;});      
    });

    coordinatesAx = -80.96135253906438;
    coordinatesAy = 35.9411934679851;

    document.getElementById("modal").onclick = function fun() {        
        windowElem = document.querySelector('.k-window');        
        moveAlong = true;       
        // Bind Kendo dialog dragstart to movement
        $("#dialog").data('kendoWindow').bind("dragstart", function (ev) {                   
            //graphicsLayer.removeAll();  
            moveAlong = true;
            showCoordinates(ev);            
        })         
    }

   function showCoordinates(evt) {      
      var point = view.toMap({x: evt.x, y: evt.y});
      var mp = webMercatorUtils.webMercatorToGeographic(point);
      dom.byId("info").innerHTML = mp.x.toFixed(3) + ", " + mp.y.toFixed(3);

     coordinatesBx = mp.x.toFixed(3);
     coordinatesBy = mp.y.toFixed(3);

     var polyline = {
       type: "polyline",
       paths: [
         [coordinatesAx, coordinatesAy], 
         [coordinatesBx, coordinatesBy]
       ]
     };
     var polylineGraphic = new Graphic({
       geometry: polyline,
       symbol: simpleLineSymbol
     })

     if (moveAlong) {       
       if (graphicsLayer.graphics.items.length < 0) {
            graphicsLayer.add(polylineGraphic)
       } else {
            // Recreate the line and reposition the modal
            graphicsLayer.removeAll();
            graphicsLayer.add(polylineGraphic)         
            windowElem.style.top = evt.y + 0 + "px";
            windowElem.style.left = evt.x + 0 + "px";
       }       
     }          
   }
});

Attempt B.) Update: I have tried going with this logic I found; although I believe it's arcgis 3.3.. and still can't get it to integrate into my CodePen prototype. Anyways I think this is the logic; just can't seem to get it right.

   $profileWindow = $("#" + elem).parents(".outter-div-wrapper");
        profileWindowOffset = $profileWindow.offset();
        profileWindowWidth = $profileWindow.outerWidth();
        profileWindowHeight = $profileWindow.outerHeight();

        screenPointTopLeft = new Point(profileWindowOffset.left, profileWindowOffset.top, app.ui.mapview.map.spatialReference);
        screenPointTopRight = new Point(profileWindowOffset.left + profileWindowWidth, profileWindowOffset.top, app.ui.mapview.map.spatialReference);
        screenPointBottomLeft = new Point(profileWindowOffset.left, profileWindowOffset.top + profileWindowHeight, app.ui.mapview.map.spatialReference);
        screenPointBottomRight = new Point(profileWindowOffset.left + profileWindowWidth, profileWindowOffset.top + profileWindowHeight, app.ui.mapview.map.spatialReference);

        arrayOfCorners.push(screenPointTopLeft);
        arrayOfCorners.push(screenPointTopRight);
        arrayOfCorners.push(screenPointBottomLeft);
        arrayOfCorners.push(screenPointBottomRight);
        //convert to screenpoint
        graphicsScreenPoint = esri.geometry.toScreenPoint(app.ui.mapview.map.extent, app.ui.mapview.map.width, app.ui.mapview.map.height, self.mapPoint_);

        //find closest Point
        profileWindowScreenPoint = this.findClosest(arrayOfCorners, graphicsScreenPoint);
        //convert from screen point to map point
        profileWindowClosestMapPoint = app.ui.mapview.map.toMap(profileWindowScreenPoint);

        mapProfileWindowPoint.push(profileWindowClosestMapPoint.x);
        mapProfileWindowPoint.push(profileWindowClosestMapPoint.y);

And here is the CodePen with the above attempt added.


Solution

  • Try replacing the JS in your codepen with this code. Needs a bit of work but I think it basically does what you want.

    What I changed was to hook into dragstart and dragend of the modal, and use a mouse motion event handler on the document when dragging the modal. I used the document because the events wouldn't get through the dialog to the view behind it.

    require([
        "esri/Map",
        "esri/views/MapView",
        "esri/Graphic",
        "esri/layers/GraphicsLayer",
        "esri/geometry/support/webMercatorUtils",
        "dojo/dom",
    ],
    
        function init(Map, MapView, Graphic, GraphicsLayer, webMercatorUtils, dom) {
            var map = new Map({
                basemap: "topo-vector"
            });
            var view = new MapView({
                container: "viewDiv",
                map: map,
                center: [-80.96135253906438, 35.9411934679851],
                zoom: 3
            });
    
            var graphicsLayer = new GraphicsLayer();
            map.add(graphicsLayer);
    
            var simpleLineSymbol = {
                type: "simple-line",
                color: [13, 121, 190, .9],
                style: "short-dash",
                width: 3
            };
            // These were const arrays (??)
            var coordinatesAx;
            var coordinatesAy;
            var coordinatesBx;
            var coordinatesBy;
            // Chane to true after the dialog is open and when modal starts dragging
            var moveAlong = false;
            var windowElem;
    
            // view.when(function () {
            //     view.on("pointer-move", showCoordinates);
            // });
    
            // NEW: Stop/start moving the modal along with the pointer by map click
            // view.when(function(){
            //     view.on("click", function () { moveAlong = !moveAlong;});      
            // });
    
            coordinatesAx = -80.96135253906438;
            coordinatesAy = 35.9411934679851;
    
            document.getElementById("modal").onclick = function fun() {
                windowElem = document.querySelector('.k-window');
                // moveAlong = true;       
                // Bind Kendo dialog dragstart to movement
                $("#dialog").data('kendoWindow').bind("dragstart", function (ev) {
                    //graphicsLayer.removeAll();  
                    moveAlong = true;
                    console.log("Dragging");
                    showCoordinates(ev);
                    document.addEventListener("mousemove", showCoordinates);
    
                }).bind("dragend", function (ev) {
                    moveAlong = false;
                    document.removeEventListener("mousemove", showCoordinates);
                    console.log("end Dragging");
                }).bind("close", function (ev) {
                    console.log("Close.  TODO clear line");
                })
            }
    
            function showCoordinates(evt) {
                var point = view.toMap({ x: evt.x, y: evt.y });
                var mp = webMercatorUtils.webMercatorToGeographic(point);
                dom.byId("info").innerHTML = mp.x.toFixed(3) + ", " + mp.y.toFixed(3);
    
                coordinatesBx = mp.x.toFixed(3);
                coordinatesBy = mp.y.toFixed(3);
    
                var polyline = {
                    type: "polyline",
                    paths: [
                        [coordinatesAx, coordinatesAy],
                        [coordinatesBx, coordinatesBy]
                    ]
                };
                var polylineGraphic = new Graphic({
                    geometry: polyline,
                    symbol: simpleLineSymbol
                })
    
                if (moveAlong) {
                    if (graphicsLayer.graphics.items.length < 0) {
                        graphicsLayer.add(polylineGraphic)
                    } else {
                        // Recreate the line and reposition the modal
                        graphicsLayer.removeAll();
                        graphicsLayer.add(polylineGraphic)
                    }
                }
            }
    
    });