Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Google Maps JavaScript API v3 Example: Place Photos</title>
    <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
  <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
  <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places"></script>
    
    <script>
      var markers = [];
  
      function initialize() {
        var map = new google.maps.Map(document.getElementById('map-canvas'), {
          mapTypeId: google.maps.MapTypeId.ROADMAP,
          maxZoom: 16,
          styles: [
            {
              elementType: 'labels',
              stylers: [ { visibility: 'on' } ]
            },
            {
              stylers: [ { saturation: -100 }, { lightness: -20 } ]
            }
          ]
        });
        var defaultBounds = new google.maps.LatLngBounds(
            new google.maps.LatLng(-33.8902, 151.1759),
            new google.maps.LatLng(-33.8474, 151.2631));
        map.fitBounds(defaultBounds);
        var input = document.getElementById('target');
        var searchBox = new google.maps.places.SearchBox(input);
        searchBox.setBounds(map.getBounds());
        var modalWindow = new ModalWindow(map);
        google.maps.event.addListener(searchBox, 'places_changed', function() {
          var places = searchBox.getPlaces();
          if (!places.length) {
            return;
          }
          for (var i = 0, marker; marker = markers[i]; i++) {
            marker.setMap(null);
          }
          markers = [];
          var bounds = new google.maps.LatLngBounds();
          for (var i = 0, place; place = places[i]; i++) {
            if (place.photos) {
              markers.push(new PhotoMarker(place, map, modalWindow));
            } else {
              markers.push(new google.maps.Marker({
                position: place.geometry.location,
                map: map,
                icon: new google.maps.MarkerImage(
                    'https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle.png',
                    null, null, new google.maps.Point(3.5,3.5)),
                clickable: false
              }));
            }
            bounds.extend(place.geometry.location);
          }
          map.fitBounds(bounds);
        });
        google.maps.event.addListener(map, 'bounds_changed', function() {
          searchBox.setBounds(map.getBounds());
        });
      }
      /* Photo Marker */
      function PhotoMarker(place, map, modalWindow) {
        this.modalWindow_ = modalWindow;
        this.place_ = place;
        this.setMap(map);
      }
      PhotoMarker.prototype = new google.maps.OverlayView();
      PhotoMarker.prototype.onAdd = function() {
        this.img_ = document.createElement('img');
        this.img_.className = 'photo-marker';
        this.img_.title = this.place_.name;
        this.img_.src = this.place_.photos[0].getUrl({
            'maxWidth': 35,
            'maxHeight': 35
        });
        this.getPanes().overlayImage.appendChild(this.img_);
        var that = this;
        google.maps.event.addDomListener(this.img_, 'click', function() {
          that.modalWindow_.getDetails(that.place_);
        });
      };
      PhotoMarker.prototype.draw = function() {
        var that = this;
        if (!this.img_ || (this.img_ && !this.img_.complete)) {
          window.clearTimeout(this.imgLoader_);
          this.imgLoader_ = window.setTimeout(function() {
              that.draw();
          }, 50);
          return;
        }
        var proj = this.getProjection();
        var pos = proj.fromLatLngToDivPixel(this.place_.geometry.location);
        var w = this.img_.offsetWidth;
        var h = this.img_.offsetHeight;
        this.img_.style.left = Math.floor(pos.x - w / 2) + 'px';
        this.img_.style.top = Math.floor(pos.y - h / 2) + 'px';
      };
      PhotoMarker.prototype.onRemove = function() {
        this.img_.parentNode.removeChild(this.img_);
        this.img_ = null;
      };
      /* Modal Window */
      function ModalWindow(map) {
        this.service_ = new google.maps.places.PlacesService(map);
        this.createDOMElements_();
        this.addEventListeners_();
      }
      ModalWindow.prototype.createDOMElements_ = function() {
        this.modal_ = document.createElement('div');
        this.modal_.id = 'modal';
        document.body.appendChild(this.modal_);
        var modalWindow = document.createElement('div');
        modalWindow.id = 'window';
        this.modal_.appendChild(modalWindow);
        var close = document.createElement('img');
        close.id = 'close';
        close.className = 'close';
        close.src = '../images/close.png';
        close.alt = 'Close window';
        modalWindow.appendChild(close);
        this.info_ = document.createElement('div');
        this.info_.id = 'info';
        modalWindow.appendChild(this.info_);
        this.photo_ = document.createElement('div');
        this.photo_.id = 'photo';
        modalWindow.appendChild(this.photo_);
        this.photos_ = document.createElement('div');
        this.photos_.id = 'photos';
        modalWindow.appendChild(this.photos_);
        this.attribution_ = document.createElement('div');
        this.attribution_.id = 'attribution';
        modalWindow.appendChild(this.attribution_);
        var mask = document.createElement('div');
        mask.id = 'mask';
        this.modal_.appendChild(mask);
      };
      ModalWindow.prototype.addEventListeners_ = function() {
        var that = this;
        google.maps.event.addDomListener(this.modal_, 'click', function(e) {
          if (e.target && (e.target.id == 'close' || e.target.id == 'mask')) {
            that.hideWindow_();
          }
        });
        google.maps.event.addDomListener(document, 'keyup', function(e) {
          // Esc key
          if (e.keyCode == 27) {
            that.hideWindow_();
          }
        });
      };
      ModalWindow.prototype.getDetails = function(place) {
        if (this.place_ && place.id == this.place_.id) {
          this.showWindow_();
          return;
        }
        var that = this;
        this.service_.getDetails({'reference': place.reference},
            function(details, status) {
          if (status != google.maps.places.PlacesServiceStatus.OK) {
            return;
          }
          that.place_ = place;
          that.details_ = details;
          that.createContent_();
          that.showWindow_();
        });
      };
      ModalWindow.prototype.createContent_ = function(place, status) {
        this.createInfo_();
        this.createPhoto_(this.place_.photos[0]);
        this.createThumbnails_();
        this.createAttribution_(this.place_.photos[0]);
      };
      ModalWindow.prototype.createPhoto_ = function(photo) {
        this.photo_.innerHTML = '';
        var img = document.createElement('img');
        img.src = photo.getUrl({'maxWidth': 480, 'maxHeight': 246});
        this.photo_.appendChild(img);
      };
      ModalWindow.prototype.createInfo_ = function() {
        this.info_.innerHTML = '';
        var name = document.createElement('h3');
        name.innerHTML = this.place_.name;
        this.info_.appendChild(name);
        var address = document.createElement('p');
        address.innerHTML = this.place_.formatted_address;
        this.info_.appendChild(address);
      };
      ModalWindow.prototype.createThumbnails_ = function() {
        this.photos_.innerHTML = '';
        for (var i = 0; i < this.details_.photos.length; i++) {
          var thumbnail = document.createElement('img');
          thumbnail.id = i;
          thumbnail.src = this.details_.photos[i].getUrl({'maxWidth': 88,
              'maxHeight': 88});
          this.photos_.appendChild(thumbnail);
        }
        this.photos_.firstChild.className = 'selected';
        this.selected_ = this.photos_.firstChild;
        var that = this;
        google.maps.event.addDomListener(this.photos_, 'click', function(e) {
          if (e.target && e.target.nodeName == 'IMG' &&
              e.target.className != 'selected') {
            that.changeSelected_(e.target);
          }
        });
      };
      ModalWindow.prototype.changeSelected_ = function(thumbnail) {
        this.selected_.className = '';
        thumbnail.className = 'selected';
        this.selected_ = thumbnail;
        this.createPhoto_(this.details_.photos[thumbnail.id]);
        this.createAttribution_(this.details_.photos[thumbnail.id]);
      };
      ModalWindow.prototype.createAttribution_ = function(photo) {
        this.attribution_.innerHTML = '';
        if (photo.html_attributions.length) {
          this.attribution_.innerHTML = photo.html_attributions[0];
          var link = this.attribution_.getElementsByTagName('a');
          if (link[0]) {
            link[0].target = '_blank';
          }
        }
      };
      ModalWindow.prototype.showWindow_ = function() {
        this.modal_.style.display = 'block';
      };
      ModalWindow.prototype.hideWindow_ = function() {
        this.modal_.style.display = 'none';
      };
      
      google.maps.event.addDomListenerOnce(window, 'load', initialize);
    </script>
    <style>
      html, body {
        font-size: 14px;
        font-family: Arial, Helvetica, sans-serif;
        height: 100%;
        margin: 0;
        padding: 0;
      }
      input {
        font-size: 16px;
        font-family: Arial, Helvetica, sans-serif;
      }
      h3 {
        margin: 0 0 5px 0;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }
      p {
        margin: 0 0 10px 0;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }
      .photo-marker {
        display: block;
        border-radius: 2px;
        -moz-border-radius: 2px;
        -webkit-border-radius: 2px;
        border: 2px solid #eee;
        box-shadow: rgba(255, 255, 255, 0.4) 0 2px 4px;
        -moz-box-shadow: rgba(255, 255, 255, 0.4) 0 2px 4px;
        -webkit-box-shadow: rgba(255, 255, 255, 0.4) 0 2px 4px;
        cursor: pointer;
        position: absolute;
        z-index: 0;
      }
      .photo-marker:hover {
        z-index: 1;
      }
      img.close {
        cursor: pointer;
        width: 38px;
        height: 38px;
        float: right;
        margin-left: 10px;
      }
      #map-canvas {
        height: 100%;
      }
      #target {
        width: 345px;
        outline: none;
        border: 1px solid #fff;
        position: absolute;
        top: 5px;
        left: 50%;
        margin-left: -181px;
        width: 350px;
        z-index: 1000;
        background-color: #fff;
        padding: 5px;
        border-radius: 2px;
        -moz-border-radius: 2px;
        -webkit-border-radius: 2px;
        box-shadow: rgba(255, 255, 255, 0.4) 0 2px 4px;
        -moz-box-shadow: rgba(255, 255, 255, 0.4) 0 2px 4px;
        -webkit-box-shadow: rgba(255, 255, 255, 0.4) 0 2px 4px;
      }
      /* Modal Window styles */
      #modal {
        display: none;
      }
      #mask {
        position: fixed;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        z-index: 1001;
        background: #fff;
        display: block;
        opacity: 0.5;
      }
      #window {
        width: 578px;
        height: 298px;
        position: fixed;
        display: block;
        z-index: 1002;
        border: 1px solid #dcdcdc;
        padding: 10px;
        background: #fff;
        border-radius: 2px;
        -moz-border-radius: 2px;
        -webkit-border-radius: 2px;
        box-shadow: rgba(0, 0, 0, 0.2) 0 0 40px;
        -moz-box-shadow: rgba(0, 0, 0, 0.2) 0 0 40px;
        -webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 0 40px;
        left: 50%;
        top: 50%;
        margin-left: -300px;
        margin-top: -160px;
      }
      #photo {
        height: 246px;
        width: 480px;
        line-height: 243px;
        text-align: center;
        margin: 0 10px 0 0;
        background: #000;
        float: left;
      }
      #photo img {
        display: inline-block;
        vertical-align: middle;
      }
      #attribution {
        user-select: none;
        -ms-user-select: none;
        -moz-user-select: none;
        -webkit-user-select: none;
        line-height: 19px;
        padding-right: 2px;
        padding-left: 50px;
        background-image:
          linear-gradient(left,
            rgba(255, 255, 255, 0) 0,
            rgba(255, 255, 255, 0.5) 50px);
        background-image:
          -ms-linear-gradient(left,
            rgba(255, 255, 255, 0) 0,
            rgba(255, 255, 255, 0.5) 50px);
        background-image:
          -moz-linear-gradient(left,
            rgba(255, 255, 255, 0) 0,
            rgba(255, 255, 255, 0.5) 50px);
        background-image:
          -webkit-linear-gradient(left,
            rgba(255, 255, 255, 0) 0,
            rgba(255, 255, 255, 0.5) 50px);
        font-size: 10px;
        color: #444;
        margin-bottom: 10px;
        position: absolute;
        bottom: 0;
        right: 108px;
      }
      #attribution a {
        color: #444;
      }
      #left {
        width:300px;
        height:100%;
          float:left;
      }
      #photos {
        float: left;
        width: 88px;
        overflow: hidden;
        overflow-y: auto;
        height: 246px;
        text-align: center;
      }
      #photos img {
        opacity: 0.7;
        margin: 0 0 10px 0;
        cursor: pointer;
        box-sizing: border-box;
        -moz-box-sizing: border-box;
        -webkit-box-sizing: border-box;
        vertical-align: middle;
      }
      #photos img:nth-last-child(1) {
        margin: 0;
      }
      #photos img:hover {
        opacity: 0.9;
      }
      #photos img.selected {
        opacity: 1;
        cursor: default;
      }
    </style>
    <script>
      
$(function() {
    $( "#photo" ).resizable();
  $( "#photo" ).draggable({revert: 'invalid'});
    $( "#left" ).droppable({
      accept: '#photo',
      drop: function( event, ui ) {
        $( this )
          .find( "p" )
            .html( "Dropped!" );
      }
    });
  });    
    </script>
  </head>
  <body>
    <div id="left"></div>
    <input id="target" type="text" placeholder="Search Box">
    <div id="map-canvas"></div>
  </body>
</html>
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers