set basemap opacity with slider

5793
3
09-22-2011 11:39 AM
DougCollins
Occasional Contributor
Greetings,

Is there a way using the ESRI Javascript API to allow the user to dynamically adjust a basemap's opacity using a slider?  The ESRI Silverlight API allows the user to dynamically fade from one basemap to another using a slider.  Is this possible to do using the Javascript API?

Thanks,
Charlie
0 Kudos
3 Replies
derekswingley1
Frequent Contributor
Of course ;).

There used to be a sample somewhere but I've lost track of it. I spent a little time putting together a new sample that shows this:
<!doctype html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
    <!--The viewport meta tag is used to improve the presentation and behavior of the samples 
      on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <title>Basemaps with an Opacity Slider</title>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.4/js/dojo/dijit/themes/nihilo/nihilo.css">
    <style>
      html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
      #map{ padding: 0; }
      
      #sliderWrapper {
        position:absolute; 
        right: 30px; 
        top:30px; 
        z-Index: 40;

        width: 250px;
        height: 50px;
        background: #fff;
        -moz-box-shadow: 0 0 5px #888;
        -webkit-box-shadow: 0 0 5px #888;
        box-shadow: 0 0 5px #888;
      }
      #sliderLabels {
        position: relative; 
        top: -1px; 
        height: 1.2em; 
        font-size: 80%; 
        font-weight: bold;
        font-family: arial;
        color: #444;
        padding: 3px;
        margin: 5px 10px 0 10px;
      }
    </style>
    <script type="text/javascript">var dojoConfig = { parseOnLoad: true };</script>
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.4"></script>
    <script type="text/javascript">
      dojo.require("esri.map");
      dojo.require("dijit.layout.BorderContainer");
      dojo.require("dijit.layout.ContentPane");
      
      // one global for all app vars
      var app = {};

      function init() {
        var ext = new esri.geometry.Extent({"xmin":-14628212,"ymin":714227,"xmax":7718305,"ymax":9832858,"spatialReference":{"wkid":102100}});
        app.map = new esri.Map("map", { extent: ext });

        app.imagery = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer");
        app.map.addLayer(app.imagery);
        app.streets = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
        app.map.addLayer(app.streets);

        dojo.connect(dijit.byId('sliderOpacity'), 'onChange', changeOpacity);
           
        var resizeTimer;
        dojo.connect(app.map, 'onLoad', function(theMap) {
          dojo.connect(dijit.byId('map'), 'resize', function() {  //resize the map if the div is resized
            clearTimeout(resizeTimer);
            resizeTimer = setTimeout( function() {
              app.map.resize();
              app.map.reposition();
            }, 500);
          });
        });
      }

      function changeOpacity(op) {
    var newOp = (op / 100);
    app.streets.setOpacity(1.0 - newOp);
        app.imagery.setOpacity(newOp);
   }
    dojo.ready(init);
    </script>

  </head>
  <body class="nihilo">
    <div data-dojo-type="dijit.layout.BorderContainer" 
         data-dojo-props="design:'headline',gutters:false" 
         style="width: 100%; height: 100%; margin: 0;">
      
      <div id="map" 
           data-dojo-type="dijit.layout.ContentPane" 
           data-dojo-props="region:'center'"> 

        <div id="sliderWrapper"> <!-- slider divs -->

          <div id="sliderOpacity" 
               data-dojo-type="dijit.form.HorizontalSlider" 
               data-dojo-props="showButtons:'true', value:0, minimum:0, maximum:100, discreteValues:101, intermediateChanges:true">                    
            <ol id="sliderLabels" 
                data-dojo-type="dijit.form.HorizontalRuleLabels" 
                data-dojo-props="container:'topDecoration'">
              <li>Streets</li>
              <li>Satellite</li>
            </ol>
          </div>
        </div> <!-- end slider divs -->

      </div>

    </div>
  </body>
</html>


