data class DragStatus(
//是否正在拖动
val onDrag: Boolean = false,
//拖动大于一定距离,气泡消失
val onDragComplete: Boolean = false
)
class MainActivity : ComponentActivity() {
companion object {
const val RADIUS = 30f
const val MIN_DRAG_DISTANCE = 110
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var offsetX by remember { mutableStateOf(0f) }
var offsetY by remember { mutableStateOf(0f) }
var controlX by remember { mutableStateOf(0f) }
var controlY by remember { mutableStateOf(0f) }
var sin by remember { mutableStateOf(0f) }
var cos by remember { mutableStateOf(0f) }
var circleStartX by remember { mutableStateOf(0f) }
var circleStartY by remember { mutableStateOf(0f) }
var bubbleEndX by remember { mutableStateOf(0f) }
var bubbleEndY by remember { mutableStateOf(0f) }
var bubbleStartX by remember { mutableStateOf(0f) }
var bubbleStartY by remember { mutableStateOf(0f) }
var circleEndX by remember { mutableStateOf(0f) }
var circleEndY by remember { mutableStateOf(0f) }
var dragStatus by remember {
mutableStateOf(DragStatus())
}
var circleRadius by remember { mutableStateOf(RADIUS) }
val bubbleRadius by remember { mutableStateOf(RADIUS) }
var minDragDistance by remember { mutableStateOf(0f) }
var previousDistance by remember { mutableStateOf(0f) }
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Canvas(modifier = Modifier.offset(), onDraw = {
//消息数量的圆
//什么时候圆显示:1.拖动没超过一定距离
if (!dragStatus.onDragComplete) {
drawCircle(Color.Red, circleRadius)
}
})
val path = Path()
Canvas(
modifier = Modifier
.offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
.pointerInput(Unit) {
detectDragGestures(
onDrag = { change, dragAmount ->
offsetX += dragAmount.x
offsetY += dragAmount.y
minDragDistance = sqrt(
(offsetX
.toDouble()
.pow(2.0) + offsetY
.toDouble()
.pow(2.0)).toFloat()
)
if (minDragDistance > previousDistance) {
circleRadius -= ((minDragDistance - previousDistance) / 5)
} else if (minDragDistance < previousDistance) {
circleRadius += ((previousDistance - minDragDistance) / 5)
}
previousDistance = minDragDistance
dragStatus = dragStatus.copy(onDrag = true)
},
onDragEnd = {
dragStatus = dragStatus.copy(onDrag = false)
if (minDragDistance < MIN_DRAG_DISTANCE) {
offsetX = 0f
offsetY = 0f
} else {
dragStatus = dragStatus.copy(onDragComplete = true)
}
minDragDistance = 0f
circleRadius = RADIUS
}
)
}, onDraw = {
path.reset()
if (dragStatus.onDrag) {
//画可以拖动的圆
drawCircle(Color.Green, bubbleRadius)
//画两个圆之间的连接效果
controlX = (offsetX + 0) / 2
controlY = (offsetY + 0) / 2
sin = offsetY / minDragDistance
cos = offsetX / minDragDistance
circleStartX = circleRadius * sin - 0f
circleStartY = 0f - circleRadius * cos
bubbleEndX = offsetX + bubbleRadius * sin
bubbleEndY = offsetY - bubbleRadius * cos
bubbleStartX = offsetX - bubbleRadius * sin
bubbleStartY = offsetY + bubbleRadius * cos
circleEndX = 0f - circleRadius * sin
circleEndY = 0f + circleRadius * cos
println(
"------------------------------\noffsetX: $offsetX offsetY: $offsetY \n" +
"controlX: $controlX controlY: $controlY\nminDragDistance: $minDragDistance\nsin: $sin cos: $cos\n" +
"circleStartX: $circleStartX circleStartY: $circleStartY\nbubbleEndX: $bubbleEndX bubbleEndY: $bubbleEndY\n" +
"bubbleStartX: $bubbleStartX bubbleStartY: $bubbleStartY\ncircleEndX: $circleEndX circleEndY: $circleEndY\n" + "------------------------------\n"
)
path.moveTo(-circleStartX, -circleStartY)
path.quadraticBezierTo(-controlX, -controlY, -bubbleEndX, -bubbleEndY)
path.lineTo(-bubbleStartX, -bubbleStartY)
path.quadraticBezierTo(-controlX, -controlY, -circleEndX, -circleEndY)
path.close()
drawPath(path, Color.Green)
}
})
}
}
}
}
I used two different colors to distinguish. Now, one canvas has drawn a circle, the other canvas has drawn a circle that can be dragged, and the path connecting two circles. When I drag the green circle, the radius of the red circle gradually decreases. The left two points of the green part should have been on the radius of the small circle. I printed the log and found that the values of (circleStartX, circleStartY) (circleEndX, circleEndY) have indeed changed, But the UI did not change due to the reduction of the radius of the red circle, and it remained in its original position
The above is all the code, and the effect is that when I move the red dot, there is a connection effect between the moving red dot and the origin. The above code can be run directly, please help me find the problem. Thank you. The current effect is problematic, and it took me a long time to find any issues. I am too foolish. The current effect is that when I drag the red dot, I change the values of the start and end points, and the printing did indeed change, but the effect drawn by path did not change. I called path. reset() but it was unsuccessful, and I couldn't find the problem. My ultimate goal is to achieve this effect: similar to a message bubble, when I drag over a certain distance, the bubble will disappear. At present, I have not achieved the remaining results and have encountered difficulties. All the English in the question comes from machine translation. I'm not sure if you can understand my question