Control the position of the camera

The map view is modeled as a camera looking down on a flat plane. The position of the camera (and hence the rendering of the map) is specified by the following properties: latitude , longitude , altitude , heading , tilt , range , and fov .

The camera target is the location of the center of the map, specified as latitude and longitude coordinates. You can specify the camera's position in two ways:

  • By target point: Use the center property to specify a coordinate on the map that the camera should face. This is best when you want to ensure a landmark or area is in focus.
  • By camera coordinates: Use the cameraPosition property to place the camera at specific latitude, longitude, and altitude coordinates. This is ideal for defining a precise viewpoint.

Logically, center and cameraPosition are linked. When you set one, the other is automatically calculated based on the camera's orientation and distance. Properties like tilt , heading , and roll control how the camera is aimed, regardless of which positioning method you use.

The following example lets you toggle between center (camera looking at the map center) and cameraPosition (camera positioned at the map center).

See the complete example source code

TypeScript

 async 
  
 function 
  
 init 
 () 
 : 
  
 Promise<void> 
  
 { 
  
 // Import the needed libraries. 
  
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'maps3d' 
 ); 
  
 const 
  
 map3DElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-map-3d' 
 ) 
 ! 
 ; 
  
 const 
  
 btn 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'switch-mode-btn' 
 ) 
  
 as 
  
 HTMLButtonElement 
 ; 
  
 const 
  
 initialCenter 
  
 = 
  
 { 
  
 lat 
 : 
  
 40.7860524 
 , 
  
 lng 
 : 
  
 - 
 73.9634983 
 , 
  
 altitude 
 : 
  
 0 
  
 }; 
  
 let 
  
 isCenterMode 
  
 = 
  
 true 
 ; 
  
 btn 
 . 
 addEventListener 
 ( 
 'click' 
 , 
  
 () 
  
 = 
>  
 { 
  
 if 
  
 ( 
 isCenterMode 
 ) 
  
 { 
  
 // Switch to Camera Position Mode. 
  
 // Place the camera at the marker's location, but 50m up in the air 
  
 map3DElement 
 . 
 cameraPosition 
  
 = 
  
 { 
  
 ... 
 initialCenter 
 , 
  
 altitude 
 : 
  
 50 
  
 }; 
  
 map3DElement 
 . 
 tilt 
  
 = 
  
 80 
 ; 
  
 btn 
 . 
 textContent 
  
 = 
  
 'Switch to Center Mode' 
 ; 
  
 isCenterMode 
  
 = 
  
 false 
 ; 
  
 } 
  
 else 
  
 { 
  
 // Revert back to Center Mode (looking AT the marker) 
  
 map3DElement 
 . 
 center 
  
 = 
  
 initialCenter 
 ; 
  
 map3DElement 
 . 
 tilt 
  
 = 
  
 70 
 ; 
  
 map3DElement 
 . 
 range 
  
 = 
  
 1500 
 ; 
  
 // Restore the original range value. 
  
 btn 
 . 
 textContent 
  
 = 
  
 'Switch to Camera Position' 
 ; 
  
 isCenterMode 
  
 = 
  
 true 
 ; 
  
 } 
  
 }); 
 } 
 void 
  
 init 
 (); 
  

JavaScript

 async 
  
 function 
  
 init 
 () 
  
 { 
  
 // Import the needed libraries. 
  
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'maps3d' 
 ); 
  
 const 
  
 map3DElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-map-3d' 
 ); 
  
 const 
  
 btn 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'switch-mode-btn' 
 ); 
  
 const 
  
 initialCenter 
  
 = 
  
 { 
  
 lat 
 : 
  
 40.7860524 
 , 
  
 lng 
 : 
  
 - 
 73.9634983 
 , 
  
 altitude 
 : 
  
 0 
  
 }; 
  
 let 
  
 isCenterMode 
  
 = 
  
 true 
 ; 
  
 btn 
 . 
 addEventListener 
 ( 
 'click' 
 , 
  
 () 
  
 = 
>  
 { 
  
 if 
  
 ( 
 isCenterMode 
 ) 
  
 { 
  
 // Switch to Camera Position Mode. 
  
 // Place the camera at the marker's location, but 50m up in the air 
  
 map3DElement 
 . 
 cameraPosition 
  
 = 
  
 { 
  
 ... 
 initialCenter 
 , 
  
 altitude 
 : 
  
 50 
  
 }; 
  
 map3DElement 
 . 
 tilt 
  
 = 
  
 80 
 ; 
  
 btn 
 . 
 textContent 
  
 = 
  
 'Switch to Center Mode' 
 ; 
  
 isCenterMode 
  
 = 
  
 false 
 ; 
  
 } 
  
 else 
  
 { 
  
 // Revert back to Center Mode (looking AT the marker) 
  
 map3DElement 
 . 
 center 
  
 = 
  
 initialCenter 
 ; 
  
 map3DElement 
 . 
 tilt 
  
 = 
  
 70 
 ; 
  
 map3DElement 
 . 
 range 
  
 = 
  
 1500 
 ; 
  
 // Restore the original range value. 
  
 btn 
 . 
 textContent 
  
 = 
  
 'Switch to Camera Position' 
 ; 
  
 isCenterMode 
  
 = 
  
 true 
 ; 
  
 } 
  
 }); 
 } 
 void 
  
 init 
 (); 
  

