PageSourceSearch

https://www.geoapify.com/component---src-template-post-js-content-…mapbox-gl-index-mdx-fc4ff0ccdc48fe6f6c2b.js

js geoapify.com collected 2026-09-24 15:24:57 UTC 42,271 bytes, 2 lines download raw bytes

1"use strict";(self.webpackChunkgeoapify_home=self.webpackChunkgeoapify_home||[]).push([[8707],{5646:function(a,n,t){t.r(n),t.d(n,{default:function(){return z}});var s=t(8453),e=t(6540);function o(a){const n=Object.assign({p:"p",a:"a",strong:"strong",h2:"h2",span:"span",code:"code",h4:"h4"},(0,s.RP)(),a.components),{Banner:t,ButtonGroup:o,Button:p}=n;return t||c("Banner",!0),p||c("Button",!0),o||c("ButtonGroup",!0),e.createElement(e.Fragment,null,e.createElement(n.p,null,"What can be more eye-catching than smooth, interactive, three-dimensional map animation? Impress your visitors by displaying your map data in stunning 3D!"),"\n",e.createElement(n.p,null,"Previously we have ",e.createElement(n.a,{href:"/leaflet-vs-openlayers/"},"compared OpenLayers and Leaflet map libraries"),". Both are great choices if you want to add interactive map to your website. They are free, battle-tested, extensible and supported by active communities."),"\n",e.createElement(n.p,null,"But what if you need a very fast, animated, eye-catching 3D map? Both Leaflet API and OpenMapLayersAPI do not support 3D and free-form map rotation. In this case Mapbox GL map library can be a great option."),"\n",e.createElement(n.p,null,"Mapbox GL JS is one of the most advanced JavaScript map rendering libraries when it comes to smooth interactive animation.\nMapbox GL API is slightly harder to use and not compatible with existing Leaflet plugins and examples.\nBut it is using hardware-accelerated WebGL technology to dynamically draw data with the speed and smoothness of a video game."),"\n",e.createElement(n.p,null,e.createElement(n.strong,null,"Update February 2021:")," Mapbox GL has changed to a non-free licence, we recommend using ",e.createElement(n.a,{href:"/mapbox-gl-new-license-and-6-free-alternatives/"},"MapLibre GL or alternatives")," instead."),"\n",e.createElement(n.p,null,"In this article I'll show you how to animate and implement 3D map rotation around a selected point. The end result should look like this:"),"\n",e.createElement("iframe",{className:"width-default",id:"ytplayer",type:"text/html",width:"800",height:"450",src:"https://www.youtube.com/embed/a8aplYWsj70?autoplay=0&origin=http://www.geoapify.com"}),"\n",e.createElement("div",{className:"image-caption"},"Map rotation animation in 3D with Mapbox GL"),"\n",e.createElement(n.p,null,"If you short on time and just looking for the complete HTML code, you can find it at the bottom of the page."),"\n",e.createElement(n.h2,null,"Setting up our 3D map"),"\n",e.createElement(n.p,null,"As first step, we need to add imports for Mapbox GL library and its CSS style sheet into the HEAD of our page"),"\n",e.createElement("div",{className:"width-default"},e.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-remark-copy-button-container">\n              <button\n                class="gatsby-remark-copy-button"\n                onClick="copyToClipboard(`<link\n  rel=&quot;stylesheet&quot;\n  href=&quot;https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/0.53.1/mapbox-gl.css&quot;\n/>\n<script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/0.53.1/mapbox-gl.js&quot;><\/script>`, this)"\n              >\n                <svg class="copy-icon" width="16" height="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">\x3c!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="#FFFFFF" d="M384 336H192c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16l140.1 0L400 115.9V320c0 8.8-7.2 16-16 16zM192 384H384c35.3 0 64-28.7 64-64V115.9c0-12.7-5.1-24.9-14.1-33.9L366.1 14.1c-9-9-21.2-14.1-33.9-14.1H192c-35.3 0-64 28.7-64 64V320c0 35.3 28.7 64 64 64zM64 128c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H256c35.3 0 64-28.7 64-64V416H272v32c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V192c0-8.8 7.2-16 16-16H96V128H64z"/></svg><svg class="success-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path fill="#fff" d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>\n              </button>\n            </div>'}}),e.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span>\n  <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span>\n  <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/0.53.1/mapbox-gl.css<span class="token punctuation">"</span></span>\n<span class="token punctuation">/></span></span>\n<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/0.53.1/mapbox-gl.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div>'}})),"\n",e.createElement(n.p,null,"Once imported, we can define a ",e.createElement(n.code,null,"<div>"),' element which will host map visualization and add Javascript code which will initialize Mapbox GL to render our map in 3D with specified initial location, zoom, pitch and bearing.\nPlease do not forget to put your real API key instead of "YOUR_API_KEY" placeholder in the map tiles URL.'),"\n",e.createElement("div",{className:"width-default"},e.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-remark-copy-button-container">\n              <button\n                class="gatsby-remark-copy-button"\n                onClick="copyToClipboard(`<div id=&quot;map&quot;></div>\n<script>\n  var map = new mapboxgl.Map({\n      container: \'map\',\n      style: &quot;https://maps.geoapify.com/v1/styles/osm-carto/style.json?api_key=YOUR_API_KEY&quot;,\n      center: [-73.991462, 40.724637], // starting position\n      zoom: 12, // starting zoom\n      pitch: 60, // starting pitch in degrees\n      bearing: 0, // starting bearing in degree\n  });\n<\/script>`, this)"\n              >\n                <svg class="copy-icon" width="16" height="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">\x3c!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="#FFFFFF" d="M384 336H192c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16l140.1 0L400 115.9V320c0 8.8-7.2 16-16 16zM192 384H384c35.3 0 64-28.7 64-64V115.9c0-12.7-5.1-24.9-14.1-33.9L366.1 14.1c-9-9-21.2-14.1-33.9-14.1H192c-35.3 0-64 28.7-64 64V320c0 35.3 28.7 64 64 64zM64 128c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H256c35.3 0 64-28.7 64-64V416H272v32c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V192c0-8.8 7.2-16 16-16H96V128H64z"/></svg><svg class="success-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
1<path d="M0 0h24v24H0z" fill="none"/><path fill="#fff" d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>\n              </button>\n            </div>'}}),e.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>map<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>\n<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript">\n  <span class="token keyword">var</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">mapboxgl<span class="token punctuation">.</span>Map</span><span class="token punctuation">(</span><span class="token punctuation">{</span>\n      <span class="token literal-property property">container</span><span class="token operator">:</span> <span class="token string">\'map\'</span><span class="token punctuation">,</span>\n      <span class="token literal-property property">style</span><span class="token operator">:</span> <span class="token string">"https://maps.geoapify.com/v1/styles/osm-carto/style.json?api_key=YOUR_API_KEY"</span><span class="token punctuation">,</span>\n      <span class="token literal-property property">center</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">73.991462</span><span class="token punctuation">,</span> <span class="token number">40.724637</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token comment">// starting position</span>\n      <span class="token literal-property property">zoom</span><span class="token operator">:</span> <span class="token number">12</span><span class="token punctuation">,</span> <span class="token comment">// starting zoom</span>\n      <span class="token literal-property property">pitch</span><span class="token operator">:</span> <span class="token number">60</span><span class="token punctuation">,</span> <span class="token comment">// starting pitch in degrees</span>\n      <span class="token literal-property property">bearing</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token comment">// starting bearing in degree</span>\n  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div>'}})),"\n",e.createElement(n.p,null,"This should give us basic interactive 3D map. You should be able to move the map to a different locations, zoom in and out, and change view angle."),"\n",e.createElement(n.span,{dangerouslySetInnerHTML:{__html:"<span class='gatsby-resp-image-wrapper' style='position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 600px; '>\n      <a class='gatsby-resp-image-link' href='/static/55bbe513d262ecbdc0b17f896f956d67/9a1cf/image-4.png' style='display: block' target='_blank' rel='noopener'>\n    <span class='gatsby-resp-image-background-image' style=\"padding-bottom: 58.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url('data:image/webp;base64,UklGRlYAAABXRUJQVlA4IEoAAAAwAwCdASoUAAwAPtFUo0uoJKMhsAgBABoJS7AKaAJxtVXAAP7uzbImc50ALK6
1Q/97dJgburpaYEGMWj3RhKr1FR6AW8wB3v+AAAA=='); background-size: cover; display: block;\"></span>\n  <img class='gatsby-resp-image-image' alt='Interactive 3D map view of Manhattan, NY' title='' src='/static/55bbe513d262ecbdc0b17f896f956d67/0a47e/image-4.png' srcset='/static/55bbe513d262ecbdc0b17f896f956d67/5a46d/image-4.png 300w,\n/static/55bbe513d262ecbdc0b17f896f956d67/fc2a6/image-4.png 450w,\n/static/55bbe513d262ecbdc0b17f896f956d67/0a47e/image-4.png 600w,\n/static/55bbe513d262ecbdc0b17f896f956d67/9a1cf/image-4.png 924w' sizes='(max-width: 600px) 100vw, 600px' style='width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;' loading='lazy' decoding='async'>\n  </a>\n    </span>"}}),"\n",e.createElement("div",{className:"image-caption"},"Interactive 3D map view of Manhattan, NY"),"\n",e.createElement(n.h2,null,"Adding map rotation animation"),"\n",e.createElement(n.p,null,"As next step, let's add dynamic map animation, which will change view angle to create effect of flying around the map center.\nPlease add the following code into our ",e.createElement(n.code,null,"<script>")," block and refresh the page:"),"\n",e.createElement("div",{className:"width-default"},e.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-remark-copy-button-container">\n              <button\n                class="gatsby-remark-copy-button"\n                onClick="copyToClipboard(`function rotateCamera(timestamp) {\n  // rotate at approximately ~10 degrees per second\n  map.rotateTo((timestamp / 100) % 360, { duration: 0 });\n  // request the next frame of the animation\n  requestAnimationFrame(rotateCamera);\n}\n\nmap.on(&quot;load&quot;, function () {\n  // start the animation\n  rotateCamera(0);\n});`, this)"\n              >\n                <svg class="copy-icon" width="16" height="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">\x3c!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="#FFFFFF" d="M384 336H192c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16l140.1 0L400 115.9V320c0 8.8-7.2 16-16 16zM192 384H384c35.3 0 64-28.7 64-64V115.9c0-12.7-5.1-24.9-14.1-33.9L366.1 14.1c-9-9-21.2-14.1-33.9-14.1H192c-35.3 0-64 28.7-64 64V320c0 35.3 28.7 64 64 64zM64 128c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H256c35.3 0 64-28.7 64-64V416H272v32c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V192c0-8.8 7.2-16 16-16H96V128H64z"/></svg><svg class="success-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path fill="#fff" d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>\n              </button>\n            </div>'}}),e.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">rotateCamera</span><span class="token punctuation">(</span><span class="token parameter">timestamp</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  <span class="token comment">// rotate at approximately ~10 degrees per second</span>\n  map<span class="token punctuation">.</span><span class="token function">rotateTo</span><span class="token punctuation">(</span><span class="token punctuation">(</span>timestamp <span class="token operator">/</span> <span class="token number">100</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">360</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">duration</span><span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token comment">// request the next frame of the animation</span>\n  <span class="token function">requestAnimationFrame</span><span class="token punctuation">(</span>rotateCamera<span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span>\n\nmap<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">"load"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  <span class="token comment">// start the animation</span>\n  <span class="token function">rotateCamera</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>'}})),"\n",e.createElement(n.h2,null,"Final steps"),"\n",e.createElement(n.p,null,"As the last step, let's add basic map navigation control.\nWe do not need to add attribution control as it is automatically configured based on the map style."),"\n",e.createElement("div",{className:"width-default"},e.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-remark-copy-button-container">\n              <button\n                class="gatsby-remark-copy-button"\n                onClick="copyToClipboard(`// map n
1avigation controls\nmap.addControl(new mapboxgl.NavigationControl());`, this)"\n              >\n                <svg class="copy-icon" width="16" height="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">\x3c!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="#FFFFFF" d="M384 336H192c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16l140.1 0L400 115.9V320c0 8.8-7.2 16-16 16zM192 384H384c35.3 0 64-28.7 64-64V115.9c0-12.7-5.1-24.9-14.1-33.9L366.1 14.1c-9-9-21.2-14.1-33.9-14.1H192c-35.3 0-64 28.7-64 64V320c0 35.3 28.7 64 64 64zM64 128c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H256c35.3 0 64-28.7 64-64V416H272v32c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V192c0-8.8 7.2-16 16-16H96V128H64z"/></svg><svg class="success-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path fill="#fff" d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>\n              </button>\n            </div>'}}),e.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// map navigation controls</span>\nmap<span class="token punctuation">.</span><span class="token function">addControl</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">mapboxgl<span class="token punctuation">.</span>NavigationControl</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>'}})),"\n",e.createElement(n.span,{dangerouslySetInnerHTML:{__html:"<span class='gatsby-resp-image-wrapper' style='position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 600px; '>\n      <a class='gatsby-resp-image-link' href='/static/ddf0cafdb95ba21e2b4cda5ba50f6e73/076ca/image-1.png' style='display: block' target='_blank' rel='noopener'>\n    <span class='gatsby-resp-image-background-image' style=\"padding-bottom: 59.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url('data:image/webp;base64,UklGRlQAAABXRUJQVlA4IEgAAABQAwCdASoUAAwAPtFUo0uoJKMhsAgBABoJS7AKaAJxt6ZDQAD+7s2yJnOdACyukP/i7wPFICV13fBAeCLhRT6VYdGoAb9qIAA='); background-size: cover; display: block;\"></span>\n  <img class='gatsby-resp-image-image' alt='Complete map with controls and attribution' title='' src='/static/ddf0cafdb95ba21e2b4cda5ba50f6e73/0a47e/image-1.png' srcset='/static/ddf0cafdb95ba21e2b4cda5ba50f6e73/5a46d/image-1.png 300w,\n/static/ddf0cafdb95ba21e2b4cda5ba50f6e73/fc2a6/image-1.png 450w,\n/static/ddf0cafdb95ba21e2b4cda5ba50f6e73/0a47e/image-1.png 600w,\n/static/ddf0cafdb95ba21e2b4cda5ba50f6e73/076ca/image-1.png 914w' sizes='(max-width: 600px) 100vw, 600px' style='width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;' loading='lazy' decoding='async'>\n  </a>\n    </span>"}}),"\n",e.createElement("div",{className:"image-caption"},"Complete map with controls and attribution"),"\n",e.createElement(n.h2,null,"Complete HTML code"),"\n",e.createElement(n.p,null,"Final version of the HTML page could look like this. Please feel free to copy the code, insert API key and open it in your browser to see how it works."),"\n",e.createElement("div",{className:"width-default"},e.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-remark-copy-button-container">\n              <button\n                class="gatsby-remark-copy-button"\n                onClick="copyToClipboard(`<html>\n  <head>\n    <meta charset=&quot;utf-8&quot; />\n    <title>Mapbox GL example: rotate map animation in 3D</title>\n    <meta\n      name=&quot;viewport&quot;\n      content=&quot;initial-scale=1,maximum-scale=1,user-scalable=no&quot;\n    />\n    <link\n      rel=&quot;stylesheet&quot;\n      href=&quot;https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/0.53.1/mapbox-gl.css&quot;\n    />\n    <script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/0.53.1/mapbox-gl.js&quot;><\/script>\n    <style>\n      body {\n        margin: 0;\n        padding: 0;\n      }\n      #map {\n        position: absolute;\n        top: 0;\n        bottom: 0;\n        width: 100%;\n      }\n    </style>\n  </head>\n  <body>\n    <div id=&quot;map&quot;></div>\n    <script>\n      var map = new mapboxgl.Map({\n          container: \'map\',\n          style: &quot;https://maps.geoapify.com/v1/styles/osm-carto/style.json?api_key=YOUR_API_KEY&quot;,\n          center: [-73.991462, 40.724637], // starting position\n          zoom: 12, // starting zoom\n          pitch: 60, // starting pitch in degrees\n          bearing: 0, // starting bearing in degree\n      });
1\n\n      function rotateCamera(timestamp) {\n          // rotate at approximately ~10 degrees per second\n          map.rotateTo((timestamp / 100) % 360, {duration: 0});\n          // request the next frame of the animation\n          requestAnimationFrame(rotateCamera);\n      }\n\n      map.on(\'load\', function () {\n          // start the animation\n          rotateCamera(0);\n      });\n\n      // map navigation controls\n      map.addControl(new mapboxgl.NavigationControl());\n    <\/script>\n  </body>\n</html>`, this)"\n              >\n                <svg class="copy-icon" width="16" height="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">\x3c!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--\x3e<path fill="#FFFFFF" d="M384 336H192c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16l140.1 0L400 115.9V320c0 8.8-7.2 16-16 16zM192 384H384c35.3 0 64-28.7 64-64V115.9c0-12.7-5.1-24.9-14.1-33.9L366.1 14.1c-9-9-21.2-14.1-33.9-14.1H192c-35.3 0-64 28.7-64 64V320c0 35.3 28.7 64 64 64zM64 128c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H256c35.3 0 64-28.7 64-64V416H272v32c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V192c0-8.8 7.2-16 16-16H96V128H64z"/></svg><svg class="success-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path fill="#fff" d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>\n              </button>\n            </div>'}}),e.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span><span class="token punctuation">></span></span>\n  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span>\n    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>utf-8<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>\n    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>Mapbox GL example: rotate map animation in 3D<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span>\n    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span>\n      <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>viewport<span class="token punctuation">"</span></span>\n      <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>initial-scale=1,maximum-scale=1,user-scalable=no<span class="token punctuation">"</span></span>\n    <span class="token punctuation">/></span></span>\n    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span>\n      <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span>\n      <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/0.53.1/mapbox-gl.css<span class="token punctuation">"</span></span>\n    <span class="token punctuation">/></span></span>\n    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/0.53.1/mapbox-gl.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span>\n    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span><span class="token punctuation">></span></span><span class="token style"><span class="token language-css">
1\n      <span class="token selector">body</span> <span class="token punctuation">{</span>\n        <span class="token property">margin</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>\n        <span class="token property">padding</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>\n      <span class="token punctuation">}</span>\n      <span class="token selector">#map</span> <span class="token punctuation">{</span>\n        <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>\n        <span class="token property">top</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>\n        <span class="token property">bottom</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>\n        <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>\n      <span class="token punctuation">}</span>\n    </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">></span></span>\n  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span>\n  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span>\n    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>map<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>\n    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript">
1\n      <span class="token keyword">var</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">mapboxgl<span class="token punctuation">.</span>Map</span><span class="token punctuation">(</span><span class="token punctuation">{</span>\n          <span class="token literal-property property">container</span><span class="token operator">:</span> <span class="token string">\'map\'</span><span class="token punctuation">,</span>\n          <span class="token literal-property property">style</span><span class="token operator">:</span> <span class="token string">"https://maps.geoapify.com/v1/styles/osm-carto/style.json?api_key=YOUR_API_KEY"</span><span class="token punctuation">,</span>\n          <span class="token literal-property property">center</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">73.991462</span><span class="token punctuation">,</span> <span class="token number">40.724637</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token comment">// starting position</span>\n          <span class="token literal-property property">zoom</span><span class="token operator">:</span> <span class="token number">12</span><span class="token punctuation">,</span> <span class="token comment">// starting zoom</span>\n          <span class="token literal-property property">pitch</span><span class="token operator">:</span> <span class="token number">60</span><span class="token punctuation">,</span> <span class="token comment">// starting pitch in degrees</span>\n          <span class="token literal-property property">bearing</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token comment">// starting bearing in degree</span>\n      <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n      <span class="token keyword">function</span> <span class="token function">rotateCamera</span><span class="token punctuation">(</span><span class="token parameter">timestamp</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n          <span class="token comment">// rotate at approximately ~10 degrees per second</span>\n          map<span class="token punctuation">.</span><span class="token function">rotateTo</span><span class="token punctuation">(</span><span class="token punctuation">(</span>timestamp <span class="token operator">/</span> <span class="token number">100</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">360</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">duration</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n          <span class="token comment">// request the next frame of the animation</span>\n          <span class="token function">requestAnimationFrame</span><span class="token punctuation">(</span>rotateCamera<span class="token punctuation">)</span><span class="token punctuation">;</span>\n      <span class="token punctuation">}</span>\n\n      map<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">\'load\'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n          <span class="token comment">// start the animation</span>\n          <span class="token function">rotateCamera</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
1\n      <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n      <span class="token comment">// map navigation controls</span>\n      map<span class="token punctuation">.</span><span class="token function">addControl</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">mapboxgl<span class="token punctuation">.</span>NavigationControl</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span>\n  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span>\n<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre></div>'}})),"\n",e.createElement(n.h2,null,"Summary"),"\n",e.createElement(n.p,null,"Mapbox GL generally requires more JavaScript code to be written than Leaflet and can be more complicated to maintain."),"\n",e.createElement(n.p,null,"So, you may ask when to use Leaflet and when to use Mapbox GL?"),"\n",e.createElement(n.p,null,"The answer is simple - if you don't need 3D and extremely fast animation then Leaflet would be the best choice. It has biggest community, best documentation, extensive set of plugins and works well in any situation. And if you really need advanced 3D maps with animations and top rendering speed on modern devices - then Mapbox GL is your friend."),"\n",e.createElement(n.p,null,"Check our article where we compare features of ",e.createElement(n.a,{href:"/map-libraries-comparison-leaflet-vs-maplibre-gl-vs-openlayers-trends-and-statistics/"},"Mapbox GL (Maplibre), Leaflet and OpenLayers")," libraries and make a right choice for your app."),"\n",e.createElement(t,null,e.createElement(n.h2,null,"Geoapify Location Platform"),e.createElement(n.h4,null,"We offer APIs and Components for digital maps. Register and try our APIs for Free!"),e.createElement(o,{className:"max-w-screen-md md:w-full mt-5 md:mx-auto"},e.createElement(p,{type:"primary",noWrap:!0,text:"Learn more",url:"/maps-api/"}),e.createElement(p,{newTab:!0,noWrap:!0,type:"secondary",text:"Get API Key",url:"https://myprojects.geoapify.com"}),e.createElement(p,{newTab:!0,type:"secondary-dark",text:"Playground",url:"https://apidocs.geoapify.com"}))))}var p=function(a){void 0===a&&(a={});const{wrapper:n}=Object.assign({},(0,s.RP)(),a.components);return n?e.createElement(n,a,e.createElement(o,a)):o(a)};function c(a,n){throw new Error("Expected "+(n?"component":"object")+" `"+a+"` to be defined: you likely forgot to import, pass, or provide it.")}var l=t(4794),i=t(2532),r=t(8154),u=t(1574),m=t(7127),g=t(1543),d=t(3428),k=t(369),h=t(2992),f=t(3481),b=t(9911),y=t(9856),w=t(529),v=t(8818),x=t(1435),E=t(5898),A=t(2389),L=t(118),H=t(2833),I=t(9816),M=t(3008),F=t(3960),_=t(7358),V=t(6649);const C={Link:l.Link,SplitSection:f.A,BackgroundPanel:b.A,Card:y.A,Button:w.A,ButtonGroup:v.A,Banner:x.A,PageList:E.A,FAQStructutedData:M.A,HowToStructuredData:A.A,FAQWithStructuredData:L.A,InputCheckbox:H.A,TryGeolocation:I.A,JSONTree:u.d,TableOfContent:F.A,PostImage:_.A,VerticalTimeline:V.VerticalTimeline,VerticalTimelineElement:V.VerticalTimelineElement},q=a=>{let{data:{post:n,logo:t,siteData:o,postFormattedData:p,prevPost:c,nextPost:l},children:u,pageContext:{modifiedTime:f}}=a;const b=n.frontmatter.featuredImage?n.frontmatter.featuredImage.childImageSharp.original:{},y=n.frontmatter.twitterImage2x1?n.frontmatter.twitterImage2x1.childImageSharp.original:{},w=n.frontmatter.categories?n.frontmatter.categories.map((a=>d.A.find((n=>n.id===a)))):null,v=n.frontmatter.tags?n.frontmatter.tags.map((a=>k.A.find((n=>n.id===a)))):null,x=v?v.map((a=>a.label)):null,E=y.src||b.src,A=E?[`https://www.geoapify.com${E}
1`]:null,L=p.frontmatter.featuredImage?p.frontmatter.featuredImage.childImageSharp.gatsbyImageData:null,H="home"===n.frontmatter.slug.split("/").join("")?"https://www.geoapify.com/":`https://www.geoapify.com/${n.frontmatter.slug}/`;return e.createElement(e.Fragment,null,e.createElement(r.m,null,e.createElement("link",{rel:"canonical",href:H,"data-baseprotocol":"https:","data-basehost":"www.geoapify.com"})),e.createElement(g.A,{webpageTitle:n.frontmatter.title_60,webpageDescription:n.frontmatter.description_120,slug:n.frontmatter.slug,imageSrc:b.src,imageWidth:b.width,imageHeight:b.height,imageAlt:n.frontmatter.featuredImageAlt_120,ogType:"article",twitterImageSrc:y.src,twitterTitle:n.frontmatter.twitterTitle_70,twitterImageAlt:n.frontmatter.twitterImageAlt_420,twitterDescription:n.frontmatter.twitterDescription_200,articleSection:"Geo information systems (GIS)",articleTags:x,created:n.frontmatter.first_publiched_date||n.frontmatter.date,modified:f}),e.createElement(h.A,{geoapifySlogan:o.siteMetadata.slogan,companyName:o.siteMetadata.company,logoSrc:t.childImageSharp.gatsbyImageData.src,logoWidth:t.childImageSharp.gatsbyImageData.width,logoHeight:t.childImageSharp.gatsbyImageData.height,slug:n.frontmatter.slug,articleName:n.frontmatter.title_60,articleHeadline:n.frontmatter.headline_110,published:n.frontmatter.first_publiched_date||n.frontmatter.date,modified:f,images:A}),e.createElement(m.A,null,e.createElement("article",{className:"geoapify-post"},e.createElement("header",{className:"geoapify-post-header"},e.createElement("div",{className:"geoapify-post-meta"},e.createElement("span",null,p.frontmatter.date),e.createElement("span",{className:"mx-1"}," / "),n.frontmatter.author?e.createElement("span",null,"by ",e.createElement("a",{rel:"noopener noreferrer",target:"_blank",href:n.frontmatter.authorUrl},n.frontmatter.author)):e.createElement("span",null,"by Geoapify"),w&&w.length?e.createElement("span",{className:"ml-1"}," / in "):null,w&&w.length?w.map(((a,n)=>e.createElement("span",{key:a.id},n?e.createElement("span",null,", "):null,e.createElement("a",{href:`/category/${a.slug}/`},a.label)))):null),e.createElement("h1",null,n.frontmatter.title),n.frontmatter.subtitle?e.createElement("h2",{className:"text-xl text-gray-700 mx-2 font-light"},n.frontmatter.subtitle):null,L?e.createElement("div",{className:"geoapify-post-featured-image"},e.createElement(i.G,{image:L,alt:n.frontmatter.featuredImageAlt_120})):null,n.frontmatter.featuredImageAlt_120?e.createElement("div",{className:"text-center mt-2 mb-10 text-sm italic text-gray-600",dangerouslySetInnerHTML:{__html:n.frontmatter.featuredImageAlt_120}}):e.createElement("div",{className:"mb-10"})),e.createElement("section",{className:"geoapify-post-body"},e.createElement(s.xA,{components:C},u))),e.createElement("div",{className:"mx-5 lg:mx-auto tag-list"},v?v.map((a=>e.createElement("a",{className:"tag",href:`/tag/${a.slug}/`,key:a.id},a.label))):null),e.createElement("div",{className:"post-navigation"},e.createElement("div",{className:"post-navigation-buttons flex flex-col md:flex-row"},c?e.createElement("div",{className:"previous-post"},e.createElement("a",{href:`/${c.frontmatter.slug}/`,rel:"prev"},e.createElement("div",{className:"previous"},e.createElement("span",{className:"chevron lnr lnr-chevron-left"}),e.createElement("div",{className:"title"},e.createElement("span",{className:"meta"},"Previous Post"),e.createElement("span",{className:"post-title"},c.frontmatter.title))))):null,l?e.createElement("div",{className:"next-post"},e.createElement("a",{href:`/${l.frontmatter.slug}/`,rel:"next"},e.createElement("div",{className:"next"},e.createElement("div",{className:"title"},e.createElement("span",{className:"meta"},"Next Post"),e.createElement("span",{className:"post-title"},l.frontmatter.title)),e.createElement("span",{className:"chevron lnr lnr-chevron-right"})))):null))))};function z(a){return e.createElement(q,a,e.createElement(p,a))}}}]);
2//# sourceMappingURL=component---src-template-post-js-content-file-path-src-posts-2019-05-24-map-animation-with-mapbox-gl-index-mdx-fc4ff0ccdc48fe6f6c2b.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.