Adjust zoom focus point
This commit is contained in:
@@ -30,13 +30,14 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
private val scale
|
||||
get() = matrixValues[Matrix.MSCALE_X]
|
||||
private val transX
|
||||
get() = halfWidth*(scale - 1f) + matrixValues[Matrix.MTRANS_X]
|
||||
get() = halfWidth * (scale - 1f) + matrixValues[Matrix.MTRANS_X]
|
||||
private val transY
|
||||
get() = halfHeight*(scale - 1f) + matrixValues[Matrix.MTRANS_Y]
|
||||
get() = halfHeight * (scale - 1f) + matrixValues[Matrix.MTRANS_Y]
|
||||
private var halfWidth = 0f
|
||||
private var halfHeight = 0f
|
||||
private val translateBounds = RectF()
|
||||
private val targetHitRect = Rect()
|
||||
private var pendingScroll = 0
|
||||
|
||||
init {
|
||||
syncMatrixValues()
|
||||
@@ -53,9 +54,13 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
|
||||
// Offset event to inside the child view
|
||||
if (scale < 1 && !targetHitRect.contains(ev.x.toInt(), ev.y.toInt())) {
|
||||
ev.offsetLocation(halfWidth - ev.x + targetHitRect.width()/3, 0f)
|
||||
ev.offsetLocation(halfWidth - ev.x + targetHitRect.width() / 3, 0f)
|
||||
}
|
||||
|
||||
// Send action cancel to avoid recycler jump when scale end
|
||||
if (scaleDetector.isInProgress) {
|
||||
ev.action = MotionEvent.ACTION_CANCEL
|
||||
}
|
||||
return super.dispatchTouchEvent(ev)
|
||||
}
|
||||
|
||||
@@ -86,6 +91,8 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
|
||||
if (scale < 1) {
|
||||
targetChild.getHitRect(targetHitRect)
|
||||
targetChild.scrollBy(0, pendingScroll)
|
||||
pendingScroll = 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +114,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
else -> 0f
|
||||
}
|
||||
|
||||
pendingScroll = dy.toInt()
|
||||
transformMatrix.postTranslate(dx, dy)
|
||||
syncMatrixValues()
|
||||
}
|
||||
@@ -135,13 +143,15 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
|
||||
override fun onScale(detector: ScaleGestureDetector): Boolean {
|
||||
val newScale = (scale * detector.scaleFactor).coerceIn(MIN_SCALE, MAX_SCALE)
|
||||
scaleChild(newScale, halfWidth, halfHeight)
|
||||
scaleChild(newScale, detector.focusX, detector.focusY)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onScaleBegin(detector: ScaleGestureDetector): Boolean = true
|
||||
|
||||
override fun onScaleEnd(p0: ScaleGestureDetector) = Unit
|
||||
override fun onScaleEnd(p0: ScaleGestureDetector) {
|
||||
pendingScroll = 0
|
||||
}
|
||||
|
||||
|
||||
private inner class GestureListener(): GestureDetector.SimpleOnGestureListener(), Runnable {
|
||||
@@ -153,7 +163,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
override fun onDoubleTap(e: MotionEvent): Boolean {
|
||||
val newScale = if (scale != 1f) 1f else MAX_SCALE
|
||||
val newScale = if (scale != 1f) 1f else MAX_SCALE * 0.8f
|
||||
ObjectAnimator.ofFloat(scale, newScale).run {
|
||||
interpolator = AccelerateDecelerateInterpolator()
|
||||
duration = 300
|
||||
|
||||
Reference in New Issue
Block a user