CSS

 html 
 , 
 body 
  
 { 
  
 height 
 : 
  
 100 
 % 
 ; 
  
 margin 
 : 
  
 0 
 ; 
  
 padding 
 : 
  
 0 
 ; 
 } 
 # 
 ui-container 
  
 { 
  
 position 
 : 
  
 absolute 
 ; 
  
 top 
 : 
  
 20 
 px 
 ; 
  
 left 
 : 
  
 20 
 px 
 ; 
  
 z-index 
 : 
  
 10 
 ; 
 } 
 button 
  
 { 
  
 background 
 : 
  
 rgba 
 ( 
 15 
 , 
  
 23 
 , 
  
 42 
 , 
  
 0.75 
 ); 
  
 backdrop-filter 
 : 
  
 blur 
 ( 
 12 
 px 
 ); 
  
 -webkit- 
 backdrop-filter 
 : 
  
 blur 
 ( 
 12 
 px 
 ); 
  
 border 
 : 
  
 1 
 px 
  
 solid 
  
 rgba 
 ( 
 255 
 , 
  
 255 
 , 
  
 255 
 , 
  
 0.1 
 ); 
  
 color 
 : 
  
 #f8fafc 
 ; 
  
 padding 
 : 
  
 12 
 px 
  
 20 
 px 
 ; 
  
 border-radius 
 : 
  
 8 
 px 
 ; 
  
 cursor 
 : 
  
 pointer 
 ; 
  
 font-size 
 : 
  
 0.9 
 rem 
 ; 
  
 font-weight 
 : 
  
 600 
 ; 
  
 transition 
 : 
  
 all 
  
 0.2 
 s 
  
 ease 
 ; 
  
 box-shadow 
 : 
  
 0 
  
 8 
 px 
  
 32 
 px 
  
 0 
  
 rgba 
 ( 
 0 
 , 
  
 0 
 , 
  
 0 
 , 
  
 0.37 
 ); 
 } 
 button 
 : 
 hover 
  
 { 
  
 background 
 : 
  
 rgba 
 ( 
 56 
 , 
  
 189 
 , 
  
 248 
 , 
  
 0.2 
 ); 
  
 border-color 
 : 
  
 rgba 
 ( 
 56 
 , 
  
 189 
 , 
  
 248 
 , 
  
 0.4 
 ); 
  
 transform 
 : 
  
 translateY 
 ( 
 -1 
 px 
 ); 
 } 
 button 
 : 
 active 
  
 { 
  
 transform 
 : 
  
 translateY 
 ( 
 0 
 ); 
 } 
  

HTML

<html>
    <head>
        <title>3D Camera Position</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <script>
            // prettier-ignore
            (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
                key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8" 
            });
        </script>
    </head>

    <body>
        <gmp-map-3d
            center="40.7860524,-73.9634983"
            range="1500"
            tilt="70"
            heading="-150"
            mode="satellite">
            <gmp-marker
                position="40.7860524,-73.9634983"
                altitude-mode="clamp-to-ground"></gmp-marker>
        </gmp-map-3d>

        <div id="ui-container">
            <button id="switch-mode-btn" type="button">
                Switch to Camera Position
            </button>
        </div>
    </body>
</html>  

Try Sample

Field of view and range

In a 3D environment, the concept of "zoom" is controlled by two distinct parameters: range and fov (field of view). While both affect how large objects appear on the map, they do so using different mechanics:

  • range : The physical distance between the camera and its center point. Adjusting the range is like moving a camera closer to or further away from a subject.
  • fov : The vertical angle of the camera lens, measured in degrees. Adjusting the field of view is equivalent to changing the lens on a camera. A higher value (up to 80 degrees) acts like a wide-angle lens, showing more of the periphery, while a lower value (down to 5 degrees) acts like a telephoto lens and narrows the focus.

The following example lets you experiment to see how the various map and camera positioning options work together. Set parameters using the UI sliders, or interact directly with the map and map controls. The resulting parameters are added to a gmp-map-3d element that you can copy and reuse.

See the complete example source code

TypeScript

 async 
  
 function 
  
 initMap 
 () 
 : 
  
 Promise<void> 
  
 { 
  
 // Declare the needed libraries. 
  
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'maps3d' 
 ); 
  
 const 
  
 map3DElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-map-3d' 
 ) 
 ! 
 ; 
  
 // Elements from HTML 
  
 const 
  
 headingSlider 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
  
 'heading' 
  
 ) 
  
 as 
  
 HTMLInputElement 
 ; 
  
 const 
  
 tiltSlider 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'tilt' 
 ) 
  
 as 
  
 HTMLInputElement 
 ; 
  
 const 
  
 rangeSlider 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'range' 
 ) 
  
 as 
  
 HTMLInputElement 
 ; 
  
 const 
  
 latSlider 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'lat' 
 ) 
  
 as 
  
 HTMLInputElement 
 ; 
  
 const 
  
 lngSlider 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'lng' 
 ) 
  
 as 
  
 HTMLInputElement 
 ; 
  
 const 
  
 fovSlider 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'fov' 
 ) 
  
 as 
  
 HTMLInputElement 
 ; 
  
 const 
  
 rollSlider 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'roll' 
 ) 
  
 as 
  
 HTMLInputElement 
 ; 
  
 const 
  
 headingVal 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'heading-val' 
 ) 
 ! 
 ; 
  
 const 
  
 tiltVal 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'tilt-val' 
 ) 
 ! 
 ; 
  
 const 
  
 rangeVal 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'range-val' 
 ) 
 ! 
 ; 
  
 const 
  
 altitudeVal 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'altitude-val' 
 ) 
 ! 
 ; 
  
 const 
  
 fovVal 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'fov-val' 
 ) 
 ! 
 ; 
  
 const 
  
 rollVal 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'roll-val' 
 ) 
 ! 
 ; 
  
 const 
  
 codeElem 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'generated-code' 
 ) 
 ! 
 ; 
  
 const 
  
 copyBtn 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'copy-btn' 
 ) 
  
 as 
  
 HTMLButtonElement 
 ; 
  
 let 
  
 currentAltitude 
  
 = 
  
 30 
 ; 
  
 let 
  
 isUserInteracting 
  
 = 
  
 false 
 ; 
  
 // Update values on UI when the map changes. 
  
 const 
  
 updateUI 
  
 = 
  
 () 
  
 = 
