Skip to content

Commit

Permalink
Ability to set animation interpolator
Browse files Browse the repository at this point in the history
  • Loading branch information
p-lr committed Jul 3, 2020
1 parent 3884fbb commit 078ef17
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 23 deletions.
4 changes: 2 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[ ![Download](https://api.bintray.com/packages/peterlaurence/maven/mapview/images/download.svg?version=2.0.9) ](https://bintray.com/peterlaurence/maven/mapview/2.0.9/link)
[ ![Download](https://api.bintray.com/packages/peterlaurence/maven/mapview/images/download.svg?version=2.0.10) ](https://bintray.com/peterlaurence/maven/mapview/2.0.10/link)

# MapView

Expand Down Expand Up @@ -60,7 +60,7 @@ There are some breaking changes, although most of them are just package refactor

Add this to your module's build.gradle
```groovy
implementation 'com.peterlaurence:mapview:2.0.9'
implementation 'com.peterlaurence:mapview:2.0.10'
```

## Origin and motivation
Expand Down
2 changes: 1 addition & 1 deletion mapview/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlinx-serialization'

def versionTag = "2.0.9"
def versionTag = "2.0.10"

androidExtensions {
experimental = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package com.peterlaurence.mapview.layout
import android.content.Context
import android.util.AttributeSet
import android.view.*
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.animation.DecelerateInterpolator
import android.view.animation.Interpolator
import android.widget.Scroller
import androidx.core.view.ViewCompat
import com.peterlaurence.mapview.layout.animators.ZoomPanAnimator
Expand All @@ -25,9 +28,11 @@ abstract class GestureLayout @JvmOverloads constructor(context: Context, attrs:
TouchUpGestureDetector.OnTouchUpListener, RotationGestureDetector.OnRotationGestureListener,
GestureController.Controllable {

/* Controllers */
internal val gestureController: GestureController by lazy { GestureController(this) }

private val defaultInterpolator: Interpolator = AccelerateDecelerateInterpolator()
private val fastInterpolator: Interpolator = DecelerateInterpolator(2f)

override fun onMinScaleUpdateRequest() {
gestureController.calculateMinimumScaleToFit(width, height)
}
Expand Down Expand Up @@ -220,20 +225,22 @@ abstract class GestureLayout @JvmOverloads constructor(context: Context, attrs:
*
* @param x Horizontal destination point.
* @param y Vertical destination point.
* @param interpolator The [Interpolator] the animation should use.
*/
fun slideTo(x: Int, y: Int) {
animator.animatePan(x, y)
fun slideTo(x: Int, y: Int, interpolator: Interpolator = defaultInterpolator) {
animator.animatePan(x, y, interpolator)
}

/**
* Scrolls and centers the [GestureLayout] to the x and y values provided using scrolling animation.
*
* @param x Horizontal destination point.
* @param y Vertical destination point.
* @param interpolator The [Interpolator] the animation should use.
*/
@Suppress("unused")
fun slideToAndCenter(x: Int, y: Int) {
slideTo(x - halfWidth, y - halfHeight)
fun slideToAndCenter(x: Int, y: Int, interpolator: Interpolator = defaultInterpolator) {
slideTo(x - halfWidth, y - halfHeight, interpolator)
}

/**
Expand All @@ -243,18 +250,21 @@ abstract class GestureLayout @JvmOverloads constructor(context: Context, attrs:
* @param x Horizontal destination point.
* @param y Vertical destination point.
* @param scale The final scale value the layout should animate to.
* @param interpolator The [Interpolator] the animation should use.
*/
fun slideToAndCenterWithScale(x: Int, y: Int, scale: Float) {
animator.animateZoomPan(x - halfWidth, y - halfHeight, scale)
fun slideToAndCenterWithScale(x: Int, y: Int, scale: Float, interpolator: Interpolator = defaultInterpolator) {
animator.animateZoomPan(x - halfWidth, y - halfHeight, scale, interpolator)
}

/**
* Scales the [GestureLayout] with animated progress, without maintaining scroll position.
*
* @param destination The final scale value the layout should animate to.
* @param interpolator The [Interpolator] the animation should use.
*/
fun smoothScaleTo(destination: Float) {
animator.animateZoom(destination)
@Suppress("unused")
fun smoothScaleTo(destination: Float, interpolator: Interpolator = defaultInterpolator) {
animator.animateZoom(destination, interpolator)
}

/**
Expand All @@ -264,22 +274,25 @@ abstract class GestureLayout @JvmOverloads constructor(context: Context, attrs:
* @param focusX The horizontal focal point to maintain, relative to the screen (as supplied by MotionEvent.getX).
* @param focusY The vertical focal point to maintain, relative to the screen (as supplied by MotionEvent.getY).
* @param scale The final scale value the layout should animate to.
* @param interpolator The [Interpolator] the animation should use.
*/
fun smoothScaleFromFocalPoint(focusX: Int, focusY: Int, scale: Float) {
fun smoothScaleFromFocalPoint(focusX: Int, focusY: Int, scale: Float, interpolator: Interpolator = defaultInterpolator) {
val (x, y, scaleCst) = gestureController.getOffsetDestination(focusX, focusY, scale)
if (scaleCst == gestureController.scale) {
return
}
animator.animateZoomPan(x, y, scaleCst)
animator.animateZoomPan(x, y, scaleCst, interpolator)
}

/**
* Animate the scale of the [GestureLayout] while maintaining the current center point.
*
* @param scale The final scale value the layout should animate to.
* @param interpolator The [Interpolator] the animation should use.
*/
fun smoothScaleFromCenter(scale: Float) {
smoothScaleFromFocalPoint(halfWidth, halfHeight, scale)
@Suppress("unused")
fun smoothScaleFromCenter(scale: Float, interpolator: Interpolator = defaultInterpolator) {
smoothScaleFromFocalPoint(halfWidth, halfHeight, scale, interpolator)
}

override fun constrainScrollToLimits() {
Expand Down Expand Up @@ -404,14 +417,14 @@ abstract class GestureLayout @JvmOverloads constructor(context: Context, attrs:
gestureController.scale)

if (gestureController.angle == 0f) {
smoothScaleFromFocalPoint(event.x.toInt(), event.y.toInt(), scaleCst)
smoothScaleFromFocalPoint(event.x.toInt(), event.y.toInt(), scaleCst, fastInterpolator)
} else {
val angleRad = -gestureController.angle.toRad()
val eventRx = (height / 2 * sin(angleRad) + width / 2 * (1 - cos(angleRad)) +
event.x * cos(angleRad) - event.y * sin(angleRad)).toInt()
val eventRy = (height / 2 * (1 - cos(angleRad)) - width / 2 * sin(angleRad) +
event.x * sin(angleRad) + event.y * cos(angleRad)).toInt()
smoothScaleFromFocalPoint(eventRx, eventRy, scaleCst)
smoothScaleFromFocalPoint(eventRx, eventRy, scaleCst, fastInterpolator)
}

return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.peterlaurence.mapview.layout.animators

import android.animation.Animator
import android.animation.ValueAnimator
import android.view.animation.AccelerateInterpolator
import android.view.animation.Interpolator

class ZoomPanAnimator(private val listener: OnZoomPanAnimationListener) : ValueAnimator(),
ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {
Expand All @@ -16,7 +16,6 @@ class ZoomPanAnimator(private val listener: OnZoomPanAnimationListener) : ValueA
addUpdateListener(this)
addListener(this)
setFloatValues(0f, 1f)
interpolator = AccelerateInterpolator()
}

private fun setupPanAnimation(x: Int, y: Int): Boolean {
Expand All @@ -33,24 +32,27 @@ class ZoomPanAnimator(private val listener: OnZoomPanAnimationListener) : ValueA
return startState.scale != endState.scale
}

fun animateZoomPan(x: Int, y: Int, scale: Float) {
fun animateZoomPan(x: Int, y: Int, scale: Float, interpolator: Interpolator) {
hasPendingZoomUpdates = setupZoomAnimation(scale)
hasPendingPanUpdates = setupPanAnimation(x, y)
if (hasPendingPanUpdates || hasPendingZoomUpdates) {
this.interpolator = interpolator
start()
}
}

fun animateZoom(scale: Float) {
fun animateZoom(scale: Float, interpolator: Interpolator) {
hasPendingZoomUpdates = setupZoomAnimation(scale)
if (hasPendingZoomUpdates) {
this.interpolator = interpolator
start()
}
}

fun animatePan(x: Int, y: Int) {
fun animatePan(x: Int, y: Int, interpolator: Interpolator) {
hasPendingPanUpdates = setupPanAnimation(x, y)
if (hasPendingPanUpdates) {
this.interpolator = interpolator
start()
}
}
Expand Down

0 comments on commit 078ef17

Please sign in to comment.