> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/ios/maps/llms.txt)

# Create a rotating globe

Your browser doesn't support HTML5 video. Open [link to the video](https://docs.mapbox.com/ios/ios/assets/medias/RotatingGlobe-925818676ae5baf1e8948ac4d387efc1.mp4).

This example demonstrates how to implement a spinning globe using the **Mapbox Maps SDK for iOS**.

The example uses the [`setProjection`](https://docs.mapbox.com/ios/maps/api/latest/documentation/mapboxmaps/stylemanager/setprojection(_:)/) method on the [`MapboxMap`](https://docs.mapbox.com/ios/maps/api/latest/documentation/mapboxmaps/mapboxmap/) class to switch from Web Mercator to the Globe Projection. Then uses the [`Atmosphere`](https://docs.mapbox.com/ios/maps/api/latest/documentation/mapboxmaps/atmosphere/) class to style how the globe is displayed, and the [`ease`](https://docs.mapbox.com/ios/maps/api/latest/documentation/mapboxmaps/cameraanimationsmanager/ease(to:duration:curve:completion:)/) method to rotate the globe over time.

> **Note: iOS Examples App Available**
> 
> This example code is part of the **Maps SDK for iOS Examples App**, a working iOS project [available on Github](https://github.com/mapbox/mapbox-maps-ios/tree/11.29.0/Sources/Examples). iOS developers are encouraged to run the examples app locally to interact with this example in an emulator and explore other features of the Maps SDK.
> 
> See our [Run the Maps SDK for iOS Examples App](https://docs.mapbox.com/help/tutorials/maps-sdk-ios-examples-app/) tutorial for step-by-step instructions.

**Swift**

Title: `SpinningGlobeExample.swift`

[View on GitHub](https://github.com/mapbox/mapbox-maps-ios/blob/main/Sources/Examples/All%20Examples/SpinningGlobeExample.swift)

```swift
import Foundation
import UIKit
import MapboxMaps
import CoreLocation

final class SpinningGlobeExample: UIViewController, GestureManagerDelegate, ExampleProtocol {
    private var userInteracting = false
    private var mapView: MapView!
    private var cancelables = Set<AnyCancelable>()

    override func viewDidLoad() {
        super.viewDidLoad()

        mapView = MapView(frame: view.bounds)
        mapView.mapboxMap.mapStyle = .standardSatellite
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        mapView.mapboxMap.setCamera(to: .init(center: CLLocationCoordinate2D(latitude: 40, longitude: -90), zoom: 1.0))
        try! self.mapView.mapboxMap.setProjection(StyleProjection(name: .globe))

        mapView.mapboxMap.onStyleLoaded.observeNext { _ in
            try! self.mapView.mapboxMap.setAtmosphere(Atmosphere())
            self.spinGlobe()
            self.finish()
        }.store(in: &cancelables)

        addStyleLoadingDebugEvents()

        mapView.gestures.delegate = self

        // Enable the camera debug option to see camera state
        let debugOptions: MapViewDebugOptions = [.camera]
        mapView.debugOptions = debugOptions

        view.addSubview(mapView)
    }

    func addStyleLoadingDebugEvents() {
        func logEvent<T: LogableEvent>(_ signal: Signal<T>) {
            signal.observe {
                print(Date(), $0.logString)
            }.store(in: &cancelables)
        }

        logEvent(mapView.mapboxMap.onMapLoadingError)
        logEvent(mapView.mapboxMap.onStyleDataLoaded)
        logEvent(mapView.mapboxMap.onStyleImageMissing)
        logEvent(mapView.mapboxMap.onMapIdle)
        logEvent(mapView.mapboxMap.onMapLoaded)
        logEvent(mapView.mapboxMap.onStyleImageMissing)
        logEvent(mapView.mapboxMap.onStyleImageMissing)
    }

    func spinGlobe() {
        // At low zooms, complete a revolution every two minutes.
        let secPerRevolution = 120.0
        // Above zoom level 5, do not rotate.
        let maxSpinZoom = 5.0
        // Rotate at intermediate speeds between zoom levels 3 and 5.
        let slowSpinZoom = 3.0

        let zoom = mapView.mapboxMap.cameraState.zoom
        if !userInteracting && zoom < maxSpinZoom {
            var distancePerSecond = 360.0 / secPerRevolution
            if zoom > slowSpinZoom {
                // Slow spinning at higher zooms
                let zoomDif = (maxSpinZoom - zoom) / (maxSpinZoom - slowSpinZoom)
                distancePerSecond *= zoomDif
            }
            let center = mapView.mapboxMap.cameraState.center
            let targetCenter = CLLocationCoordinate2D(latitude: center.latitude, longitude: center.longitude - distancePerSecond)

            // Smoothly animate the map over one second.
            // When this animation is complete, call it again
            mapView.camera.ease(to: .init(center: targetCenter), duration: 1.0, curve: .linear) { [weak self] rotating in

                guard rotating == .end else {
                    return
                }
                self?.spinGlobe()
            }
        }
    }

    func gestureManager(_ gestureManager: GestureManager, didBegin gestureType: GestureType) {
        userInteracting = true
    }

    func gestureManager(_ gestureManager: GestureManager, didEnd gestureType: GestureType, willAnimate: Bool) {

        if !willAnimate {
            userInteracting = false
            DispatchQueue.main.async {
                self.spinGlobe()
            }
        }
    }

    func gestureManager(_ gestureManager: GestureManager, didEndAnimatingFor gestureType: GestureType) {
        userInteracting = false
        DispatchQueue.main.async {
            self.spinGlobe()
        }
    }
}
```