>  
 { 
  
 const 
  
 heading 
  
 = 
  
 map3DElement 
 . 
 heading 
 ? 
 . 
 toFixed 
 ( 
 0 
 ) 
  
 ?? 
  
 '0' 
 ; 
  
 const 
  
 tilt 
  
 = 
  
 map3DElement 
 . 
 tilt 
 ? 
 . 
 toFixed 
 ( 
 0 
 ) 
  
 ?? 
  
 '0' 
 ; 
  
 const 
  
 range 
  
 = 
  
 map3DElement 
 . 
 range 
 ? 
 . 
 toFixed 
 ( 
 0 
 ) 
  
 ?? 
  
 '0' 
 ; 
  
 const 
  
 rawFov 
  
 = 
  
 parseFloat 
 ( 
 map3DElement 
 . 
 fov 
 ? 
 . 
 toFixed 
 ( 
 0 
 ) 
  
 ?? 
  
 '45' 
 ); 
  
 const 
  
 fovClamped 
  
 = 
  
 Math 
 . 
 min 
 ( 
 80 
 , 
  
 Math 
 . 
 max 
 ( 
 5 
 , 
  
 rawFov 
 )); 
  
 const 
  
 fov 
  
 = 
  
 fovClamped 
 . 
 toString 
 (); 
  
 const 
  
 roll 
  
 = 
  
 map3DElement 
 . 
 roll 
 ? 
 . 
 toFixed 
 ( 
 0 
 ) 
  
 ?? 
  
 '0' 
 ; 
  
 const 
  
 center 
  
 = 
  
 map3DElement 
 . 
 center 
 ; 
  
 const 
  
 mode 
  
 = 
  
 map3DElement 
 . 
 mode 
 ; 
  
 headingVal 
 . 
 textContent 
  
 = 
  
 heading 
 ; 
  
 tiltVal 
 . 
 textContent 
  
 = 
  
 tilt 
 ; 
  
 rangeVal 
 . 
 textContent 
  
 = 
  
 range 
 ; 
  
 fovVal 
 . 
 textContent 
  
 = 
  
 fov 
 ; 
  
 rollVal 
 . 
 textContent 
  
 = 
  
 roll 
 ; 
  
 if 
  
 ( 
 ! 
 isUserInteracting 
 ) 
  
 { 
  
 fovSlider 
 . 
 value 
  
 = 
  
 fov 
 ; 
  
 headingSlider 
 . 
 value 
  
 = 
  
 heading 
 ; 
  
 tiltSlider 
 . 
 value 
  
 = 
  
 tilt 
 ; 
  
 rangeSlider 
 . 
 value 
  
 = 
  
 Math 
 . 
 min 
 ( 
 10000 
 , 
  
 parseFloat 
 ( 
 range 
 )). 
 toString 
 (); 
  
 rollSlider 
 . 
 value 
  
 = 
  
 roll 
 ; 
  
 } 
  
 if 
  
 ( 
 center 
 ) 
  
 { 
  
 const 
  
 lat 
  
 = 
  
 center 
 . 
 lat 
 . 
 toFixed 
 ( 
 4 
 ); 
  
 const 
  
 lng 
  
 = 
  
 center 
 . 
 lng 
 . 
 toFixed 
 ( 
 4 
 ); 
  
 const 
  
 alt 
  
 = 
  
 currentAltitude 
 . 
 toFixed 
 ( 
 0 
 ); 
  
 latSlider 
 . 
 value 
  
 = 
  
 lat 
 ; 
  
 lngSlider 
 . 
 value 
  
 = 
  
 lng 
 ; 
  
 altitudeVal 
 . 
 textContent 
  
 = 
  
 alt 
 ; 
  
 codeElem 
 . 
 textContent 
  
 = 
  
 `<gmp-map-3d center=" 
 ${ 
 lat 
 } 
 , 
 ${ 
 lng 
 } 
 , 
 ${ 
 alt 
 } 
 " mode=" 
 ${ 
 mode 
 } 
 " tilt=" 
 ${ 
 tilt 
 } 
 " range=" 
 ${ 
 range 
 } 
 " heading=" 
 ${ 
 heading 
 } 
 " fov=" 
 ${ 
 fov 
 } 
 " roll=" 
 ${ 
 roll 
 } 
 "></gmp-map-3d>` 
 ; 
  
 } 
  
 }; 
  
 // Copy generated HTML to clipboard. 
  
 copyBtn 
 . 
 addEventListener 
 ( 
 'click' 
 , 
  
 () 
  
 = 
>  
 { 
  
 void 
  
 navigator 
 . 
 clipboard 
 . 
 writeText 
 ( 
 codeElem 
 . 
 textContent 
  
 || 
  
 '' 
 ); 
  
 copyBtn 
 . 
 textContent 
  
 = 
  
 'Copied!' 
 ; 
  
 setTimeout 
 (() 
  
 = 
>  
 { 
  
 copyBtn 
 . 
 textContent 
  
 = 
  
 'Copy HTML' 
 ; 
  
 }, 
  
 2000 
 ); 
  
 }); 
  
 // Listen to slider changes using event delegation. 
  
 const 
  
 panel 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 '.panel' 
 ) 
 ! 
 ; 
  
 panel 
 . 
 addEventListener 
 ( 
 'input' 
 , 
  
 ( 
 e 
 ) 
  
 = 
>  
 { 
  
 const 
  
 target 
  
 = 
  
 e 
 . 
 target 
  
 as 
  
 HTMLInputElement 
 ; 
  
 if 
  
 ( 
 target 
 . 
 tagName 
  
 !== 
  
 'INPUT' 
 ) 
  
 return 
 ; 
  
 isUserInteracting 
  
 = 
  
 true 
 ; 
  
 const 
  
 prop 
  
 = 
  
 target 
 . 
 name 
 ; 
  
 const 
  
 val 
  
 = 
  
 parseFloat 
 ( 
 target 
 . 
 value 
 ); 
  
 if 
  
 ( 
 prop 
  
 === 
  
 'lat' 
 ) 
  
 { 
  
 const 
  
 currentCenter 
  
 = 
  
 map3DElement 
 . 
 center 
 ; 
  
 if 
  
 ( 
 currentCenter 
 ) 
  
 { 
  
 map3DElement 
 . 
 center 
  
 = 
  
 { 
  
 lat 
 : 
  
 val 
 , 
  
 lng 
 : 
  
 currentCenter.lng 
 , 
  
 altitude 
 : 
  
 currentCenter.altitude 
 , 
  
 }; 
  
 } 
  
 } 
  
 else 
  
 if 
  
 ( 
 prop 
  
 === 
  
 'lng' 
 ) 
  
 { 
  
 const 
  
 currentCenter 
  
 = 
  
 map3DElement 
 . 
 center 
 ; 
  
 if 
  
 ( 
 currentCenter 
 ) 
  
 { 
  
 map3DElement 
 . 
 center 
  
 = 
  
 { 
  
 lat 
 : 
  
 currentCenter.lat 
 , 
  
 lng 
 : 
  
 val 
 , 
  
 altitude 
 : 
  
 currentCenter.altitude 
 , 
  
 }; 
  
 } 
  
 } 
  
 else 
  
 if 
  
 ( 
 prop 
  
 === 
  
 'altitude' 
 ) 
  
 { 
  
 currentAltitude 
  
 = 
  
 val 
 ; 
  
 const 
  
 currentCenter 
  
 = 
  
 map3DElement 
 . 
 center 
 ; 
  
 if 
  
 ( 
 currentCenter 
 ) 
  
 { 
  
 map3DElement 
 . 
 center 
  
 = 
  
 { 
  
 lat 
 : 
  
 currentCenter.lat 
 , 
  
 lng 
 : 
  
 currentCenter.lng 
 , 
  
 altitude 
 : 
  
 val 
 , 
  
 }; 
  
 } 
  
 } 
  
 else 
  
 if 
  
 ( 
 prop 
  
 === 
  
 'tilt' 
 ) 
  
 { 
  
 map3DElement 
 . 
 tilt 
  
 = 
  
 Math 
 . 
 max 
 ( 
 0 
 , 
  
 val 
 ); 
  
 } 
  
 else 
  
 if 
  
 ( 
 prop 
  
 === 
  
 'fov' 
 ) 
  
 { 
  
 map3DElement 
 . 
 fov 
  
 = 
  
 Math 
 . 
 min 
 ( 
 80 
 , 
  
 Math 
 . 
 max 
 ( 
 5 
 , 
  
 val 
 )); 
  
 } 
  
 else 
  
 { 
  
 // eslint-disable-next-line @typescript-eslint/no-explicit-any 
  
 ( 
 map3DElement 
  
 as 
  
 any 
 )[ 
 prop 
 ] 
  
 = 
  
 val 
 ; 
  
 } 
  
 updateUI 
 (); 
  
 }); 
  
 panel 
 . 
 addEventListener 
 ( 
 'change' 
 , 
  
 ( 
 e 
 ) 
  
 = 
>  
 { 
  
 const 
  
 target 
  
 = 
  
 e 
 . 
 target 
  
 as 
  
 HTMLInputElement 
 ; 
  
 if 
  
 ( 
 target 
 . 
 tagName 
  
 === 
  
 'INPUT' 
 ) 
  
 { 
  
 isUserInteracting 
  
 = 
  
 false 
 ; 
  
 } 
  
 }); 
  
 // Update UI on camera change events. 
  
 map3DElement 
 . 
 addEventListener 
 ( 
 'gmp-headingchange' 
 , 
  
 updateUI 
 ); 
  
 map3DElement 
 . 
 addEventListener 
 ( 
 'gmp-tiltchange' 
 , 
  
 updateUI 
 ); 
  
 map3DElement 
 . 
 addEventListener 
 ( 
 'gmp-rangechange' 
 , 
  
 updateUI 
 ); 
  
 map3DElement 
 . 
 addEventListener 
 ( 
 'gmp-fovchange' 
 , 
  
 updateUI 
 ); 
  
 // Initial UI sync 
  
 setTimeout 
 ( 
 updateUI 
 , 
  
 500 
 ); 
 } 
 void 
  
 initMap 
 (); 
  

