## Comparing layers

This example allows comparison of two layers with resizable map panes using the
[Split.js](https://github.com/nathancahill/split/tree/master/packages/splitjs)
library.
<iframe src="https://geo-devrel-javascript-samples.web.app/samples/split-map-panes/app/dist/" allow="fullscreen; "></iframe>

### TypeScript

```typescript
function initMap(): void {
  const mapOptions = {
    center: { lat: 44.5250489, lng: -110.83819 },
    zoom: 18,
    scaleControl: false,
    streetViewControl: false,
  };

  // instantiate the map on the left with control positioning
  mapLeft = new google.maps.Map(
    document.getElementById("map-left") as HTMLElement,
    {
      ...mapOptions,
      mapTypeId: "satellite",
      tilt: 0, // at high zoom levels we need to maintain the same projection
      fullscreenControlOptions: {
        position: google.maps.ControlPosition.LEFT_BOTTOM,
      },
      mapTypeControlOptions: {
        position: google.maps.ControlPosition.LEFT_TOP,
      },
      zoomControlOptions: {
        position: google.maps.ControlPosition.LEFT_BOTTOM,
      },
    }
  );

  // instantiate the map on the right with control positioning
  mapRight = new google.maps.Map(
    document.getElementById("map-right") as HTMLElement,
    {
      ...mapOptions,
      fullscreenControlOptions: {
        position: google.maps.ControlPosition.RIGHT_BOTTOM,
      },
      mapTypeControlOptions: {
        position: google.maps.ControlPosition.RIGHT_TOP,
      },
      zoomControlOptions: {
        position: google.maps.ControlPosition.RIGHT_BOTTOM,
      },
    }
  );

  // helper function to keep maps in sync
  function sync(...maps: google.maps.Map[]) {
    let center: google.maps.LatLng, zoom: number;

    function update(changedMap) {
      maps.forEach((m) => {
        if (m === changedMap) {
          return;
        }

        m.setCenter(center);
        m.setZoom(zoom);
      });
    }

    maps.forEach((m) => {
      m.addListener("bounds_changed", () => {
        const changedCenter = m.getCenter()!;
        const changedZoom = m.getZoom()!;

        if (changedCenter !== center || changedZoom !== zoom) {
          center = changedCenter;
          zoom = changedZoom;
          update(m);
        }
      });
    });
  }

  sync(mapLeft, mapRight);

  function handleContainerResize() {
    const width = (document.getElementById("container") as HTMLElement)
      .offsetWidth;

    (
      document.getElementById("map-left") as HTMLElement
    ).style.width = `${width}px`;
    (
      document.getElementById("map-right") as HTMLElement
    ).style.width = `${width}px`;
  }

  // trigger to set map container size since using absolute
  handleContainerResize();
  // add event listener
  window.addEventListener("resize", handleContainerResize);

  //@ts-ignore
  Split(["#left", "#right"], {
    sizes: [50, 50],
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;
```

> [!NOTE]
> **Note:** Read the [guide](https://developers.google.com/maps/documentation/javascript/using-typescript.md.txt) on using TypeScript and Google Maps.

### JavaScript

```javascript
function initMap() {
  const mapOptions = {
    center: { lat: 44.5250489, lng: -110.83819 },
    zoom: 18,
    scaleControl: false,
    streetViewControl: false,
  };

  // instantiate the map on the left with control positioning
  mapLeft = new google.maps.Map(document.getElementById("map-left"), {
    ...mapOptions,
    mapTypeId: "satellite",
    tilt: 0, // at high zoom levels we need to maintain the same projection
    fullscreenControlOptions: {
      position: google.maps.ControlPosition.LEFT_BOTTOM,
    },
    mapTypeControlOptions: {
      position: google.maps.ControlPosition.LEFT_TOP,
    },
    zoomControlOptions: {
      position: google.maps.ControlPosition.LEFT_BOTTOM,
    },
  });
  // instantiate the map on the right with control positioning
  mapRight = new google.maps.Map(document.getElementById("map-right"), {
    ...mapOptions,
    fullscreenControlOptions: {
      position: google.maps.ControlPosition.RIGHT_BOTTOM,
    },
    mapTypeControlOptions: {
      position: google.maps.ControlPosition.RIGHT_TOP,
    },
    zoomControlOptions: {
      position: google.maps.ControlPosition.RIGHT_BOTTOM,
    },
  });

  // helper function to keep maps in sync
  function sync(...maps) {
    let center, zoom;

    function update(changedMap) {
      maps.forEach((m) => {
        if (m === changedMap) {
          return;
        }

        m.setCenter(center);
        m.setZoom(zoom);
      });
    }

    maps.forEach((m) => {
      m.addListener("bounds_changed", () => {
        const changedCenter = m.getCenter();
        const changedZoom = m.getZoom();

        if (changedCenter !== center || changedZoom !== zoom) {
          center = changedCenter;
          zoom = changedZoom;
          update(m);
        }
      });
    });
  }

  sync(mapLeft, mapRight);

  function handleContainerResize() {
    const width = document.getElementById("container").offsetWidth;

    document.getElementById("map-left").style.width = `${width}px`;
    document.getElementById("map-right").style.width = `${width}px`;
  }

  // trigger to set map container size since using absolute
  handleContainerResize();
  // add event listener
  window.addEventListener("resize", handleContainerResize);
  //@ts-ignore
  Split(["#left", "#right"], {
    sizes: [50, 50],
  });
}

window.initMap = initMap;
```

> [!NOTE]
> **Note:** The JavaScript is compiled from the TypeScript snippet.

### CSS

```css
/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#container,
#left,
#right,
.map,
.gutter {
  height: 100%;
}

#left,
#right,
.gutter {
  float: left;
  position: relative;
  overflow: hidden;
}

#map-left {
  position: absolute;
  left: 0;
  top: 0;
}

#map-right {
  position: absolute;
  right: 0;
  top: 0;
}

.gutter {
  background-color: #eee;
  background-repeat: no-repeat;
  background-position: 50%;
}

.gutter.gutter-horizontal {
  cursor: col-resize;
  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==");
}
```

### HTML

```html
<html>
  <head>
    <title>Split Map Panes</title>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/split.js/1.5.11/split.min.js"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="container">
      <div id="left">
        <div id="map-left" class="map"></div>
      </div>
      <div id="right">
        <div id="map-right" class="map"></div>
      </div>
    </div>

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>
```

### Clone Sample


Git and Node.js are required to run this sample locally. Follow these [instructions](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) to install Node.js and NPM. The following commands clone, install dependencies and start the sample application.

```javascript
  git clone -b sample-split-map-panes https://github.com/googlemaps/js-samples.git
  cd js-samples
  npm i
  npm start
```


Other samples can be tried by switching to any branch beginning with `sample-SAMPLE_NAME`.

```javascript
  git checkout sample-SAMPLE_NAME
  npm i
  npm start
```