From 783c1d14073af8cbfd8e055680fcc47f91cb2939 Mon Sep 17 00:00:00 2001 From: Masashi Katsumata Date: Thu, 22 Oct 2026 18:53:56 -0700 Subject: [PATCH] Pass labelPosition through the React Native bridge --- .../react/marker/NativeMarkerCodec.kt | 5 +++++ ios/NativeMapCodec.swift | 6 +++++- src/info/InfoBubbleLayer.native.tsx | 6 ++++-- src/marker/ReactNativeImageIcon.ts | 15 +++++++++++++-- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/android/src/main/java/com/mapconductor/react/marker/NativeMarkerCodec.kt b/android/src/main/java/com/mapconductor/react/marker/NativeMarkerCodec.kt index d942b8d..957e12b 100644 --- a/android/src/main/java/com/mapconductor/react/marker/NativeMarkerCodec.kt +++ b/android/src/main/java/com/mapconductor/react/marker/NativeMarkerCodec.kt @@ -12,6 +12,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.facebook.react.bridge.ReadableMap import com.mapconductor.core.features.GeoPoint +import com.mapconductor.core.marker.AbstractDefaultIcon import com.mapconductor.core.marker.ColorDefaultIcon import com.mapconductor.core.marker.DrawableDefaultIcon import com.mapconductor.core.marker.ImageIcon @@ -207,6 +208,7 @@ private data class NativeMarkerIcon( val labelTextColor: Color?, val labelTextSize: Float, val labelStrokeColor: Color, + val labelPosition: String, ) { fun toMarkerIcon(context: Context): MarkerIconInterface? { iconCache[this]?.let { return it } @@ -221,6 +223,7 @@ private data class NativeMarkerIcon( labelTextColor = labelTextColor, labelTextSize = labelTextSize.sp, labelStrokeColor = labelStrokeColor, + labelPosition = labelPosition, infoAnchor = infoAnchor, iconSize = iconSize.dp, debug = debug, @@ -237,6 +240,7 @@ private data class NativeMarkerIcon( labelTextColor = labelTextColor, labelTextSize = labelTextSize.sp, labelStrokeColor = labelStrokeColor, + labelPosition = labelPosition, infoAnchor = infoAnchor, iconSize = iconSize.dp, debug = debug, @@ -283,6 +287,7 @@ private data class NativeMarkerIcon( parseColor(map.string("labelTextColor"), Color.Black), labelTextSize = (map.number("labelTextSize") ?: 18.0).toFloat(), labelStrokeColor = parseColor(map.string("labelStrokeColor"), Color.White), + labelPosition = map.string("labelPosition") ?: AbstractDefaultIcon.DEFAULT_LABEL_POSITION, ) } } diff --git a/ios/NativeMapCodec.swift b/ios/NativeMapCodec.swift index 53c1736..5b2a8a2 100644 --- a/ios/NativeMapCodec.swift +++ b/ios/NativeMapCodec.swift @@ -187,6 +187,7 @@ public struct NativeMarkerIconPayload { public let labelTextColor: UIColor? public let labelTextSize: CGFloat public let labelStrokeColor: UIColor + public let labelPosition: String public static func decode(_ value: Any?) -> NativeMarkerIconPayload? { guard let map = mcMap(value), let type = mcString(map["type"]), @@ -207,7 +208,8 @@ public struct NativeMarkerIconPayload { label: mcString(map["label"]), labelTextColor: mcColor(css: map["labelTextColor"], default: .black), labelTextSize: CGFloat(mcDouble(map["labelTextSize"], default: 18.0)), - labelStrokeColor: mcColor(css: map["labelStrokeColor"], default: .white) ?? .white + labelStrokeColor: mcColor(css: map["labelStrokeColor"], default: .white) ?? .white, + labelPosition: mcString(map["labelPosition"]) ?? DefaultMarkerIcon.defaultLabelPosition ) } @@ -222,6 +224,7 @@ public struct NativeMarkerIconPayload { labelTextColor: labelTextColor, labelTextSize: labelTextSize, labelStrokeColor: labelStrokeColor, + labelPosition: labelPosition, infoAnchor: infoAnchor, iconSize: iconSize, debug: debug @@ -238,6 +241,7 @@ public struct NativeMarkerIconPayload { labelTextColor: labelTextColor, labelTextSize: labelTextSize, labelStrokeColor: labelStrokeColor, + labelPosition: labelPosition, infoAnchor: infoAnchor, iconSize: iconSize, debug: debug diff --git a/src/info/InfoBubbleLayer.native.tsx b/src/info/InfoBubbleLayer.native.tsx index 1f79b44..19297da 100644 --- a/src/info/InfoBubbleLayer.native.tsx +++ b/src/info/InfoBubbleLayer.native.tsx @@ -1,6 +1,7 @@ import { useEffect, useMemo, useState } from 'react'; import { StyleSheet, View } from 'react-native'; import type { Offset } from '@mapconductor/js-sdk-core'; +import { markerIconExtentPx } from '@mapconductor/js-sdk-core'; import type { MapViewScope } from '../MapViewScope.native'; import type { InfoBubbleEntry } from './InfoBubbleEntry'; import { InfoBubbleOverlay } from './InfoBubbleOverlay.native'; @@ -57,7 +58,8 @@ export function InfoBubbleLayer({ const markerId = entry.markerId ?? entry.id; const offset = infoBubbleScreenPositions.get(entry.id) ?? markerScreenPositions.get(markerId); if (!offset) return null; - const iconSizeValue = entry.icon ? entry.icon.iconSize * entry.icon.scale : 0; + // anchor / infoAnchor はアイコンの実寸に対する割合(web と同じ。InfoBubbleOverlay を参照)。 + const iconSizeValue = markerIconExtentPx(entry.icon); const iconOffset = entry.icon?.anchor ?? { x: 0.5, y: 0.5 }; const infoAnchorOffset = entry.icon?.infoAnchor ?? { x: 0.5, y: 0.5 }; @@ -65,7 +67,7 @@ export function InfoBubbleLayer({