Skip to content

Commit

Permalink
Add ContinuousAnimator, add couple util methods to Point and DragGest…
Browse files Browse the repository at this point in the history
…ure classes.
  • Loading branch information
zbsz committed Aug 8, 2015
1 parent 2c2a077 commit 979da94
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 10 deletions.
49 changes: 41 additions & 8 deletions src/main/scala/com/geteit/view/TouchReactor.scala
Expand Up @@ -85,7 +85,39 @@ class Point(var x: Float, var y: Float) {
this
}

def dst(x: Float, y: Float) = math.sqrt((x - this.x) * (x - this.x) + (y - this.y) * (y - this.y)).toFloat
def angle = Point.angle(x, y)

def dot(p: Point): Float = dot(p.x, p.y)

def dot(x: Float, y: Float): Float = x * this.x + y * this.y

def len2 = x * x + y * y

def len = math.sqrt(len2)

def dst(x: Float, y: Float) = math.sqrt(dst2(x, y)).toFloat

def dst2(x: Float, y: Float) = (x - this.x) * (x - this.x) + (y - this.y) * (y - this.y)

def rotate(degrees: Float): Point = {
val rad = degrees * 0.017453292F
val cos = math.cos(rad).toFloat
val sin = math.sin(rad).toFloat
val newX = x * cos - y * sin
val newY = x * sin + y * cos
x = newX
y = newY
this
}

override def toString = s"Point($x, $y)"
}

object Point {
def angle(x: Float, y: Float) = {
val a = math.atan2(y, x).toFloat * 57.295776F
if (a < 0) a + 360 else a
}
}

class ClickGesture(context: Context, reactor: TouchReactor, longClickTimeout: FiniteDuration = 500.millis)(implicit eventContext: EventContext) {
Expand Down Expand Up @@ -141,16 +173,16 @@ class ClickGesture(context: Context, reactor: TouchReactor, longClickTimeout: Fi
}

object DragGesture {
val NONE = 0
val HORIZONTAL = 1
val VERTICAL = 2
val BOTH = HORIZONTAL | VERTICAL

private def isHorizontal(dir: Int) = dir == NONE || dir == HORIZONTAL
private def isHorizontal(dir: Int) = (dir & HORIZONTAL) != 0

private def isVertical(dir: Int) = dir == NONE || dir == VERTICAL
private def isVertical(dir: Int) = (dir & VERTICAL) != 0
}

class DragGesture(context: Context, reactor: TouchReactor, direction: Int = DragGesture.NONE)(implicit eventContext: EventContext) {
class DragGesture(context: Context, reactor: TouchReactor, direction: Int = DragGesture.BOTH)(implicit eventContext: EventContext) {

import DragGesture._

Expand All @@ -166,6 +198,8 @@ class DragGesture(context: Context, reactor: TouchReactor, direction: Int = Drag
private val minimumVelocity = configuration.getScaledMinimumFlingVelocity
private val maximumVelocity = configuration.getScaledMaximumFlingVelocity

protected def hit(x: Float, y: Float) = true

reactor.onDown { ev: MotionEvent =>
dragging = false

Expand All @@ -174,19 +208,18 @@ class DragGesture(context: Context, reactor: TouchReactor, direction: Int = Drag
onDragEnd ! dragged
}

if (onDragStart.hasSubscribers || onDrag.hasSubscribers || onFling.hasSubscribers) {
if ((onDragStart.hasSubscribers || onDrag.hasSubscribers || onFling.hasSubscribers) && hit(ev.getX, ev.getY)) {
startPos.set(ev.getX, ev.getY)
var velocityTracker: VelocityTracker = null
var dragObserver: Subscription = null

def shouldStartDrag(x: Float, y: Float) = {
direction match {
case NONE => startPos.dst(ev.getX, ev.getY) > touchSlop
case BOTH => startPos.dst(ev.getX, ev.getY) > touchSlop
case VERTICAL => math.abs(ev.getY - startPos.y) > touchSlop && math.abs((ev.getY - startPos.y) / (ev.getX - startPos.x)) > 2 || math.abs(ev.getY - startPos.y) > 2 * touchSlop
case HORIZONTAL => math.abs(ev.getX - startPos.x) > touchSlop && math.abs((ev.getX - startPos.x) / (ev.getY - startPos.y)) > 2 || math.abs(ev.getX - startPos.x) > 2 * touchSlop
}
}

dragObserver = reactor.onDrag { ev: MotionEvent =>
if (!dragging && shouldStartDrag(ev.getX, ev.getY)) {
onDragStart !(ev.getX, ev.getY)
Expand Down
64 changes: 62 additions & 2 deletions src/main/scala/com/geteit/view/ValueAnimator.scala
Expand Up @@ -3,10 +3,12 @@ package com.geteit.view
import android.content.Context
import android.os.{Looper, SystemClock}
import android.view.View
import android.view.animation.LinearInterpolator
import com.geteit.util.{GtObjHandler, MathUtils}
import com.nineoldandroids.animation.Animator.AnimatorListener
import com.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener
import com.nineoldandroids.animation.{ValueAnimator, AnimatorListenerAdapter, Animator}
import com.geteit.util.Log._

object GtValueAnimator {
}
Expand Down Expand Up @@ -50,14 +52,25 @@ class GtValueAnimator(duration: Long = 300) {
this
}

def startInt(values: Int*) = {
def startInt(start: Int, end: Int) = {
// GtAssert.assertUIThread()

if (values.nonEmpty) anim.setIntValues(values: _*)
anim.setIntValues(start, end)
anim.start()
this
}

def updateInt(start: Int, end: Int) = {
if (anim.isRunning) {
val value = anim.getAnimatedValue.asInstanceOf[Int]
val values = anim.getValues
} else {
anim.setIntValues(start, end)
anim.start()
}
this
}

def end() {
// GtAssert.assertUIThread()

Expand All @@ -72,6 +85,53 @@ class GtValueAnimator(duration: Long = 300) {
def isRunning = anim.isRunning
}

class ContinuousValueAnimator(var start: Long, onUpdate: Long => Unit) extends AnimatorUpdateListener {
private implicit val tag: LogTag = "ContinuousValueAnimator"

lazy val anim = {
val a = new ValueAnimator
a.addUpdateListener(this)
a.setInterpolator(new LinearInterpolator())
a.setFloatValues(0f, 1f)
a
}

var current: Long = start
var target: Long = 0

def cancel() = if (anim.isRunning) anim.cancel()

def set(value: Long) = {
cancel()
current = value
onUpdate(current)
}

def animateTo(target: Long) = {
this.target = target
if (anim.isRunning) {
val duration = anim.getDuration
val shouldContinue = (current > start && target >= current) || (current < start && target <= current)
if (shouldContinue) {
val time = ((current - start).toFloat / (target - start) * duration).toLong
anim.setCurrentPlayTime(time)
} else {
anim.cancel()
start = current
anim.start()
}
} else {
start = current
anim.start()
}
}

override def onAnimationUpdate(animation: ValueAnimator): Unit = {
current = start + ((target - start) * animation.getAnimatedFraction + .5).toLong
onUpdate(current)
}
}

class FadeAnimator(view: View, duration: Long = 300, hiddenVisibility: Int = View.GONE) extends GtValueAnimator(duration) {

private val transform = ViewTransformFactory.createTransform(view)
Expand Down

0 comments on commit 979da94

Please sign in to comment.