Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proof of concept: reimplement gestures to enable compose ui blending on web #216

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ val Platform.supportsLayers: Boolean
get() = isAndroid || isIos

val Platform.supportsBlending: Boolean
get() = isAndroid || isIos
get() = isAndroid || isIos || isWeb

val Platform.usesMaplibreNative: Boolean
get() = isAndroid || isIos
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import dev.sargunv.maplibrecompose.core.AndroidMap
import dev.sargunv.maplibrecompose.core.AndroidScaleBar
import dev.sargunv.maplibrecompose.core.MaplibreMap
import org.maplibre.android.MapLibre
import org.maplibre.android.gestures.AndroidGesturesManager
import org.maplibre.android.maps.MapLibreMapOptions
import org.maplibre.android.maps.MapView

Expand Down Expand Up @@ -63,6 +64,12 @@ internal fun AndroidMapView(
mapView ->
currentMapView = mapView
mapView.getMapAsync { map ->
map.setGesturesManager(AndroidGesturesManager(context), false, false)
mapView.isClickable = false
mapView.isLongClickable = false
mapView.isFocusable = false
mapView.setFocusableInTouchMode(false)
mapView.requestDisallowInterceptTouchEvent(false)
currentMap =
AndroidMap(
mapView = mapView,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,15 +212,8 @@ internal class AndroidMap(
override fun setMaximumFps(maximumFps: Int) = mapView.setMaximumFps(maximumFps)

override fun setGestureSettings(value: GestureSettings) {
map.uiSettings.isRotateGesturesEnabled = value.isRotateGesturesEnabled
map.uiSettings.isScrollGesturesEnabled = value.isScrollGesturesEnabled
map.uiSettings.isTiltGesturesEnabled = value.isTiltGesturesEnabled
map.uiSettings.isZoomGesturesEnabled = value.isZoomGesturesEnabled
// on iOS, there is no setting for enabling quick zoom (=double-tap, hold and move up or down)
// and zoom in by a double tap separately, so isZoomGesturesEnabled turns on or off ALL zoom
// gestures
map.uiSettings.isQuickZoomGesturesEnabled = value.isZoomGesturesEnabled
map.uiSettings.isDoubleTapGesturesEnabled = value.isZoomGesturesEnabled
map.uiSettings.setAllGesturesEnabled(false)
map.gesturesManager.detectors.clear()
}

override fun setOrnamentSettings(value: OrnamentSettings) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package dev.sargunv.maplibrecompose.compose

import androidx.compose.foundation.gestures.rememberTransformableState
import androidx.compose.foundation.gestures.transformable
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
Expand All @@ -8,6 +10,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.DpOffset
import co.touchlab.kermit.Logger
import dev.sargunv.maplibrecompose.compose.engine.LayerNode
Expand All @@ -20,6 +23,7 @@ import dev.sargunv.maplibrecompose.core.StandardMaplibreMap
import dev.sargunv.maplibrecompose.core.Style
import dev.sargunv.maplibrecompose.core.util.PlatformUtils
import io.github.dellisd.spatialk.geojson.Position
import kotlin.math.log2
import kotlin.math.roundToInt
import kotlinx.coroutines.launch

Expand Down Expand Up @@ -178,8 +182,26 @@ public fun MaplibreMap(

val scope = rememberCoroutineScope()

val density = LocalDensity.current

val transformableState = rememberTransformableState { zoomChange, offsetChange, rotationChange ->
val center = cameraState.screenLocationFromPosition(cameraState.position.target)
val newCenter =
center - with(density) { DpOffset(offsetChange.x.toDp(), offsetChange.y.toDp()) }
val newTarget = cameraState.positionFromScreenLocation(newCenter)
val newZoom =
(cameraState.position.zoom + log2(zoomChange)).coerceIn(
zoomRange.start.toDouble(),
zoomRange.endInclusive.toDouble(),
)
val newBearing = (cameraState.position.bearing - rotationChange).mod(360.0)
println("newTarget: $newTarget, newZoom: $newZoom, newBearing: $newBearing")
cameraState.position =
cameraState.position.copy(target = newTarget, zoom = newZoom, bearing = newBearing)
}

ComposableMapView(
modifier = modifier.fillMaxSize(),
modifier = modifier.fillMaxSize().transformable(transformableState),
styleUri = styleUri,
update = { map ->
when (map) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,11 @@ internal class WebviewMap(private val bridge: WebviewBridge) : MaplibreMap {
}

override suspend fun asyncSetGestureSettings(value: GestureSettings) {
bridge.callVoid("setTiltGesturesEnabled", value.isTiltGesturesEnabled)
bridge.callVoid("setZoomGesturesEnabled", value.isZoomGesturesEnabled)
bridge.callVoid("setRotateGesturesEnabled", value.isRotateGesturesEnabled)
bridge.callVoid("setScrollGesturesEnabled", value.isScrollGesturesEnabled)
bridge.callVoid("setKeyboardGesturesEnabled", value.isKeyboardGesturesEnabled)
bridge.callVoid("setTiltGesturesEnabled", false)
bridge.callVoid("setZoomGesturesEnabled", false)
bridge.callVoid("setRotateGesturesEnabled", false)
bridge.callVoid("setScrollGesturesEnabled", false)
bridge.callVoid("setKeyboardGesturesEnabled", false)
}

override suspend fun animateCameraPosition(finalPosition: CameraPosition, duration: Duration) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ internal fun IosMapView(
UIKitView(
modifier = modifier.fillMaxSize(),
properties =
UIKitInteropProperties(interactionMode = UIKitInteropInteractionMode.NonCooperative),
UIKitInteropProperties(
interactionMode = UIKitInteropInteractionMode.Cooperative(delayMillis = Int.MAX_VALUE)
),
factory = {
MLNMapView(
frame =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ import cocoapods.MapLibre.MLNOrnamentPositionTopLeft
import cocoapods.MapLibre.MLNOrnamentPositionTopRight
import cocoapods.MapLibre.MLNStyle
import cocoapods.MapLibre.MLNZoomLevelForAltitude
import cocoapods.MapLibre.allowsRotating
import cocoapods.MapLibre.allowsScrolling
import cocoapods.MapLibre.allowsTilting
import cocoapods.MapLibre.allowsZooming
import dev.sargunv.maplibrecompose.core.util.toBoundingBox
import dev.sargunv.maplibrecompose.core.util.toCGPoint
import dev.sargunv.maplibrecompose.core.util.toCGRect
Expand Down Expand Up @@ -294,10 +297,13 @@ internal class IosMap(
}

override fun setGestureSettings(value: GestureSettings) {
mapView.rotateEnabled = value.isRotateGesturesEnabled
mapView.scrollEnabled = value.isScrollGesturesEnabled
mapView.allowsTilting = value.isTiltGesturesEnabled
mapView.zoomEnabled = value.isZoomGesturesEnabled
mapView.rotateEnabled = false
mapView.scrollEnabled = false
mapView.allowsTilting = false
mapView.zoomEnabled = false
mapView.allowsZooming = false
mapView.allowsScrolling = false
mapView.allowsRotating = false
}

private fun calculateMargins(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ internal fun WebMapView(

HtmlElement(
modifier = modifier.onGloballyPositioned { maybeMap?.resize() },
// zIndex = "-1", // TODO figure out pointer interop
zIndex = "-1",
factory = {
document.createElement("div").unsafeCast<HTMLElement>().apply {
style.apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,43 +132,13 @@ internal class JsMap(
}

override fun setGestureSettings(value: GestureSettings) {
if (value.isTiltGesturesEnabled) {
impl.touchPitch.enable()
} else {
impl.touchPitch.disable()
}

if (value.isRotateGesturesEnabled) {
impl.dragRotate.enable()
impl.keyboard.enableRotation()
impl.touchZoomRotate.enableRotation()
} else {
impl.dragRotate.disable()
impl.keyboard.disableRotation()
impl.touchZoomRotate.disableRotation()
}

if (value.isScrollGesturesEnabled) {
impl.dragPan.enable()
} else {
impl.dragPan.disable()
}

if (value.isZoomGesturesEnabled) {
impl.doubleClickZoom.enable()
impl.scrollZoom.enable()
impl.touchZoomRotate.enable()
} else {
impl.doubleClickZoom.disable()
impl.scrollZoom.disable()
impl.touchZoomRotate.disable()
}

if (value.isKeyboardGesturesEnabled) {
impl.keyboard.enable()
} else {
impl.keyboard.disable()
}
impl.touchPitch.disable()
impl.dragRotate.disable()
impl.keyboard.disable()
impl.dragPan.disable()
impl.doubleClickZoom.disable()
impl.scrollZoom.disable()
impl.touchZoomRotate.disable()
}

private var compassPosition: String? = null
Expand Down
Loading