Anonymous
Увеличить изображение за пределами Jetpack Compose HorizontalPager
Сообщение
Anonymous » 04 июл 2024, 01:20
Я пытаюсь реализовать масштабирование изображения с помощью PointerEvent (2 пальца), и оно работает отлично (уменьшение границ столбцов, что составляет 0,4% от высоты экрана) при переносе в столбец но он не работает должным образом, если он заключен в HorizontalPager.
Код со снимком экрана для реализации Column:
Код: Выделить всё
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ProductImageDialog(
properties: DialogProperties = DialogProperties(usePlatformDefaultWidth = false),
onDismissRequest: () -> Unit
) {
var scale by remember { mutableFloatStateOf(1f) }
var offset by remember { mutableStateOf(Offset.Zero) }
val coroutineScope = rememberCoroutineScope()
var userScrollEnabled by remember { mutableStateOf(true) }
val pagerState = rememberPagerState { 2 }
Dialog(
properties = properties,
onDismissRequest = onDismissRequest
) {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.Green),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.End
) {
IconButton(onClick = onDismissRequest) {
Icon(
imageVector = Icons.Default.Close,
tint = Color.White,
contentDescription = null
)
}
Spacer(modifier = Modifier.height(8.dp))
Column(
modifier = Modifier
.background(color = Color.White)
.fillMaxWidth()
.fillMaxHeight(0.4f),
) {
// items(2) { page ->
Image(
painter = painterResource(id = R.drawable.image_1),
contentDescription = null,
modifier = Modifier
.fillMaxSize()
.pointerInput(Unit) {
coroutineScope
.launch {
awaitPointerEventScope {
while (true) {
val event = awaitPointerEvent()
when (event.changes.size) {
2 -> {
userScrollEnabled = false
val change1 = event.changes[0]
val change2 = event.changes[1]
val distanceCurrent = calculateDistance(
change1.position,
change2.position
)
val distancePrevious = calculateDistance(
change1.previousPosition,
change2.previousPosition
)
scale *= distanceCurrent / distancePrevious
offset += change1.positionChange()
Log.i(
"TAGTTTTTT",
"distanceCurrent: $distanceCurrent\ndistancePrevious: $distancePrevious\nscale: $scale\noffset: $offset"
)
}
else -> {
userScrollEnabled = true
scale = 1f
offset = Offset.Zero
}
}
}
}
}
}
.graphicsLayer(
scaleX = scale,
scaleY = scale,
translationX = offset.x,
translationY = offset.y
),
contentScale = ContentScale.Inside
)
// }
}
}
}
}
private fun calculateDistance(point1: Offset, point2: Offset): Float {
val dx = point1.x - point2.x
val dy = point1.y - point2.y
return sqrt(dx * dx + dy * dy)
}
Вот код, использующий Горизонтальный пейджер:
Код: Выделить всё
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ProductImageDialog(
properties: DialogProperties = DialogProperties(usePlatformDefaultWidth = false),
onDismissRequest: () -> Unit
) {
var scale by remember { mutableFloatStateOf(1f) }
var offset by remember { mutableStateOf(Offset.Zero) }
val coroutineScope = rememberCoroutineScope()
var userScrollEnabled by remember { mutableStateOf(true) }
val pagerState = rememberPagerState { 2 }
Dialog(
properties = properties,
onDismissRequest = onDismissRequest
) {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.Green),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.End
) {
IconButton(onClick = onDismissRequest) {
Icon(
imageVector = Icons.Default.Close,
tint = Color.White,
contentDescription = null
)
}
Spacer(modifier = Modifier.height(8.dp))
HorizontalPager(
modifier = Modifier
.background(color = Color.White)
.fillMaxWidth()
.fillMaxHeight(0.4f),
state = pagerState,
userScrollEnabled = userScrollEnabled,
) { page ->
Image(
painter = if (page == 0) painterResource(id = R.drawable.image_1) else painterResource(id = R.drawable.image_2),
contentDescription = null,
modifier = Modifier
.fillMaxSize()
.pointerInput(Unit) {
coroutineScope
.launch {
awaitPointerEventScope {
while (true) {
val event = awaitPointerEvent()
when (event.changes.size) {
2 -> {
userScrollEnabled = false
val change1 = event.changes[0]
val change2 = event.changes[1]
val distanceCurrent = calculateDistance(
change1.position,
change2.position
)
val distancePrevious = calculateDistance(
change1.previousPosition,
change2.previousPosition
)
scale *= distanceCurrent / distancePrevious
offset += change1.positionChange()
Log.i(
"TAGTTTTTT",
"distanceCurrent: $distanceCurrent\ndistancePrevious: $distancePrevious\nscale: $scale\noffset: $offset"
)
}
else -> {
userScrollEnabled = true
scale = 1f
offset = Offset.Zero
}
}
}
}
}
}
.graphicsLayer(
scaleX = scale,
scaleY = scale,
translationX = offset.x,
translationY = offset.y
),
contentScale = ContentScale.Inside
)
}
}
}
}
Подробнее здесь:
https://stackoverflow.com/questions/787 ... ontalpager
1720045252
Anonymous
Я пытаюсь реализовать масштабирование изображения с помощью PointerEvent (2 пальца), и оно работает отлично (уменьшение границ столбцов, что составляет 0,4% от высоты экрана) при переносе в столбец но он не работает должным образом, если он заключен в HorizontalPager. [img]https://i.sstatic.net/fzDP9Bl6.jpg[/img] Код со снимком экрана для реализации Column: [code]@OptIn(ExperimentalFoundationApi::class) @Composable fun ProductImageDialog( properties: DialogProperties = DialogProperties(usePlatformDefaultWidth = false), onDismissRequest: () -> Unit ) { var scale by remember { mutableFloatStateOf(1f) } var offset by remember { mutableStateOf(Offset.Zero) } val coroutineScope = rememberCoroutineScope() var userScrollEnabled by remember { mutableStateOf(true) } val pagerState = rememberPagerState { 2 } Dialog( properties = properties, onDismissRequest = onDismissRequest ) { Column( modifier = Modifier .fillMaxSize() .background(Color.Green), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.End ) { IconButton(onClick = onDismissRequest) { Icon( imageVector = Icons.Default.Close, tint = Color.White, contentDescription = null ) } Spacer(modifier = Modifier.height(8.dp)) Column( modifier = Modifier .background(color = Color.White) .fillMaxWidth() .fillMaxHeight(0.4f), ) { // items(2) { page -> Image( painter = painterResource(id = R.drawable.image_1), contentDescription = null, modifier = Modifier .fillMaxSize() .pointerInput(Unit) { coroutineScope .launch { awaitPointerEventScope { while (true) { val event = awaitPointerEvent() when (event.changes.size) { 2 -> { userScrollEnabled = false val change1 = event.changes[0] val change2 = event.changes[1] val distanceCurrent = calculateDistance( change1.position, change2.position ) val distancePrevious = calculateDistance( change1.previousPosition, change2.previousPosition ) scale *= distanceCurrent / distancePrevious offset += change1.positionChange() Log.i( "TAGTTTTTT", "distanceCurrent: $distanceCurrent\ndistancePrevious: $distancePrevious\nscale: $scale\noffset: $offset" ) } else -> { userScrollEnabled = true scale = 1f offset = Offset.Zero } } } } } } .graphicsLayer( scaleX = scale, scaleY = scale, translationX = offset.x, translationY = offset.y ), contentScale = ContentScale.Inside ) // } } } } } private fun calculateDistance(point1: Offset, point2: Offset): Float { val dx = point1.x - point2.x val dy = point1.y - point2.y return sqrt(dx * dx + dy * dy) } [/code] [img]https://i.sstatic.net/GPD3WufQ.jpg[/img] Вот код, использующий Горизонтальный пейджер: [code]@OptIn(ExperimentalFoundationApi::class) @Composable fun ProductImageDialog( properties: DialogProperties = DialogProperties(usePlatformDefaultWidth = false), onDismissRequest: () -> Unit ) { var scale by remember { mutableFloatStateOf(1f) } var offset by remember { mutableStateOf(Offset.Zero) } val coroutineScope = rememberCoroutineScope() var userScrollEnabled by remember { mutableStateOf(true) } val pagerState = rememberPagerState { 2 } Dialog( properties = properties, onDismissRequest = onDismissRequest ) { Column( modifier = Modifier .fillMaxSize() .background(Color.Green), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.End ) { IconButton(onClick = onDismissRequest) { Icon( imageVector = Icons.Default.Close, tint = Color.White, contentDescription = null ) } Spacer(modifier = Modifier.height(8.dp)) HorizontalPager( modifier = Modifier .background(color = Color.White) .fillMaxWidth() .fillMaxHeight(0.4f), state = pagerState, userScrollEnabled = userScrollEnabled, ) { page -> Image( painter = if (page == 0) painterResource(id = R.drawable.image_1) else painterResource(id = R.drawable.image_2), contentDescription = null, modifier = Modifier .fillMaxSize() .pointerInput(Unit) { coroutineScope .launch { awaitPointerEventScope { while (true) { val event = awaitPointerEvent() when (event.changes.size) { 2 -> { userScrollEnabled = false val change1 = event.changes[0] val change2 = event.changes[1] val distanceCurrent = calculateDistance( change1.position, change2.position ) val distancePrevious = calculateDistance( change1.previousPosition, change2.previousPosition ) scale *= distanceCurrent / distancePrevious offset += change1.positionChange() Log.i( "TAGTTTTTT", "distanceCurrent: $distanceCurrent\ndistancePrevious: $distancePrevious\nscale: $scale\noffset: $offset" ) } else -> { userScrollEnabled = true scale = 1f offset = Offset.Zero } } } } } } .graphicsLayer( scaleX = scale, scaleY = scale, translationX = offset.x, translationY = offset.y ), contentScale = ContentScale.Inside ) } } } } [/code] [img]https://i.sstatic.net/e8ThWS8v.jpg[/img] Подробнее здесь: [url]https://stackoverflow.com/questions/78704381/zoom-image-outside-bounders-of-jetpackcompose-horizontalpager[/url]