Add transition when map tile range changes

This commit is contained in:
MM20 2024-06-16 00:27:57 +02:00
parent 964687ada0
commit 4065b75bdc
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389

View File

@ -4,9 +4,17 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.core.animateOffsetAsState import androidx.compose.animation.core.animateOffsetAsState
import androidx.compose.animation.core.animateValueAsState import androidx.compose.animation.core.animateValueAsState
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.animation.slideIn
import androidx.compose.animation.slideOut
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
@ -102,11 +110,10 @@ fun MapTiles(
val userLocation = userLocation() val userLocation = userLocation()
val (start, stop, zoom) = remember(location, userLocation) { val tileRange = remember(location, userLocation) {
getTileRange(location, userLocation, tiles, maxZoomLevel) getTileRange(location, userLocation, tiles, maxZoomLevel)
} }
val sideLength = stop.x - start.x + 1
val colorMatrix = remember(applyTheming, darkMode, tintColor) { val colorMatrix = remember(applyTheming, darkMode, tintColor) {
// darkreader css for openstreetmap tiles // darkreader css for openstreetmap tiles
@ -128,6 +135,38 @@ fun MapTiles(
modifier = modifier, modifier = modifier,
contentAlignment = Alignment.Center, contentAlignment = Alignment.Center,
) { ) {
AnimatedContent(
tileRange,
transitionSpec = {
if (targetState.zoomLevel == initialState.zoomLevel) {
val initialCenterX = (initialState.stop.x + initialState.start.x) / 2f
val targetCenterX = (targetState.stop.x + targetState.start.x) / 2f
val initialCenterY = (initialState.stop.y + initialState.start.y) / 2f
val targetCenterY = (targetState.stop.y + targetState.start.y) / 2f
val initialDeltaX = targetCenterX - initialCenterX
val targetDeltaX = targetCenterX - initialCenterX
val initialDeltaY = targetCenterY - initialCenterY
val targetDeltaY = targetCenterY - initialCenterY
return@AnimatedContent slideIn {
IntOffset(
(targetDeltaX * (it.width / tiles.width)).toInt(),
(targetDeltaY * (it.height / tiles.height)).toInt()
)
} togetherWith slideOut {
IntOffset(
-(initialDeltaX * (it.width / tiles.width)).toInt(),
-(initialDeltaY * (it.height / tiles.height)).toInt()
)
}
}
val scale = 2f.pow(targetState.zoomLevel - initialState.zoomLevel)
fadeIn() + scaleIn(initialScale = 1f / scale) togetherWith
fadeOut() + scaleOut(targetScale = scale)
}
) { (start, stop, zoom) ->
val sideLength = stop.x - start.x + 1
Column(modifier = Modifier.fillMaxWidth()) { Column(modifier = Modifier.fillMaxWidth()) {
for (y in start.y..stop.y) { for (y in start.y..stop.y) {
Row( Row(
@ -239,6 +278,7 @@ fun MapTiles(
} }
} }
} }
}
/** /**
* Returns the tile coordinates for a given location at a given zoom level (not rounded). * Returns the tile coordinates for a given location at a given zoom level (not rounded).