JavaScript

 async 
  
 function 
  
 initMap 
 () 
  
 { 
  
 // Declare the needed libraries. 
  
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'maps3d' 
 ); 
  
 const 
  
 map3DElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-map-3d' 
 ); 
  
 // Elements from HTML 
  
 const 
  
 headingSlider 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'heading' 
 ); 
  
 const 
  
 tiltSlider 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'tilt' 
 ); 
  
 const 
  
 rangeSlider 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'range' 
 ); 
  
 const 
  
 latSlider 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'lat' 
 ); 
  
 const 
  
 lngSlider 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'lng' 
 ); 
  
 const 
  
 fovSlider 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'fov' 
 ); 
  
 const 
  
 rollSlider 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'roll' 
 ); 
  
 const 
  
 headingVal 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'heading-val' 
 ); 
  
 const 
  
 tiltVal 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'tilt-val' 
 ); 
  
 const 
  
 rangeVal 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'range-val' 
 ); 
  
 const 
  
 altitudeVal 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'altitude-val' 
 ); 
  
 const 
  
 fovVal 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'fov-val' 
 ); 
  
 const 
  
 rollVal 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'roll-val' 
 ); 
  
 const 
  
 codeElem 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'generated-code' 
 ); 
  
 const 
  
 copyBtn 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'copy-btn' 
 ); 
  
 let 
  
 currentAltitude 
  
 = 
  
 30 
 ; 
  
 let 
  
 isUserInteracting 
  
 = 
  
 false 
 ; 
  
 // Update values on UI when the map changes. 
  
 const 
  
 updateUI 
  
 = 
  
 () 
  
 = 
