Animate camera properties independently / Mergeable camera animations
Rationale
Currently camera position is either set
- programmatically:
- with animation:
map.flyTo/map.easeTo - without animation:
map.jumpTo
- with animation:
- through user interaction
dragPanscrollZoom
Whenever a user interacts during an animation, this will stop the animation mid-flight.
For a lot of interactions this is the correct default, but p.ex when animating padding in combination with scrollZoom: { around: 'center' } it can cause lay-out issues. As padding is often used to account for UI elements, stopping their animation mid-flight is not ideal:
https://github.com/user-attachments/assets/62595f30-a32e-47cd-ac75-411361f7c806
(video displaying how the map is offcentered after interrupting the padding-animation midflight)
As a workaround I am in the process of writing my own camera-controller to independently set padding and other camera-properties through requestAnimationFraming map.jumpTo, but it has the reverse problem: as I can not stop padding animations midflight I can not use maplibre's default dragPan while padding-animation is running. To enable that feature I would need to take over all user interactions, which adds a lot of complexity.
A possible upstreamed solution would be to make camera properties be able to be animated separately from each other.
I am not sure how this would look like from api side, but maybe something like map.flyTo({ merge: true, interruptible: 'auto', padding: { left: 500 }}).
mergemerge: false[default] stops all ongoing animations and starts a new animation, except from camera-animations that were set withinterruptible: falsemerge: 'auto'stops all animation(s) withinterruptible: trueand merges the camera-properties that were set withinterruptible: 'auto'orinterruptible: falsemerge: trueit merges the new camera-properties with all of its previous camera-properties and ongoing -animations
interruptibleinterruptible: true[default] signals to all future animations that as long as that future animation does not havemerge: true, it should stop the current animation.interruptible: 'auto'signals to all future animations that it should not stop this animation if that future animation has eithermerge: trueormerge: 'auto'interruptible: falsesignals to all future animations that it should never stop this animation
All handlers would then set it with map.jumpTo({ merge: 'auto', ... }), allowing for users to merge p.ex animating padding while it is panning.
With this api proposal this feature would not be a breaking change: the combined defaults would create the current behavior.
Impact
If we do nothing the current behaviour causes UI layout issues. To account for this the user would need to take up a lot of complexity that could be better handled on the library side.
Source: maplibre/maplibre-gl-js