We should probably put this in the official samples...
JohnGravois
Frequent Contributor
i went ahead and updated this sample to use AMD/version 3.8 of our API and on style event listeners.

http://jsfiddle.net/jagravois/3rZK5/

<!doctype html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <!--The viewport meta tag is used to improve the presentation and behavior of the samples 
      on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <title>Basemaps with an Opacity Slider</title>
    <link rel="stylesheet" type="text/css" href="http://js.arcgis.com/3.8/js/dojo/dijit/themes/nihilo/nihilo.css">
    <link rel="stylesheet" type="text/css" href="http://js.arcgis.com/3.8/js/esri/css/esri.css">
    <style>
      html, body { height: 100%; width: 100%; margin: 0; padding: 0; }      
      
      #map{ padding: 0; }
      
      #sliderWrapper {
        position:absolute; 
        right: 30px; 
        top:30px; 
        z-Index: 40;

        width: 250px;
        height: 50px;
        background: #fff;
        -moz-box-shadow: 0 0 5px #888;
        -webkit-box-shadow: 0 0 5px #888;
        box-shadow: 0 0 5px #888;
      }
      #sliderLabels {
        position: relative; 
        top: -1px; 
        height: 1.2em; 
        font-size: 80%; 
        font-weight: bold;
        font-family: arial;
        color: #444;
        padding: 3px;
        margin: 5px 10px 0 10px;
      }
    </style>
    <script type="text/javascript">var dojoConfig = { parseOnLoad: true };</script>
    <script type="text/javascript" src="http://js.arcgis.com/3.8/"></script>
    <script type="text/javascript">
      require([
        "esri/map",
            "esri/layers/ArcGISTiledMapServiceLayer",
            
            "dojo/on",
            "dijit/registry",
        "dijit/layout/BorderContainer",
        "dijit/layout/ContentPane",
            "dijit/form/HorizontalSlider",
            "dijit/form/HorizontalRuleLabels"],
       function (Map, ArcGISTiledMapServiceLayer, on, registry) {      
       
            var map = new esri.Map("map", {
                    center: [-80,20],
                    zoom: 3
                });

            var oceans = new ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer");
            map.addLayer(oceans);
            var streets = new ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
            map.addLayer(streets);

            
            //wire an event handler for the dojo slider
            map.on("load", function() {
              on(registry.byId('sliderOpacity'), 'change', changeOpacity);
            });

            function changeOpacity(op) {
                var newOp = (op / 100);
                streets.setOpacity(1.0 - newOp);
                oceans.setOpacity(newOp);
            }

       });      
    </script>

  </head>
  <body class="nihilo">
    <div data-dojo-type="dijit/layout/BorderContainer" 
         data-dojo-props="design:'headline',gutters:false" 
         style="width: 100%; height: 100%; margin: 0;">
      
      <div id="map" 
           data-dojo-type="dijit/layout/ContentPane" 
           data-dojo-props="region:'center'"
           style="width: 100%; height: 100%; margin: 0;"> 

        <div id="sliderWrapper"> <!-- slider divs -->

          <div id="sliderOpacity" 
               data-dojo-type="dijit/form/HorizontalSlider" 
               data-dojo-props="showButtons:'true', value:0, minimum:0, maximum:100, discreteValues:101, intermediateChanges:true">                    
            <ol id="sliderLabels" 
                data-dojo-type="dijit/form/HorizontalRuleLabels" 
                data-dojo-props="container:'topDecoration'">
              <li>Streets</li>
              <li>Oceans</li>
            </ol>
          </div>
        </div> <!-- end slider divs -->
        
      </div>

    </div>
  </body>
</html>
MatejTacer
New Contributor III
This is nice if you add baseMaplayer manually as a separate layer.
Is this possible with baseMap gallery widget?

I'd like to add a slider that would set opacity on whichever baseMap layer has been selected from the widget.

edited:
just figured it out. this is one way of doing it:  map.getLayer(map.basemapLayerIds).setOpacity(0.1);
0 Kudos