>  
 { 
  
 const 
  
 heading 
  
 = 
  
 map3DElement 
 . 
 heading 
 ? 
 . 
 toFixed 
 ( 
 0 
 ) 
  
 ?? 
  
 '0' 
 ; 
  
 const 
  
 tilt 
  
 = 
  
 map3DElement 
 . 
 tilt 
 ? 
 . 
 toFixed 
 ( 
 0 
 ) 
  
 ?? 
  
 '0' 
 ; 
  
 const 
  
 range 
  
 = 
  
 map3DElement 
 . 
 range 
 ? 
 . 
 toFixed 
 ( 
 0 
 ) 
  
 ?? 
  
 '0' 
 ; 
  
 const 
  
 rawFov 
  
 = 
  
 parseFloat 
 ( 
 map3DElement 
 . 
 fov 
 ? 
 . 
 toFixed 
 ( 
 0 
 ) 
  
 ?? 
  
 '45' 
 ); 
  
 const 
  
 fovClamped 
  
 = 
  
 Math 
 . 
 min 
 ( 
 80 
 , 
  
 Math 
 . 
 max 
 ( 
 5 
 , 
  
 rawFov 
 )); 
  
 const 
  
 fov 
  
 = 
  
 fovClamped 
 . 
 toString 
 (); 
  
 const 
  
 roll 
  
 = 
  
 map3DElement 
 . 
 roll 
 ? 
 . 
 toFixed 
 ( 
 0 
 ) 
  
 ?? 
  
 '0' 
 ; 
  
 const 
  
 center 
  
 = 
  
 map3DElement 
 . 
 center 
 ; 
  
 const 
  
 mode 
  
 = 
  
 map3DElement 
 . 
 mode 
 ; 
  
 headingVal 
 . 
 textContent 
  
 = 
  
 heading 
 ; 
  
 tiltVal 
 . 
 textContent 
  
 = 
  
 tilt 
 ; 
  
 rangeVal 
 . 
 textContent 
  
 = 
  
 range 
 ; 
  
 fovVal 
 . 
 textContent 
  
 = 
  
 fov 
 ; 
  
 rollVal 
 . 
 textContent 
  
 = 
  
 roll 
 ; 
  
 if 
  
 ( 
 ! 
 isUserInteracting 
 ) 
  
 { 
  
 fovSlider 
 . 
 value 
  
 = 
  
 fov 
 ; 
  
 headingSlider 
 . 
 value 
  
 = 
  
 heading 
 ; 
  
 tiltSlider 
 . 
 value 
  
 = 
  
 tilt 
 ; 
  
 rangeSlider 
 . 
 value 
  
 = 
  
 Math 
 . 
 min 
 ( 
 10000 
 , 
  
 parseFloat 
 ( 
 range 
 )). 
 toString 
 (); 
  
 rollSlider 
 . 
 value 
  
 = 
  
 roll 
 ; 
  
 } 
  
 if 
  
 ( 
 center 
 ) 
  
 { 
  
 const 
  
 lat 
  
 = 
  
 center 
 . 
 lat 
 . 
 toFixed 
 ( 
 4 
 ); 
  
 const 
  
 lng 
  
 = 
  
 center 
 . 
 lng 
 . 
 toFixed 
 ( 
 4 
 ); 
  
 const 
  
 alt 
  
 = 
  
 currentAltitude 
 . 
 toFixed 
 ( 
 0 
 ); 
  
 latSlider 
 . 
 value 
  
 = 
  
 lat 
 ; 
  
 lngSlider 
 . 
 value 
  
 = 
  
 lng 
 ; 
  
 altitudeVal 
 . 
 textContent 
  
 = 
  
 alt 
 ; 
  
 codeElem 
 . 
 textContent 
  
 = 
  
 `<gmp-map-3d center=" 
 ${ 
 lat 
 } 
 , 
 ${ 
 lng 
 } 
 , 
 ${ 
 alt 
 } 
 " mode=" 
 ${ 
 mode 
 } 
 " tilt=" 
 ${ 
 tilt 
 } 
 " range=" 
 ${ 
 range 
 } 
 " heading=" 
 ${ 
 heading 
 } 
 " fov=" 
 ${ 
 fov 
 } 
 " roll=" 
 ${ 
 roll 
 } 
 "></gmp-map-3d>` 
 ; 
  
 } 
  
 }; 
  
 // Copy generated HTML to clipboard. 
  
 copyBtn 
 . 
 addEventListener 
 ( 
 'click' 
 , 
  
 () 
  
 = 
>  
 { 
  
 void 
  
 navigator 
 . 
 clipboard 
 . 
 writeText 
 ( 
 codeElem 
 . 
 textContent 
  
 || 
  
 '' 
 ); 
  
 copyBtn 
 . 
 textContent 
  
 = 
  
 'Copied!' 
 ; 
  
 setTimeout 
 (() 
  
 = 
>  
 { 
  
 copyBtn 
 . 
 textContent 
  
 = 
  
 'Copy HTML' 
 ; 
  
 }, 
  
 2000 
 ); 
  
 }); 
  
 // Listen to slider changes using event delegation. 
  
 const 
  
 panel 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 '.panel' 
 ); 
  
 panel 
 . 
 addEventListener 
 ( 
 'input' 
 , 
  
 ( 
 e 
 ) 
  
 = 
>  
 { 
  
 const 
  
 target 
  
 = 
  
 e 
 . 
 target 
 ; 
  
 if 
  
 ( 
 target 
 . 
 tagName 
  
 !== 
  
 'INPUT' 
 ) 
  
 return 
 ; 
  
 isUserInteracting 
  
 = 
  
 true 
 ; 
  
 const 
  
 prop 
  
 = 
  
 target 
 . 
 name 
 ; 
  
 const 
  
 val 
  
 = 
  
 parseFloat 
 ( 
 target 
 . 
 value 
 ); 
  
 if 
  
 ( 
 prop 
  
 === 
  
 'lat' 
 ) 
  
 { 
  
 const 
  
 currentCenter 
  
 = 
  
 map3DElement 
 . 
 center 
 ; 
  
 if 
  
 ( 
 currentCenter 
 ) 
  
 { 
  
 map3DElement 
 . 
 center 
  
 = 
  
 { 
  
 lat 
 : 
  
 val 
 , 
  
 lng 
 : 
  
 currentCenter 
 . 
 lng 
 , 
  
 altitude 
 : 
  
 currentCenter 
 . 
 altitude 
 , 
  
 }; 
  
 } 
  
 } 
  
 else 
  
 if 
  
 ( 
 prop 
  
 === 
  
 'lng' 
 ) 
  
 { 
  
 const 
  
 currentCenter 
  
 = 
  
 map3DElement 
 . 
 center 
 ; 
  
 if 
  
 ( 
 currentCenter 
 ) 
  
 { 
  
 map3DElement 
 . 
 center 
  
 = 
  
 { 
  
 lat 
 : 
  
 currentCenter 
 . 
 lat 
 , 
  
 lng 
 : 
  
 val 
 , 
  
 altitude 
 : 
  
 currentCenter 
 . 
 altitude 
 , 
  
 }; 
  
 } 
  
 } 
  
 else 
  
 if 
  
 ( 
 prop 
  
 === 
  
 'altitude' 
 ) 
  
 { 
  
 currentAltitude 
  
 = 
  
 val 
 ; 
  
 const 
  
 currentCenter 
  
 = 
  
 map3DElement 
 . 
 center 
 ; 
  
 if 
  
 ( 
 currentCenter 
 ) 
  
 { 
  
 map3DElement 
 . 
 center 
  
 = 
  
 { 
  
 lat 
 : 
  
 currentCenter 
 . 
 lat 
 , 
  
 lng 
 : 
  
 currentCenter 
 . 
 lng 
 , 
  
 altitude 
 : 
  
 val 
 , 
  
 }; 
  
 } 
  
 } 
  
 else 
  
 if 
  
 ( 
 prop 
  
 === 
  
 'tilt' 
 ) 
  
 { 
  
 map3DElement 
 . 
 tilt 
  
 = 
  
 Math 
 . 
 max 
 ( 
 0 
 , 
  
 val 
 ); 
  
 } 
  
 else 
  
 if 
  
 ( 
 prop 
  
 === 
  
 'fov' 
 ) 
  
 { 
  
 map3DElement 
 . 
 fov 
  
 = 
  
 Math 
 . 
 min 
 ( 
 80 
 , 
  
 Math 
 . 
 max 
 ( 
 5 
 , 
  
 val 
 )); 
  
 } 
  
 else 
  
 { 
  
 // eslint-disable-next-line @typescript-eslint/no-explicit-any 
  
 map3DElement 
 [ 
 prop 
 ] 
  
 = 
  
 val 
 ; 
  
 } 
  
 updateUI 
 (); 
  
 }); 
  
 panel 
 . 
 addEventListener 
 ( 
 'change' 
 , 
  
 ( 
 e 
 ) 
  
 = 
>  
 { 
  
 const 
  
 target 
  
 = 
  
 e 
 . 
 target 
 ; 
  
 if 
  
 ( 
 target 
 . 
 tagName 
  
 === 
  
 'INPUT' 
 ) 
  
 { 
  
 isUserInteracting 
  
 = 
  
 false 
 ; 
  
 } 
  
 }); 
  
 // Update UI on camera change events. 
  
 map3DElement 
 . 
 addEventListener 
 ( 
 'gmp-headingchange' 
 , 
  
 updateUI 
 ); 
  
 map3DElement 
 . 
 addEventListener 
 ( 
 'gmp-tiltchange' 
 , 
  
 updateUI 
 ); 
  
 map3DElement 
 . 
 addEventListener 
 ( 
 'gmp-rangechange' 
 , 
  
 updateUI 
 ); 
  
 map3DElement 
 . 
 addEventListener 
 ( 
 'gmp-fovchange' 
 , 
  
 updateUI 
 ); 
  
 // Initial UI sync 
  
 setTimeout 
 ( 
 updateUI 
 , 
  
 500 
 ); 
 } 
 void 
  
 initMap 
 (); 
  

