{"action":"created","comment":{"url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/pulls/comments/169129318","pull_request_review_id":97606252,"id":169129318,"diff_hunk":"@@ -0,0 +1,160 @@\n+package com.mapbox.mapboxsdk.plugins.locationlayer.camera;\n+\n+import android.animation.Animator;\n+import android.animation.AnimatorSet;\n+import android.animation.ValueAnimator;\n+import android.support.annotation.NonNull;\n+import android.support.annotation.Nullable;\n+\n+import com.mapbox.mapboxsdk.camera.CameraPosition;\n+import com.mapbox.mapboxsdk.geometry.LatLng;\n+import com.mapbox.mapboxsdk.maps.MapboxMap;\n+\n+import java.util.ArrayList;\n+import java.util.List;\n+\n+public class MapAnimator {\n+\n+  private List<Animator> animators;\n+  private AnimatorSet animatorSet;\n+\n+  private MapAnimator(List<Animator> animators) {\n+    this.animators = animators;\n+    animatorSet = new AnimatorSet();\n+  }\n+\n+  public void playTogether() {\n+    animatorSet.playTogether(animators);\n+    animatorSet.start();\n+  }\n+\n+  public void playTogether(@Nullable Animator.AnimatorListener listener) {\n+    animatorSet.addListener(listener);\n+    playTogether();\n+  }\n+\n+  public void playSequentially() {\n+    animatorSet.playSequentially(animators);\n+    animatorSet.start();\n+  }\n+\n+  public void playSequentially(@Nullable Animator.AnimatorListener listener) {\n+    animatorSet.addListener(listener);\n+    playSequentially();\n+  }\n+\n+  public void cancel() {\n+    animatorSet.cancel();\n+  }\n+\n+  public static Builder builder(MapboxMap mapboxMap) {\n+    return new Builder(mapboxMap);\n+  }\n+\n+  public static final class Builder {\n+\n+    private final MapboxMap mapboxMap;\n+    private List<Animator> animators;\n+    private CameraPosition currentPosition;\n+\n+    private Builder(MapboxMap mapboxMap) {\n+      this.mapboxMap = mapboxMap;\n+      this.animators = new ArrayList<>();\n+      // Get the current target from the current map camera position\n+      currentPosition = mapboxMap.getCameraPosition();\n+    }\n+\n+    public Builder addLatLngAnimator(@NonNull LatLngAnimator latLngAnimator) {\n+\n+      LatLng currentTarget = currentPosition.target;\n+      if (currentTarget == latLngAnimator.getTarget()) {\n+        return this;\n+      }\n+\n+      latLngAnimator.setObjectValues(currentTarget, latLngAnimator.getTarget());\n+      latLngAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {\n+        @Override\n+        public void onAnimationUpdate(ValueAnimator animation) {\n+          mapboxMap.setLatLng((LatLng) animation.getAnimatedValue());\n+        }\n+      });\n+\n+      animators.add(latLngAnimator);\n+      return this;\n+    }\n+\n+    public Builder addZoomAnimator(@NonNull ZoomAnimator zoomAnimator) {\n+\n+      float currentZoom = (float) currentPosition.zoom;\n+      if (currentZoom == zoomAnimator.getTargetZoom()) {\n+        return this;\n+      }\n+\n+      zoomAnimator.setFloatValues(currentZoom, zoomAnimator.getTargetZoom());\n+      zoomAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {\n+        @Override\n+        public void onAnimationUpdate(ValueAnimator animation) {\n+          mapboxMap.setZoom((Float) animation.getAnimatedValue());\n+        }\n+      });\n+\n+      animators.add(zoomAnimator);\n+      return this;\n+    }\n+\n+    public Builder addBearingAnimator(@NonNull BearingAnimator bearingAnimator) {\n+\n+      float currentBearing = (float) currentPosition.bearing;\n+      float normalizedTargetBearing = normalizeBearing(currentBearing, bearingAnimator.getTargetBearing());\n+      if (currentBearing == normalizedTargetBearing) {\n+        return this;\n+      }\n+\n+      bearingAnimator.setFloatValues(currentBearing, normalizedTargetBearing);\n+      bearingAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {\n+        @Override\n+        public void onAnimationUpdate(ValueAnimator animation) {\n+          mapboxMap.setBearing((Float) animation.getAnimatedValue());\n+        }\n+      });\n+\n+      animators.add(bearingAnimator);\n+      return this;\n+    }\n+\n+    public Builder addTiltAnimator(@NonNull TiltAnimator tiltAnimator) {\n+\n+      float currentTilt = (float) currentPosition.tilt;\n+      if (currentTilt == tiltAnimator.getTargetTilt()) {\n+        return this;\n+      }\n+\n+      tiltAnimator.setFloatValues(currentTilt, tiltAnimator.getTargetTilt());\n+      tiltAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {\n+        @Override\n+        public void onAnimationUpdate(ValueAnimator animation) {\n+          mapboxMap.setTilt((Float) animation.getAnimatedValue());\n+        }\n+      });\n+\n+      animators.add(tiltAnimator);\n+      return this;\n+    }\n+\n+\n+\n+    public MapAnimator build() {\n+      return new MapAnimator(animators);\n+    }\n+  }\n+\n+  private static float normalizeBearing(float currentBearing, float targetBearing) {","path":"plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/MapAnimator.java","position":151,"original_position":151,"commit_id":"6f79da7a82dde7dc529f4cd2217152781f792900","original_commit_id":"6f79da7a82dde7dc529f4cd2217152781f792900","user":{"login":"cammace","id":5652865,"avatar_url":"https://avatars2.githubusercontent.com/u/5652865?v=4","gravatar_id":"","url":"https://api.github.com/users/cammace","html_url":"https://github.com/cammace","followers_url":"https://api.github.com/users/cammace/followers","following_url":"https://api.github.com/users/cammace/following{/other_user}","gists_url":"https://api.github.com/users/cammace/gists{/gist_id}","starred_url":"https://api.github.com/users/cammace/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cammace/subscriptions","organizations_url":"https://api.github.com/users/cammace/orgs","repos_url":"https://api.github.com/users/cammace/repos","events_url":"https://api.github.com/users/cammace/events{/privacy}","received_events_url":"https://api.github.com/users/cammace/received_events","type":"User","site_admin":false},"body":"We should just extract this method into the Utils class since I already use the same logic in `LocationLayerPlugin`","created_at":"2018-02-19T16:51:45Z","updated_at":"2018-02-19T16:51:45Z","html_url":"https://github.com/mapbox/mapbox-plugins-android/pull/293#discussion_r169129318","pull_request_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/pulls/293","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/mapbox/mapbox-plugins-android/pulls/comments/169129318"},"html":{"href":"https://github.com/mapbox/mapbox-plugins-android/pull/293#discussion_r169129318"},"pull_request":{"href":"https://api.github.com/repos/mapbox/mapbox-plugins-android/pulls/293"}}},"pull_request":{"url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/pulls/293","id":170009399,"html_url":"https://github.com/mapbox/mapbox-plugins-android/pull/293","diff_url":"https://github.com/mapbox/mapbox-plugins-android/pull/293.diff","patch_url":"https://github.com/mapbox/mapbox-plugins-android/pull/293.patch","issue_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/issues/293","number":293,"state":"open","locked":false,"title":"Map + Location Animators ","user":{"login":"danesfeder","id":8434572,"avatar_url":"https://avatars0.githubusercontent.com/u/8434572?v=4","gravatar_id":"","url":"https://api.github.com/users/danesfeder","html_url":"https://github.com/danesfeder","followers_url":"https://api.github.com/users/danesfeder/followers","following_url":"https://api.github.com/users/danesfeder/following{/other_user}","gists_url":"https://api.github.com/users/danesfeder/gists{/gist_id}","starred_url":"https://api.github.com/users/danesfeder/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danesfeder/subscriptions","organizations_url":"https://api.github.com/users/danesfeder/orgs","repos_url":"https://api.github.com/users/danesfeder/repos","events_url":"https://api.github.com/users/danesfeder/events{/privacy}","received_events_url":"https://api.github.com/users/danesfeder/received_events","type":"User","site_admin":false},"body":"This PR will aim to add new, more powerful APIs for animating the `MapboxMap` camera.  This functionality will include the ability to account for padding, zoom, and tilt when animating towards a targeted `LatLng`.  Can be integrated with the `LocationLayer` to add the same camera tracking functionality found in the currently `MyLocationView` in the Maps SDK. \r\n\r\ncc @tobrun @LukasPaczos \r\n\r\n","created_at":"2018-02-19T16:49:04Z","updated_at":"2018-02-19T16:51:45Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7eb14db35ca3932c46002d512fa057ef6ed0cb16","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/pulls/293/commits","review_comments_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/pulls/293/comments","review_comment_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/issues/293/comments","statuses_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/statuses/6f79da7a82dde7dc529f4cd2217152781f792900","head":{"label":"mapbox:map-location-animators","ref":"map-location-animators","sha":"6f79da7a82dde7dc529f4cd2217152781f792900","user":{"login":"mapbox","id":600935,"avatar_url":"https://avatars1.githubusercontent.com/u/600935?v=4","gravatar_id":"","url":"https://api.github.com/users/mapbox","html_url":"https://github.com/mapbox","followers_url":"https://api.github.com/users/mapbox/followers","following_url":"https://api.github.com/users/mapbox/following{/other_user}","gists_url":"https://api.github.com/users/mapbox/gists{/gist_id}","starred_url":"https://api.github.com/users/mapbox/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mapbox/subscriptions","organizations_url":"https://api.github.com/users/mapbox/orgs","repos_url":"https://api.github.com/users/mapbox/repos","events_url":"https://api.github.com/users/mapbox/events{/privacy}","received_events_url":"https://api.github.com/users/mapbox/received_events","type":"Organization","site_admin":false},"repo":{"id":87212987,"name":"mapbox-plugins-android","full_name":"mapbox/mapbox-plugins-android","owner":{"login":"mapbox","id":600935,"avatar_url":"https://avatars1.githubusercontent.com/u/600935?v=4","gravatar_id":"","url":"https://api.github.com/users/mapbox","html_url":"https://github.com/mapbox","followers_url":"https://api.github.com/users/mapbox/followers","following_url":"https://api.github.com/users/mapbox/following{/other_user}","gists_url":"https://api.github.com/users/mapbox/gists{/gist_id}","starred_url":"https://api.github.com/users/mapbox/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mapbox/subscriptions","organizations_url":"https://api.github.com/users/mapbox/orgs","repos_url":"https://api.github.com/users/mapbox/repos","events_url":"https://api.github.com/users/mapbox/events{/privacy}","received_events_url":"https://api.github.com/users/mapbox/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mapbox/mapbox-plugins-android","description":"Experimental plugins to supercharge your maps ⚡️","fork":false,"url":"https://api.github.com/repos/mapbox/mapbox-plugins-android","forks_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/forks","keys_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/teams","hooks_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/hooks","issue_events_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/issues/events{/number}","events_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/events","assignees_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/assignees{/user}","branches_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/branches{/branch}","tags_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/tags","blobs_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/git/refs{/sha}","trees_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/statuses/{sha}","languages_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/languages","stargazers_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/stargazers","contributors_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/contributors","subscribers_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/subscribers","subscription_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/subscription","commits_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/commits{/sha}","git_commits_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/git/commits{/sha}","comments_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/comments{/number}","issue_comment_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/issues/comments{/number}","contents_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/contents/{+path}","compare_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/merges","archive_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/downloads","issues_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/issues{/number}","pulls_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/pulls{/number}","milestones_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/milestones{/number}","notifications_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/labels{/name}","releases_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/releases{/id}","deployments_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/deployments","created_at":"2017-04-04T16:56:50Z","updated_at":"2018-02-18T13:18:41Z","pushed_at":"2018-02-19T16:49:06Z","git_url":"git://github.com/mapbox/mapbox-plugins-android.git","ssh_url":"git@github.com:mapbox/mapbox-plugins-android.git","clone_url":"https://github.com/mapbox/mapbox-plugins-android.git","svn_url":"https://github.com/mapbox/mapbox-plugins-android","homepage":null,"size":1764,"stargazers_count":39,"watchers_count":39,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":17,"mirror_url":null,"archived":false,"open_issues_count":70,"license":{"key":"bsd-2-clause","name":"BSD 2-Clause \"Simplified\" License","spdx_id":"BSD-2-Clause","url":"https://api.github.com/licenses/bsd-2-clause"},"forks":17,"open_issues":70,"watchers":39,"default_branch":"master"}},"base":{"label":"mapbox:master","ref":"master","sha":"4cb4a740c03340ec1cf5a1c21a47538e20a29454","user":{"login":"mapbox","id":600935,"avatar_url":"https://avatars1.githubusercontent.com/u/600935?v=4","gravatar_id":"","url":"https://api.github.com/users/mapbox","html_url":"https://github.com/mapbox","followers_url":"https://api.github.com/users/mapbox/followers","following_url":"https://api.github.com/users/mapbox/following{/other_user}","gists_url":"https://api.github.com/users/mapbox/gists{/gist_id}","starred_url":"https://api.github.com/users/mapbox/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mapbox/subscriptions","organizations_url":"https://api.github.com/users/mapbox/orgs","repos_url":"https://api.github.com/users/mapbox/repos","events_url":"https://api.github.com/users/mapbox/events{/privacy}","received_events_url":"https://api.github.com/users/mapbox/received_events","type":"Organization","site_admin":false},"repo":{"id":87212987,"name":"mapbox-plugins-android","full_name":"mapbox/mapbox-plugins-android","owner":{"login":"mapbox","id":600935,"avatar_url":"https://avatars1.githubusercontent.com/u/600935?v=4","gravatar_id":"","url":"https://api.github.com/users/mapbox","html_url":"https://github.com/mapbox","followers_url":"https://api.github.com/users/mapbox/followers","following_url":"https://api.github.com/users/mapbox/following{/other_user}","gists_url":"https://api.github.com/users/mapbox/gists{/gist_id}","starred_url":"https://api.github.com/users/mapbox/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mapbox/subscriptions","organizations_url":"https://api.github.com/users/mapbox/orgs","repos_url":"https://api.github.com/users/mapbox/repos","events_url":"https://api.github.com/users/mapbox/events{/privacy}","received_events_url":"https://api.github.com/users/mapbox/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mapbox/mapbox-plugins-android","description":"Experimental plugins to supercharge your maps ⚡️","fork":false,"url":"https://api.github.com/repos/mapbox/mapbox-plugins-android","forks_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/forks","keys_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/teams","hooks_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/hooks","issue_events_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/issues/events{/number}","events_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/events","assignees_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/assignees{/user}","branches_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/branches{/branch}","tags_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/tags","blobs_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/git/refs{/sha}","trees_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/statuses/{sha}","languages_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/languages","stargazers_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/stargazers","contributors_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/contributors","subscribers_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/subscribers","subscription_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/subscription","commits_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/commits{/sha}","git_commits_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/git/commits{/sha}","comments_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/comments{/number}","issue_comment_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/issues/comments{/number}","contents_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/contents/{+path}","compare_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/merges","archive_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/downloads","issues_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/issues{/number}","pulls_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/pulls{/number}","milestones_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/milestones{/number}","notifications_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/labels{/name}","releases_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/releases{/id}","deployments_url":"https://api.github.com/repos/mapbox/mapbox-plugins-android/deployments","created_at":"2017-04-04T16:56:50Z","updated_at":"2018-02-18T13:18:41Z","pushed_at":"2018-02-19T16:49:06Z","git_url":"git://github.com/mapbox/mapbox-plugins-android.git","ssh_url":"git@github.com:mapbox/mapbox-plugins-android.git","clone_url":"https://github.com/mapbox/mapbox-plugins-android.git","svn_url":"https://github.com/mapbox/mapbox-plugins-android","homepage":null,"size":1764,"stargazers_count":39,"watchers_count":39,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":17,"mirror_url":null,"archived":false,"open_issues_count":70,"license":{"key":"bsd-2-clause","name":"BSD 2-Clause \"Simplified\" License","spdx_id":"BSD-2-Clause","url":"https://api.github.com/licenses/bsd-2-clause"},"forks":17,"open_issues":70,"watchers":39,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mapbox/mapbox-plugins-android/pulls/293"},"html":{"href":"https://github.com/mapbox/mapbox-plugins-android/pull/293"},"issue":{"href":"https://api.github.com/repos/mapbox/mapbox-plugins-android/issues/293"},"comments":{"href":"https://api.github.com/repos/mapbox/mapbox-plugins-android/issues/293/comments"},"review_comments":{"href":"https://api.github.com/repos/mapbox/mapbox-plugins-android/pulls/293/comments"},"review_comment":{"href":"https://api.github.com/repos/mapbox/mapbox-plugins-android/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mapbox/mapbox-plugins-android/pulls/293/commits"},"statuses":{"href":"https://api.github.com/repos/mapbox/mapbox-plugins-android/statuses/6f79da7a82dde7dc529f4cd2217152781f792900"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"cammace"}}