Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add animation utilities + demo. #17

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions demo/AndroidManifest.xml
Expand Up @@ -44,6 +44,7 @@
<activity android:name=".PolyDecodeDemoActivity"/>
<activity android:name=".TextIconDemoActivity"/>
<activity android:name=".DistanceDemoActivity"/>
<activity android:name=".AnimationDemoActivity"/>

</application>

Expand Down
6 changes: 6 additions & 0 deletions demo/build.gradle
Expand Up @@ -29,3 +29,9 @@ android {
}
}
}

task startDemo(type: Exec) {
dependsOn 'installDebug'
def adb = new File(System.env.ANDROID_HOME, "platform-tools${File.separator}adb")
commandLine adb, "shell", "am", "start", "-n", "com.google.maps.android.utils.demo/.MainActivity"
}
@@ -0,0 +1,42 @@
package com.google.maps.android.utils.demo;

import android.animation.ValueAnimator;
import android.annotation.SuppressLint;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.maps.android.animation.Animation;
import com.google.maps.android.animation.SphericalAnimation;
import com.google.maps.android.ui.TextIconGenerator;

public class AnimationDemoActivity extends BaseDemoActivity implements GoogleMap.OnMapClickListener {
private Marker mClickyMarker;

@SuppressLint("NewApi")
@Override
protected void startDemo() {
getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(0, -180), 3));
Marker marker = getMap().addMarker(new MarkerOptions().position(new LatLng(-30, -170)).draggable(true));

ValueAnimator animator = Animation.ofMarkerPosition(marker, new LatLng(30, 170));
animator.setDuration(2000);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setRepeatMode(ValueAnimator.REVERSE);
animator.start();

getMap().setOnMapClickListener(this);

mClickyMarker = getMap().addMarker(new MarkerOptions().position(new LatLng(-20, 175)).
icon(BitmapDescriptorFactory.fromBitmap(new TextIconGenerator(this).makeIcon("Click the map!"))));
}

@SuppressLint("NewApi")
@Override
public void onMapClick(LatLng latLng) {
SphericalAnimation.ofMarkerPosition(mClickyMarker, latLng).start();
}
}
Expand Up @@ -20,6 +20,7 @@ protected void onCreate(Bundle savedInstanceState) {
addDemo("PolyUtil.decode", PolyDecodeDemoActivity.class);
addDemo("TextIconGenerator", TextIconDemoActivity.class);
addDemo("SphericalUtil.computeDistanceBetween", DistanceDemoActivity.class);
addDemo("Marker Animation", AnimationDemoActivity.class);
}

private void addDemo(String demoName, Class<? extends Activity> activityClass) {
Expand Down
62 changes: 62 additions & 0 deletions library/src/com/google/maps/android/animation/Animation.java
@@ -0,0 +1,62 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.maps.android.animation;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.os.Build;

import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class Animation {
/**
* Constructs and returns a ValueAnimator that animates between LatLng values.
* @param latLngs A set of locations that the animation will animate between over time.
*/
public static ValueAnimator ofLatLng(LatLng... latLngs) {
return ValueAnimator.ofObject(new LatLngTypeEvaluator(), latLngs);
}

/**
* Constructs and returns an ObjectAnimator that animates between LatLng values.
*
* @param target The object whose property is to be animated.
* @param propertyName The property being animated.
* @param latLngs A set of locations that the animation will animate between over time.
*/
public static ValueAnimator ofLatLng(Object target, String propertyName, LatLng... latLngs) {
return ObjectAnimator.ofObject(target, propertyName, new LatLngTypeEvaluator(), latLngs);
}

/**
* Constructs and returns an ObjectAnimator that animates a Marker's position between LatLng values.
*
* @param target The marker whose position is to be animated.
* @param latLngs A set of locations that the marker will animate between over time.
* @return An ObjectAnimator object that is set up to animate between the given values.
*/
public static ValueAnimator ofMarkerPosition(Marker target, LatLng... latLngs) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return ObjectAnimator.ofObject(target, new PositionProperty(), new LatLngTypeEvaluator(), latLngs);
}
return ofLatLng(target, "position", latLngs);
}
}
@@ -0,0 +1,42 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.maps.android.animation;

import android.animation.TypeEvaluator;
import android.annotation.TargetApi;
import android.os.Build;

import com.google.android.gms.maps.model.LatLng;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
class LatLngTypeEvaluator implements TypeEvaluator<LatLng> {
@Override
public LatLng evaluate(float v, LatLng a, LatLng b) {
double lat = interp(v, a.latitude, b.latitude);

// Take the shortest path across the 180th meridian.
double lngDelta = a.longitude - b.longitude;
if (Math.abs(lngDelta) < 180) {
return new LatLng(lat, interp(v, a.longitude, b.longitude));
}
return new LatLng(lat, interp(v, a.longitude, b.longitude + Math.signum(lngDelta) * 360));
}

private double interp(float v, double a, double b) {
return a + (b - a) * v;
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.maps.android.animation;

import android.annotation.TargetApi;
import android.os.Build;
import android.util.Property;

import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
class PositionProperty extends Property<Marker, LatLng> {
public PositionProperty() {
super(LatLng.class, "position");
}

@Override
public void set(Marker marker, LatLng latLng) {
marker.setPosition(latLng);
}

@Override
public LatLng get(Marker marker) {
return marker.getPosition();
}
}
@@ -0,0 +1,62 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.maps.android.animation;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.os.Build;

import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class SphericalAnimation {
/**
* Constructs and returns a ValueAnimator that animates between LatLng values.
* @param latLngs A set of locations that the animation will animate between over time.
*/
public static ValueAnimator ofLatLng(LatLng... latLngs) {
return ValueAnimator.ofObject(new SphericalLatLngTypeEvaluator(), latLngs);
}

/**
* Constructs and returns an ObjectAnimator that animates between LatLng values.
*
* @param target The object whose property is to be animated.
* @param propertyName The property being animated.
* @param latLngs A set of locations that the animation will animate between over time.
*/
public static ValueAnimator ofLatLng(Object target, String propertyName, LatLng... latLngs) {
return ObjectAnimator.ofObject(target, propertyName, new SphericalLatLngTypeEvaluator(), latLngs);
}

/**
* Constructs and returns an ObjectAnimator that animates a Marker's position between LatLng values.
*
* @param target The marker whose position is to be animated.
* @param latLngs A set of locations that the marker will animate between over time.
* @return An ObjectAnimator object that is set up to animate between the given values.
*/
public static ValueAnimator ofMarkerPosition(Marker target, LatLng... latLngs) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return ObjectAnimator.ofObject(target, new PositionProperty(), new SphericalLatLngTypeEvaluator(), latLngs);
}
return ofLatLng(target, "position", latLngs);
}
}
@@ -0,0 +1,32 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.maps.android.animation;

import android.animation.TypeEvaluator;
import android.annotation.TargetApi;
import android.os.Build;

import com.google.android.gms.maps.model.LatLng;
import com.google.maps.android.SphericalUtil;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
class SphericalLatLngTypeEvaluator implements TypeEvaluator<LatLng> {
@Override
public LatLng evaluate(float v, LatLng a, LatLng b) {
return SphericalUtil.interpolate(a, b, v);
}
}