CSS

 html 
 , 
 body 
  
 { 
  
 height 
 : 
  
 100 
 % 
 ; 
  
 margin 
 : 
  
 0 
 ; 
  
 padding 
 : 
  
 0 
 ; 
  
 font-family 
 : 
  
 'Inter' 
 , 
  
 - 
 apple-system 
 , 
  
 BlinkMacSystemFont 
 , 
  
 'Segoe UI' 
 , 
  
 Roboto 
 , 
  
 Oxygen 
 , 
  
 Ubuntu 
 , 
  
 Cantarell 
 , 
  
 'Open Sans' 
 , 
  
 'Helvetica Neue' 
 , 
  
 sans-serif 
 ; 
  
 background-color 
 : 
  
 #0f172a 
 ; 
  
 color 
 : 
  
 #e2e8f0 
 ; 
 } 
 gmp-map-3d 
  
 { 
  
 height 
 : 
  
 100 
 % 
 ; 
  
 width 
 : 
  
 100 
 % 
 ; 
 } 
 /* Glassmorphism UI Overlay */ 
 # 
 ui-container 
  
 { 
  
 position 
 : 
  
 absolute 
 ; 
  
 top 
 : 
  
 20 
 px 
 ; 
  
 left 
 : 
  
 20 
 px 
 ; 
  
 width 
 : 
  
 320 
 px 
 ; 
  
 z-index 
 : 
  
 10 
 ; 
 } 
 . 
 panel 
  
 { 
  
 background 
 : 
  
 rgba 
 ( 
 15 
 , 
  
 23 
 , 
  
 42 
 , 
  
 0.75 
 ); 
  
 backdrop-filter 
 : 
  
 blur 
 ( 
 12 
 px 
 ); 
  
 -webkit- 
 backdrop-filter 
 : 
  
 blur 
 ( 
 12 
 px 
 ); 
  
 border 
 : 
  
 1 
 px 
  
 solid 
  
 rgba 
 ( 
 255 
 , 
  
 255 
 , 
  
 255 
 , 
  
 0.1 
 ); 
  
 border-radius 
 : 
  
 16 
 px 
 ; 
  
 padding 
 : 
  
 24 
 px 
 ; 
  
 margin-top 
 : 
  
 10 
 px 
 ; 
  
 box-shadow 
 : 
  
 0 
  
 8 
 px 
  
 32 
 px 
  
 0 
  
 rgba 
 ( 
 0 
 , 
  
 0 
 , 
  
 0 
 , 
  
 0.37 
 ); 
 } 
 h1 
  
 { 
  
 font-size 
 : 
  
 1.25 
 rem 
 ; 
  
 font-weight 
 : 
  
 700 
 ; 
  
 margin 
 : 
  
 0 
  
 0 
  
 4 
 px 
  
 0 
 ; 
  
 background 
 : 
  
 linear-gradient 
 ( 
 to 
  
 right 
 , 
  
 #38bdf8 
 , 
  
 #818cf8 
 ); 
  
 -webkit- 
 background-clip 
 : 
  
 text 
 ; 
  
 -webkit- 
 text-fill-color 
 : 
  
 transparent 
 ; 
 } 
 . 
 sub-title 
  
 { 
  
 font-size 
 : 
  
 0.85 
 rem 
 ; 
  
 color 
 : 
  
 #94a3b8 
 ; 
  
 margin 
 : 
  
 0 
  
 0 
  
 20 
 px 
  
 0 
 ; 
 } 
 h2 
  
 { 
  
 font-size 
 : 
  
 0.95 
 rem 
 ; 
  
 font-weight 
 : 
  
 600 
 ; 
  
 margin 
 : 
  
 16 
 px 
  
 0 
  
 8 
 px 
  
 0 
 ; 
  
 color 
 : 
  
 #f8fafc 
 ; 
 } 
 . 
 control-group 
  
 { 
  
 margin-bottom 
 : 
  
 16 
 px 
 ; 
 } 
 label 
  
 { 
  
 display 
 : 
  
 block 
 ; 
  
 font-size 
 : 
  
 0.85 
 rem 
 ; 
  
 margin-bottom 
 : 
  
 6 
 px 
 ; 
  
 color 
 : 
  
 #cbd5e1 
 ; 
 } 
 span 
  
 { 
  
 font-weight 
 : 
  
 600 
 ; 
  
 color 
 : 
  
 #38bdf8 
 ; 
 } 
 . 
 row 
  
 { 
  
 display 
 : 
  
 flex 
 ; 
  
 gap 
 : 
  
 12 
 px 
 ; 
 } 
 . 
 col 
  
 { 
  
 flex 
 : 
  
 1 
 ; 
 } 
 input 
 [ 
 type 
 = 
 'number' 
 ] 
  
 { 
  
 font-family 
 : 
  
 'Fira Code' 
 , 
  
 monospace 
 ; 
  
 background 
 : 
  
 rgba 
 ( 
 15 
 , 
  
 23 
 , 
  
 42 
 , 
  
 0.5 
 ); 
  
 border 
 : 
  
 1 
 px 
  
 solid 
  
 rgba 
 ( 
 255 
 , 
  
 255 
 , 
  
 255 
 , 
  
 0.1 
 ); 
  
 color 
 : 
  
 #f8fafc 
 ; 
  
 padding 
 : 
  
 4 
 px 
  
 8 
 px 
 ; 
  
 border-radius 
 : 
  
 6 
 px 
 ; 
  
 outline 
 : 
  
 none 
 ; 
 } 
 input 
 [ 
 type 
 = 
 'range' 
 ] 
  
 { 
  
 width 
 : 
  
 100 
 % 
 ; 
  
 height 
 : 
  
 4 
 px 
 ; 
  
 background 
 : 
  
 #334155 
 ; 
  
 border-radius 
 : 
  
 2 
 px 
 ; 
  
 outline 
 : 
  
 none 
 ; 
  
 -webkit- 
 appearance 
 : 
  
 none 
 ; 
 } 
 input 
 [ 
 type 
 = 
 'range' 
 ] 
 :: 
 -webkit-slider-thumb 
  
 { 
  
 -webkit- 
 appearance 
 : 
  
 none 
 ; 
  
 width 
 : 
  
 16 
 px 
 ; 
  
 height 
 : 
  
 16 
 px 
 ; 
  
 border-radius 
 : 
  
 50 
 % 
 ; 
  
 background 
 : 
  
 #38bdf8 
 ; 
  
 cursor 
 : 
  
 pointer 
 ; 
  
 box-shadow 
 : 
  
 0 
  
 0 
  
 8 
 px 
  
 rgba 
 ( 
 56 
 , 
  
 189 
 , 
  
 248 
 , 
  
 0.5 
 ); 
  
 transition 
 : 
  
 all 
  
 0.2 
 s 
  
 ease 
 ; 
 } 
 input 
 [ 
 type 
 = 
 'range' 
 ] 
 :: 
 -webkit-slider-thumb 
 : 
 hover 
  
 { 
  
 transform 
 : 
  
 scale 
 ( 
 1.2 
 ); 
  
 background 
 : 
  
 #60a5fa 
 ; 
 } 
 . 
 buttons 
  
 { 
  
 display 
 : 
  
 flex 
 ; 
  
 flex-direction 
 : 
  
 column 
 ; 
  
 gap 
 : 
  
 8 
 px 
 ; 
 } 
 button 
  
 { 
  
 background 
 : 
  
 rgba 
 ( 
 51 
 , 
  
 65 
 , 
  
 85 
 , 
  
 0.5 
 ); 
  
 border 
 : 
  
 1 
 px 
  
 solid 
  
 rgba 
 ( 
 255 
 , 
  
 255 
 , 
  
 255 
 , 
  
 0.05 
 ); 
  
 color 
 : 
  
 #f8fafc 
 ; 
  
 padding 
 : 
  
 10 
 px 
  
 16 
 px 
 ; 
  
 border-radius 
 : 
  
 8 
 px 
 ; 
  
 cursor 
 : 
  
 pointer 
 ; 
  
 font-size 
 : 
  
 0.85 
 rem 
 ; 
  
 font-weight 
 : 
  
 500 
 ; 
  
 transition 
 : 
  
 all 
  
 0.2 
 s 
  
 ease 
 ; 
  
 text-align 
 : 
  
 left 
 ; 
 } 
 button 
 : 
 hover 
  
 { 
  
 background 
 : 
  
 rgba 
 ( 
 56 
 , 
  
 189 
 , 
  
 248 
 , 
  
 0.2 
 ); 
  
 border-color 
 : 
  
 rgba 
 ( 
 56 
 , 
  
 189 
 , 
  
 248 
 , 
  
 0.4 
 ); 
  
 transform 
 : 
  
 translateY 
 ( 
 -1 
 px 
 ); 
 } 
 button 
 : 
 active 
  
 { 
  
 transform 
 : 
  
 translateY 
 ( 
 0 
 ); 
 } 
 . 
 status-group 
  
 p 
  
 { 
  
 font-size 
 : 
  
 0.8 
 rem 
 ; 
  
 color 
 : 
  
 #94a3b8 
 ; 
  
 margin 
 : 
  
 4 
 px 
  
 0 
 ; 
  
 background 
 : 
  
 rgba 
 ( 
 30 
 , 
  
 41 
 , 
  
 59 
 , 
  
 0.5 
 ); 
  
 padding 
 : 
  
 6 
 px 
  
 10 
 px 
 ; 
  
 border-radius 
 : 
  
 6 
 px 
 ; 
  
 font-family 
 : 
  
 monospace 
 ; 
 } 
 . 
 code-box 
  
 { 
  
 position 
 : 
  
 relative 
 ; 
  
 background 
 : 
  
 rgba 
 ( 
 15 
 , 
  
 23 
 , 
  
 42 
 , 
  
 0.9 
 ); 
  
 border-radius 
 : 
  
 8 
 px 
 ; 
  
 border 
 : 
  
 1 
 px 
  
 solid 
  
 rgba 
 ( 
 255 
 , 
  
 255 
 , 
  
 255 
 , 
  
 0.05 
 ); 
  
 margin-top 
 : 
  
 8 
 px 
 ; 
 } 
 pre 
  
 { 
  
 margin 
 : 
  
 0 
 ; 
  
 padding 
 : 
  
 12 
 px 
 ; 
  
 overflow-x 
 : 
  
 auto 
 ; 
 } 
 code 
  
 { 
  
 font-family 
 : 
  
 'Fira Code' 
 , 
  
 monospace 
 ; 
  
 font-size 
 : 
  
 0.75 
 rem 
 ; 
  
 color 
 : 
  
 #38bdf8 
 ; 
 } 
 # 
 copy-btn 
  
 { 
  
 display 
 : 
  
 block 
 ; 
  
 width 
 : 
  
 100 
 % 
 ; 
  
 margin-top 
 : 
  
 8 
 px 
 ; 
  
 padding 
 : 
  
 8 
 px 
 ; 
  
 font-size 
 : 
  
 0.85 
 rem 
 ; 
  
 font-weight 
 : 
  
 600 
 ; 
  
 background 
 : 
  
 #334155 
 ; 
  
 color 
 : 
  
 #f8fafc 
 ; 
  
 border 
 : 
  
 none 
 ; 
  
 border-radius 
 : 
  
 6 
 px 
 ; 
  
 text-align 
 : 
  
 center 
 ; 
  
 cursor 
 : 
  
 pointer 
 ; 
  
 transition 
 : 
  
 all 
  
 0.2 
 s 
  
 ease 
 ; 
 } 
 # 
 copy-btn 
 : 
 hover 
  
 { 
  
 background 
 : 
  
 #38bdf8 
 ; 
  
 color 
 : 
  
 #0f172a 
 ; 
 } 
  

