Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GMap Bearing rotation in smooth motion (avoid jerky effect when changing bearing values)

I want to rotate GMap by changing the bearing angle value, so the camera rotates around the center point (360-Degree one full round ). When we change the bearing, there is a easing effect at camera start and end points. How can I control/change that in order to make the rotation smooth when change Bearing values (in order to rotate map in 360 Degree, smooth animation)?

Required this for all languages as it appears the easing effect is different in different language libraries. e.g. Swift, Android, PHP, JS, Node.js, React.

Swift Example (running OK in Linear Animation):

Note that initially the animation did had jerks in iOS as well, but when we make use of CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear along its CATransaction properties then the GMap animation turned into smooth animation. so now if you see the code below, the change in Bearing value does not create jerky effect (due to the easing effect in GMap animation). I am looking for appropriate solution for Android and Web as well.

//Move the map around current location, first loop
let timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
CATransaction.begin()
CATransaction.setValue(3.0, forKey: kCATransactionAnimationDuration)
CATransaction.setAnimationTimingFunction(timingFunction)
CATransaction.setCompletionBlock({
    //Move the map around current location, second loop
    let timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    CATransaction.begin()
    CATransaction.setValue(3.0, forKey: kCATransactionAnimationDuration)
    CATransaction.setAnimationTimingFunction(timingFunction)
    CATransaction.setCompletionBlock({
        //Move the map around current location, third loop
        let timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
        CATransaction.begin()
        CATransaction.setValue(3.0, forKey: kCATransactionAnimationDuration)
        CATransaction.setAnimationTimingFunction(timingFunction)
        CATransaction.setCompletionBlock({
            UIView.animate(withDuration: 0.5, animations: {
                self.findingYourLocation.alpha = 0.0
            })
            //TODO: Set nearest branch
            // Zoom in one zoom level
            let zoomCamera = GMSCameraUpdate.zoomIn()
            self.mapView.animate(with: zoomCamera)

            // Center the camera on UBL Branch when animation finished
            //let nearestBranch = CLLocationCoordinate2D(latitude: 24.850751, longitude: 67.016589)
            let nearestBranch = CLLocationCoordinate2D.init(latitude: 24.806849, longitude: 67.038734)
            let nearestBranchCam = GMSCameraUpdate.setTarget(nearestBranch)



            CATransaction.begin()

            let timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
            CATransaction.setValue(3.0, forKey: kCATransactionAnimationDuration)
            CATransaction.setAnimationTimingFunction(timingFunction)
            CATransaction.setCompletionBlock({
                self.nextButton.alpha = 1.0
            })
            self.mapView.animate(with: nearestBranchCam)
            self.mapView.animate(toZoom: 15)
            self.mapView.animate(toBearing: 0)
            self.mapView.animate(toViewingAngle: 0)

            CATransaction.commit()

        })
        self.mapView.animate(toBearing: self.mapView.camera.bearing + 120)
        CATransaction.commit()

    })
    self.mapView.animate(toBearing: self.mapView.camera.bearing + 120)
    CATransaction.commit()

})
self.mapView.animate(toBearing: self.mapView.camera.bearing + 120)
CATransaction.commit()

The Android example code (has problem):

The Android example/sample code can be found here: https://issuetracker.google.com/issues/71738889

Which also includes an .apk file, an .mp4 video of sample app output. Which clearly shows jerky effects when Bearing value changes while rotating the map in 360-Degree.

like image 865
Nah Avatar asked Jan 06 '18 02:01

Nah


1 Answers

I'm going to write this as another answer as I'd like to take the time to write a wall of text, whereas I'd like to keep the other answer as short as possible since it might still help other people with a similar problem.

The problem

So if I understand correctly, what you're trying to do is build an application with Google maps for different platforms. You're running into an issue with Google maps (the jerky movement) and you're trying to find a fix for all the platforms.

My proposed solutions

I'll divide this into a few sections, because I see different ways to go forward.

  • Find a solution for all the platforms.

This one seems like the most straightforward, but it could be akin to the XY problem. I've tried to introduce you to some ways of animating views, and you've solved the problem in your iOS app, but at the core what you're dealing with is a flaw in the Google maps animation when changing the bearing. I am not sure if there is a way to tackle this problem on every platform, as I haven't tried.

  • Use a different map

This sounds like a big step, and depending on your usage something you don't want to do. However, I've successfully used Leaflet (a JS map) with a WKWebView on iOS and Android and that all worked pretty well (this obviously also works fine in the browser). Keep in mind that some other maps might also have the jerky animation.

Wrapping it up

I hope I've given some insight. I'll add to this answer as we find out new things about the problem. Could you try to provide a minimal reproducible example? That way I can give it a better try. Good luck!

like image 153
JillevdW Avatar answered Nov 19 '22 01:11

JillevdW