Reputation: 64
I have been trying to rotate an image using a single finger without success. So i wanted to know if anyone of you have succeeded doing this. this is a part of my code.
DrawButton(
modifier = Modifier
.offset(0.dp, (height - 17.5).dp)
.pointerInput(Unit) {
detectDragGestures { change, _ ->
boxCenter = Point(
box.startX + box.width / 2,
box.startY + box.height / 2
)
val anglePoint=getAnglePoint(boxCenter,
Point(box.startX,box.startY+box.height),angle
)
val rawX = change.position.x +anglePoint.x
val rawY = change.position.y + anglePoint.y
lastX = change.previousPosition.x + anglePoint.x
lastY = change.previousPosition.y + anglePoint.y
if (lastX != -1f) {
// if (abs(rawX - lastX) < 5 && abs(rawY - lastY) < 5) {
// Log.e("detectDragGestures","detectDragGestures")
//
// return@detectDragGestures
// }
}
pushPoint = getPushPoint(box, change.previousPosition)
val O: Point = boxCenter
val A: Point = pushPoint
val B = getPushPoint(box, change.position)
val dOA = getDistance(O, A)
val dOB = getDistance(O, B)
val fz = (A.x - O.x) * (B.x - O.x) + (A.y - O.y) * (B.y - O.y)
val fm = dOA * dOB
var comAngle =
180 * acos((fz / fm).toDouble()) / PI
if (java.lang.Double.isNaN(comAngle)) {
Log.e("isNaN", "isNaN")
comAngle =
if (lastComAngle < 90 || lastComAngle > 270) 0.toDouble() else 180.toDouble()
// return@detectDragGestures
} else if ((B.y - O.y) * (A.x - O.x) < (A.y - O.y) * (B.x - O.x)) {
comAngle = 360 - comAngle
}
lastComAngle = comAngle.toFloat()
val targetAngle: Float = (angle + comAngle).toFloat()
Log.e("targetAngle","$targetAngle")
Log.e("angle","$angle")
angle = targetAngle % 360
}
},
R.drawable.ic_rotate
)
I have tried to convert this solution to compose without success: https://github.com/ryanch741/android-view-rotate-zoom-single-finger/tree/master/src/com/example/testimg. Thanks previously for your help
Upvotes: 4
Views: 748
Reputation: 23954
I found a solution basically converting this answer to Compose.
@ExperimentalComposeUiApi
@Composable
fun OneFingerImageRotation() {
var viewRotation = remember { 0.0 }
var fingerRotation = remember { 0.0 }
var rotation by remember {
mutableStateOf(0.0)
}
val density = LocalDensity.current
BoxWithConstraints {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Gray)
.pointerInteropFilter { event ->
val x: Float = event.x
val y: Float = event.y
val xc: Float = with(density) { maxWidth.toPx() } / 2f
val yc: Float = with(density) { maxHeight.toPx() } / 2f
when (event.action) {
MotionEvent.ACTION_DOWN -> {
viewRotation = rotation
fingerRotation = Math.toDegrees(atan2((x - xc).toDouble(), (yc - y).toDouble()))
}
MotionEvent.ACTION_MOVE -> {
val newFingerRotation =
Math.toDegrees(atan2((x - xc).toDouble(), (yc - y).toDouble()))
rotation = (viewRotation + newFingerRotation - fingerRotation)
}
MotionEvent.ACTION_UP -> {
fingerRotation = 0.0
}
}
true
}
) {
Image(
modifier = Modifier
.align(Alignment.Center)
.graphicsLayer(
rotationZ = rotation.toFloat()
),
contentDescription = null,
painter = painterResource(R.drawable.pandora)
)
}
}
}
Here is the result:
Upvotes: 1