Select to view content in your preferred language

Is there any way to lock the heading of the camera in a SceneView?

2255
14
07-14-2023 01:20 AM
alionthego
Emerging Contributor

I am trying to lock the heading of the camera on a SceneView to North as the user scrolls around the map.

 I can't see any option to do that other than a .onChanged modifier to the camera.  The problem with this is if you listen for changes to camera and change the heading back to North each time, you both lose the momentum scroll and also it will mess up other camera functionality like allowing the user to go to present position.  

Is there any way at all to lock the camera heading on North or any other heading as the user scrolls around the 3D sceneView other than listening to Camera changes and replacing the camera each time?

Being new to this I also have noticed that the Camera properties are get only so each time you need to assign a new Camera to the SceneView if you want to change the heading programmatically which is why the listener approach does not work well.

0 Kudos
14 Replies
Ting
by Esri Contributor
Esri Contributor

We don't have a specific API for this behavior. However, you can achieve this by using the interaction status modifier like below. It is a more subtle way than just replacing the camera state property, which would cause a bouncing visual effect.

import SwiftUI
import ArcGIS

struct ContentView: View {
    @State private var scene = Scene(basemapStyle: .arcGISImagery)
    
    @State private var camera: Camera? = Camera(lookingAt: Point(latitude: 34, longitude: -117), distance: 5e4, heading: 0, pitch: 30, roll: 0)
    
    var body: some View {
        SceneViewReader { proxy in
            SceneView(scene: scene, camera: $camera)
                .onInteractingChanged { isChanging in
                    if let camera, !isChanging {
                        Task {
                            await proxy.setViewpointCamera(camera.rotatedTo(heading: 0, pitch: camera.pitch, roll: camera.roll), duration: 0.3)
                        }
                    }
                }
        }
    }
}

 It will reset the viewpoint camera's heading to north once the interaction stops. You can tweak the animation duration to make it feel more natural, or use other view status changed event to reset the camera.

I'll raise this request to our 3D team so they can look further at what they can do to improve this.

0 Kudos
alionthego
Emerging Contributor

Thanks for the reply.  I don’t see the .onInteractingChanged in SwiftUI or ArcGIS (200) library?  Is this for an earlier version of ArcGIS?

0 Kudos
Ting
by Esri Contributor
Esri Contributor

Oops, that modifier will be released in the next update in a few weeks.

0 Kudos
alionthego
Emerging Contributor

Understand.  But if the effect is to change the heading after the momentum is finished it is not what I am looking for or what other apps I've used for Global navigation are using.  I want to be able to lock the heading and maintain the momentum as the user pans the globe around.  Without this when navigating around in an atlas app or global navigation app it is very confusing as you easily end up 'upside down' .  I hope this feature will be included in a near future release.  Thanks very much.

0 Kudos
Ting
by Esri Contributor
Esri Contributor

Thanks for the suggestion. We will look into the GlobeCameraController API and try to add some options. Coincidentally there is another question on limiting the extent of a scene view, so we want to factor in the most popular usecases before improving that API. Will let you know once we reach the next step.

0 Kudos
alionthego
Emerging Contributor

I have recently been finding the limitation of not being able to lock the camera to North very concerning in my app.  It's so easy to get completely disorientated and have the map upside down when panning and really curious why this feature is not available.  

The two most commonly used 3D maps used worldwide are Google Maps and Apple Maps.  In google maps if you select Globe view and in Apple Maps the default globe view map both lock to north when spinning around and panning across the earth.  Without it, such a map would be frustrating to use which is the problem I'm having.  I understand how locally this would not be a major issue but with any map that is using a global perspective this becomes very limiting.   And I would think one main use of a SceneView is the global perspective.

I have implemented observer on the camera to change the viewPoint each time forcing it to North but losing the momentum makes it feel jerky and unnatural.  Really hope you guys will come back to this soon.  Thanks very much.

0 Kudos
alionthego
Emerging Contributor

A great example of north fixed panning is the Apple Maps native app.  If you zoom right out and pan that is similar to the effect I’m trying to achieve.  

0 Kudos
Ting
by Esri Contributor
Esri Contributor

I've logged an issue in our future release plan. This is indeed a very important user feature that we want to support so thanks for bringing it up!

Meanwhile, you may give the Compass toolkit component a try and enable user to reset the heading if it is all upside down.

0 Kudos
alionthego
Emerging Contributor

Thanks very much.  Look forward to seeing this implemented in the future.

0 Kudos