HTML

<html>
    <head>
        <title>Google Maps 3D - Camera Position Controller</title>
        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <script>
            // prettier-ignore
            (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
                key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8"
            });
        </script>
    </head>

    <body>
        <gmp-map-3d
            center="40.7811,-73.9599,0"
            mode="HYBRID"
            tilt="76"
            range="3270"
            heading="-154"></gmp-map-3d>
        <div id="ui-container">
            <div class="panel">
                <div class="control-group">
                    <label for="heading">
                        Heading: <span id="heading-val">0</span>&deg;
                    </label>
                    <input
                        type="range"
                        id="heading"
                        name="heading"
                        min="-180"
                        max="180"
                        value="0"
                        step="1" />
                </div>

                <div class="control-group">
                    <label for="tilt">
                        Tilt: <span id="tilt-val">45</span>&deg;
                    </label>
                    <input
                        type="range"
                        id="tilt"
                        name="tilt"
                        min="0"
                        max="90"
                        value="45"
                        step="1" />
                </div>

                <div class="control-group">
                    <label for="range">
                        Range: <span id="range-val">1000</span>m
                    </label>
                    <input
                        type="range"
                        id="range"
                        name="range"
                        min="100"
                        max="10000"
                        value="1000"
                        step="100" />
                </div>

                <div class="control-group row">
                    <div class="col">
                        <label for="lat">Latitude</label>
                        <input
                            type="number"
                            id="lat"
                            name="lat"
                            min="-90"
                            max="90"
                            value="40.7040"
                            step="0.0001" />
                    </div>
                    <div class="col">
                        <label for="lng">Longitude</label>
                        <input
                            type="number"
                            id="lng"
                            name="lng"
                            min="-180"
                            max="180"
                            value="-74.0180"
                            step="0.0001" />
                    </div>
                </div>

                <div class="control-group">
                    <label for="altitude">
                        Altitude: <span id="altitude-val">30</span>m
                    </label>
                    <input
                        type="range"
                        id="altitude"
                        name="altitude"
                        min="0"
                        max="5000"
                        value="30"
                        step="10" />
                </div>

                <div class="control-group">
                    <label for="fov">
                        FOV: <span id="fov-val">35</span>&deg;
                    </label>
                    <input
                        type="range"
                        id="fov"
                        name="fov"
                        min="5"
                        max="80"
                        value="35"
                        step="1" />
                </div>

                <div class="control-group">
                    <label for="roll">
                        Roll: <span id="roll-val">0</span>&deg;
                    </label>
                    <input
                        type="range"
                        id="roll"
                        name="roll"
                        min="-180"
                        max="180"
                        value="0"
                        step="1" />
                </div>

                <div class="status-group">
                    <div class="code-box">
                        <pre><code id="generated-code"></code></pre>
                    </div>
                    <button id="copy-btn">Copy HTML</button>
                </div>
            </div>
        </div>
    </body>
</html>  

Try Sample

Create a Mobile Website
View Site in Mobile | Classic
Share by: