Add js support for features

This commit is contained in:
Alexander Nozik 2022-12-27 12:34:24 +03:00
parent 8969b2b094
commit 33cadb1d15
13 changed files with 66 additions and 86 deletions

View File

@ -4,5 +4,6 @@ compose.version=1.2.2
agp.version=4.2.2 agp.version=4.2.2
android.useAndroidX=true android.useAndroidX=true
org.jetbrains.compose.experimental.jscanvas.enabled=true
toolsVersion=0.13.3-kotlin-1.7.20 toolsVersion=0.13.3-kotlin-1.7.20

View File

@ -9,36 +9,35 @@ import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import center.sciprog.maps.coordinates.* import center.sciprog.maps.coordinates.*
import center.sciprog.maps.features.* import center.sciprog.maps.features.*
import center.sciprog.maps.features.Feature.Companion.defaultZoomRange
internal fun FeatureCollection<Gmc>.coordinatesOf(pair: Pair<Number, Number>) = internal fun FeatureBuilder<Gmc>.coordinatesOf(pair: Pair<Number, Number>) =
GeodeticMapCoordinates.ofDegrees(pair.first.toDouble(), pair.second.toDouble()) GeodeticMapCoordinates.ofDegrees(pair.first.toDouble(), pair.second.toDouble())
public typealias MapFeature = Feature<Gmc> public typealias MapFeature = Feature<Gmc>
public fun FeatureCollection<Gmc>.circle( public fun FeatureBuilder<Gmc>.circle(
centerCoordinates: Pair<Number, Number>, centerCoordinates: Pair<Number, Number>,
zoomRange: DoubleRange = defaultZoomRange, zoomRange: DoubleRange = defaultZoomRange,
size: Dp = 5.dp, size: Dp = 5.dp,
color: Color = Color.Red, color: Color = defaultColor,
id: String? = null, id: String? = null,
): FeatureId<CircleFeature<Gmc>> = feature( ): FeatureId<CircleFeature<Gmc>> = feature(
id, CircleFeature(coordinateSpace, coordinatesOf(centerCoordinates), zoomRange, size, color) id, CircleFeature(coordinateSpace, coordinatesOf(centerCoordinates), zoomRange, size, color)
) )
public fun FeatureCollection<Gmc>.rectangle( public fun FeatureBuilder<Gmc>.rectangle(
centerCoordinates: Pair<Number, Number>, centerCoordinates: Pair<Number, Number>,
zoomRange: DoubleRange = defaultZoomRange, zoomRange: DoubleRange = defaultZoomRange,
size: DpSize = DpSize(5.dp, 5.dp), size: DpSize = DpSize(5.dp, 5.dp),
color: Color = Color.Red, color: Color = defaultColor,
id: String? = null, id: String? = null,
): FeatureId<RectangleFeature<Gmc>> = feature( ): FeatureId<RectangleFeature<Gmc>> = feature(
id, RectangleFeature(coordinateSpace, coordinatesOf(centerCoordinates), zoomRange, size, color) id, RectangleFeature(coordinateSpace, coordinatesOf(centerCoordinates), zoomRange, size, color)
) )
public fun FeatureCollection<Gmc>.draw( public fun FeatureBuilder<Gmc>.draw(
position: Pair<Number, Number>, position: Pair<Number, Number>,
zoomRange: DoubleRange = defaultZoomRange, zoomRange: DoubleRange = defaultZoomRange,
id: String? = null, id: String? = null,
@ -49,10 +48,10 @@ public fun FeatureCollection<Gmc>.draw(
) )
public fun FeatureCollection<Gmc>.line( public fun FeatureBuilder<Gmc>.line(
curve: GmcCurve, curve: GmcCurve,
zoomRange: DoubleRange = defaultZoomRange, zoomRange: DoubleRange = defaultZoomRange,
color: Color = Color.Red, color: Color = defaultColor,
id: String? = null, id: String? = null,
): FeatureId<LineFeature<Gmc>> = feature( ): FeatureId<LineFeature<Gmc>> = feature(
id, id,
@ -60,11 +59,11 @@ public fun FeatureCollection<Gmc>.line(
) )
public fun FeatureCollection<Gmc>.line( public fun FeatureBuilder<Gmc>.line(
aCoordinates: Pair<Double, Double>, aCoordinates: Pair<Double, Double>,
bCoordinates: Pair<Double, Double>, bCoordinates: Pair<Double, Double>,
zoomRange: DoubleRange = defaultZoomRange, zoomRange: DoubleRange = defaultZoomRange,
color: Color = Color.Red, color: Color = defaultColor,
id: String? = null, id: String? = null,
): FeatureId<LineFeature<Gmc>> = feature( ): FeatureId<LineFeature<Gmc>> = feature(
id, id,
@ -72,19 +71,19 @@ public fun FeatureCollection<Gmc>.line(
) )
public fun FeatureCollection<Gmc>.arc( public fun FeatureBuilder<Gmc>.arc(
center: Pair<Double, Double>, center: Pair<Double, Double>,
radius: Distance, radius: Distance,
startAngle: Angle, startAngle: Angle,
arcLength: Angle, arcLength: Angle,
zoomRange: DoubleRange = defaultZoomRange, zoomRange: DoubleRange = defaultZoomRange,
color: Color = Color.Red, color: Color = defaultColor,
id: String? = null, id: String? = null,
): FeatureId<ArcFeature<Gmc>> = feature( ): FeatureId<ArcFeature<Gmc>> = feature(
id, id,
ArcFeature( ArcFeature(
coordinateSpace, coordinateSpace,
oval = Rectangle(coordinatesOf(center), radius, radius), oval = coordinateSpace.Rectangle(coordinatesOf(center), radius, radius),
startAngle = startAngle.radians.toFloat(), startAngle = startAngle.radians.toFloat(),
arcLength = arcLength.radians.toFloat(), arcLength = arcLength.radians.toFloat(),
zoomRange = zoomRange, zoomRange = zoomRange,
@ -92,17 +91,17 @@ public fun FeatureCollection<Gmc>.arc(
) )
) )
public fun FeatureCollection<Gmc>.points( public fun FeatureBuilder<Gmc>.points(
points: List<Pair<Double, Double>>, points: List<Pair<Double, Double>>,
zoomRange: DoubleRange = defaultZoomRange, zoomRange: DoubleRange = defaultZoomRange,
stroke: Float = 2f, stroke: Float = 2f,
color: Color = Color.Red, color: Color = defaultColor,
pointMode: PointMode = PointMode.Points, pointMode: PointMode = PointMode.Points,
id: String? = null, id: String? = null,
): FeatureId<PointsFeature<Gmc>> = ): FeatureId<PointsFeature<Gmc>> =
feature(id, PointsFeature(coordinateSpace, points.map(::coordinatesOf), zoomRange, stroke, color, pointMode)) feature(id, PointsFeature(coordinateSpace, points.map(::coordinatesOf), zoomRange, stroke, color, pointMode))
public fun FeatureCollection<Gmc>.image( public fun FeatureBuilder<Gmc>.image(
position: Pair<Double, Double>, position: Pair<Double, Double>,
image: ImageVector, image: ImageVector,
size: DpSize = DpSize(20.dp, 20.dp), size: DpSize = DpSize(20.dp, 20.dp),
@ -119,11 +118,11 @@ public fun FeatureCollection<Gmc>.image(
) )
) )
public fun FeatureCollection<Gmc>.text( public fun FeatureBuilder<Gmc>.text(
position: Pair<Double, Double>, position: Pair<Double, Double>,
text: String, text: String,
zoomRange: DoubleRange = defaultZoomRange, zoomRange: DoubleRange = defaultZoomRange,
color: Color = Color.Red, color: Color = defaultColor,
font: FeatureFont.() -> Unit = { size = 16f }, font: FeatureFont.() -> Unit = { size = 16f },
id: String? = null, id: String? = null,
): FeatureId<TextFeature<Gmc>> = feature( ): FeatureId<TextFeature<Gmc>> = feature(

View File

@ -98,7 +98,7 @@ public actual fun MapView(
} }
val painterCache: Map<PainterFeature<Gmc>, Painter> = key(featuresState) { val painterCache: Map<PainterFeature<Gmc>, Painter> = key(featuresState) {
featuresState.features.values.filterIsInstance<PainterFeature<Gmc>>().associateWith { it.painter() } featuresState.features.values.filterIsInstance<PainterFeature<Gmc>>().associateWith { it.getPainter() }
} }
Canvas(modifier = modifier.mapControls(state).fillMaxSize()) { Canvas(modifier = modifier.mapControls(state).fillMaxSize()) {

View File

@ -6,6 +6,7 @@ package center.sciprog.maps.coordinates
public class GeodeticMapCoordinates( public class GeodeticMapCoordinates(
public val latitude: Angle, public val latitude: Angle,
longitude: Angle, longitude: Angle,
public val elevation: Distance = 0.kilometers
) { ) {
public val longitude: Angle = longitude.normalized(Angle.zero) public val longitude: Angle = longitude.normalized(Angle.zero)

View File

@ -1,39 +1,15 @@
plugins { plugins {
kotlin("multiplatform") id("space.kscience.gradle.mpp")
id("org.jetbrains.compose") id("org.jetbrains.compose")
`maven-publish` `maven-publish`
} }
kotlin { kotlin {
explicitApi = org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode.Warning
jvm {
compilations.all {
kotlinOptions.jvmTarget = space.kscience.gradle.KScienceVersions.JVM_TARGET.toString()
}
}
sourceSets { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
api(compose.foundation) api(compose.foundation)
} }
} }
val jvmMain by getting{
}
val jvmTest by getting {
dependencies {
implementation(kotlin("test-junit5"))
implementation("org.junit.jupiter:junit-jupiter:5.8.2")
} }
} }
}
}
java {
targetCompatibility = space.kscience.gradle.KScienceVersions.JVM_TARGET
}
tasks.withType<Test> {
useJUnitPlatform()
}

View File

@ -30,7 +30,7 @@ public class AttributeMap {
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (javaClass != other?.javaClass) return false if (other == null || this::class != other::class) return false
other as AttributeMap other as AttributeMap

View File

@ -13,7 +13,6 @@ import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import center.sciprog.maps.features.Feature.Companion.defaultZoomRange
public typealias DoubleRange = FloatRange public typealias DoubleRange = FloatRange
public typealias FloatRange = ClosedFloatingPointRange<Float> public typealias FloatRange = ClosedFloatingPointRange<Float>
@ -28,15 +27,11 @@ public interface Feature<T : Any> {
public var attributes: AttributeMap public var attributes: AttributeMap
public fun getBoundingBox(zoom: Float): Rectangle<T>? public fun getBoundingBox(zoom: Float): Rectangle<T>?
public companion object {
public val defaultZoomRange: FloatRange = 0f..Float.POSITIVE_INFINITY
}
} }
public interface PainterFeature<T:Any>: Feature<T> { public interface PainterFeature<T:Any>: Feature<T> {
@Composable @Composable
public fun painter(): Painter public fun getPainter(): Painter
} }
public interface SelectableFeature<T : Any> : Feature<T> { public interface SelectableFeature<T : Any> : Feature<T> {
@ -72,10 +67,11 @@ public fun <T : Any> Iterable<Feature<T>>.computeBoundingBox(
*/ */
public class FeatureSelector<T : Any>( public class FeatureSelector<T : Any>(
override val space: CoordinateSpace<T>, override val space: CoordinateSpace<T>,
override val zoomRange: FloatRange,
override var attributes: AttributeMap = AttributeMap(), override var attributes: AttributeMap = AttributeMap(),
public val selector: (zoom: Float) -> Feature<T>, public val selector: (zoom: Float) -> Feature<T>,
) : Feature<T> { ) : Feature<T> {
override val zoomRange: FloatRange get() = defaultZoomRange
override fun getBoundingBox(zoom: Float): Rectangle<T>? = selector(zoom).getBoundingBox(zoom) override fun getBoundingBox(zoom: Float): Rectangle<T>? = selector(zoom).getBoundingBox(zoom)
} }
@ -85,9 +81,9 @@ public class PathFeature<T : Any>(
public val rectangle: Rectangle<T>, public val rectangle: Rectangle<T>,
public val path: Path, public val path: Path,
public val brush: Brush, public val brush: Brush,
override val zoomRange: FloatRange,
public val style: DrawStyle = Fill, public val style: DrawStyle = Fill,
public val targetRect: Rect = path.getBounds(), public val targetRect: Rect = path.getBounds(),
override val zoomRange: FloatRange = defaultZoomRange,
override var attributes: AttributeMap = AttributeMap(), override var attributes: AttributeMap = AttributeMap(),
) : DraggableFeature<T> { ) : DraggableFeature<T> {
override fun withCoordinates(newCoordinates: T): Feature<T> = with(space) { override fun withCoordinates(newCoordinates: T): Feature<T> = with(space) {
@ -109,7 +105,7 @@ public class PathFeature<T : Any>(
public class PointsFeature<T : Any>( public class PointsFeature<T : Any>(
override val space: CoordinateSpace<T>, override val space: CoordinateSpace<T>,
public val points: List<T>, public val points: List<T>,
override val zoomRange: FloatRange = defaultZoomRange, override val zoomRange: FloatRange,
public val stroke: Float = 2f, public val stroke: Float = 2f,
public val color: Color = Color.Red, public val color: Color = Color.Red,
public val pointMode: PointMode = PointMode.Points, public val pointMode: PointMode = PointMode.Points,
@ -123,7 +119,7 @@ public class PointsFeature<T : Any>(
public data class CircleFeature<T : Any>( public data class CircleFeature<T : Any>(
override val space: CoordinateSpace<T>, override val space: CoordinateSpace<T>,
override val center: T, override val center: T,
override val zoomRange: FloatRange = defaultZoomRange, override val zoomRange: FloatRange,
public val size: Dp = 5.dp, public val size: Dp = 5.dp,
public val color: Color = Color.Red, public val color: Color = Color.Red,
override var attributes: AttributeMap = AttributeMap(), override var attributes: AttributeMap = AttributeMap(),
@ -138,7 +134,7 @@ public data class CircleFeature<T : Any>(
public class RectangleFeature<T : Any>( public class RectangleFeature<T : Any>(
override val space: CoordinateSpace<T>, override val space: CoordinateSpace<T>,
override val center: T, override val center: T,
override val zoomRange: FloatRange = defaultZoomRange, override val zoomRange: FloatRange,
public val size: DpSize = DpSize(5.dp, 5.dp), public val size: DpSize = DpSize(5.dp, 5.dp),
public val color: Color = Color.Red, public val color: Color = Color.Red,
override var attributes: AttributeMap = AttributeMap(), override var attributes: AttributeMap = AttributeMap(),
@ -154,7 +150,7 @@ public class LineFeature<T : Any>(
override val space: CoordinateSpace<T>, override val space: CoordinateSpace<T>,
public val a: T, public val a: T,
public val b: T, public val b: T,
override val zoomRange: FloatRange = defaultZoomRange, override val zoomRange: FloatRange,
public val color: Color = Color.Red, public val color: Color = Color.Red,
override var attributes: AttributeMap = AttributeMap(), override var attributes: AttributeMap = AttributeMap(),
) : SelectableFeature<T> { ) : SelectableFeature<T> {
@ -175,7 +171,7 @@ public class ArcFeature<T : Any>(
public val oval: Rectangle<T>, public val oval: Rectangle<T>,
public val startAngle: Float, public val startAngle: Float,
public val arcLength: Float, public val arcLength: Float,
override val zoomRange: FloatRange = defaultZoomRange, override val zoomRange: FloatRange,
public val color: Color = Color.Red, public val color: Color = Color.Red,
override var attributes: AttributeMap = AttributeMap(), override var attributes: AttributeMap = AttributeMap(),
) : DraggableFeature<T> { ) : DraggableFeature<T> {
@ -189,7 +185,7 @@ public class ArcFeature<T : Any>(
public data class DrawFeature<T : Any>( public data class DrawFeature<T : Any>(
override val space: CoordinateSpace<T>, override val space: CoordinateSpace<T>,
public val position: T, public val position: T,
override val zoomRange: FloatRange = defaultZoomRange, override val zoomRange: FloatRange,
override var attributes: AttributeMap = AttributeMap(), override var attributes: AttributeMap = AttributeMap(),
public val drawFeature: DrawScope.() -> Unit, public val drawFeature: DrawScope.() -> Unit,
) : DraggableFeature<T> { ) : DraggableFeature<T> {
@ -203,7 +199,7 @@ public data class BitmapImageFeature<T : Any>(
override val center: T, override val center: T,
public val size: DpSize, public val size: DpSize,
public val image: ImageBitmap, public val image: ImageBitmap,
override val zoomRange: FloatRange = defaultZoomRange, override val zoomRange: FloatRange,
override var attributes: AttributeMap = AttributeMap(), override var attributes: AttributeMap = AttributeMap(),
) : MarkerFeature<T> { ) : MarkerFeature<T> {
override fun getBoundingBox(zoom: Float): Rectangle<T> = space.Rectangle(center, zoom, size) override fun getBoundingBox(zoom: Float): Rectangle<T> = space.Rectangle(center, zoom, size)
@ -216,7 +212,7 @@ public data class VectorImageFeature<T : Any>(
override val center: T, override val center: T,
public val size: DpSize, public val size: DpSize,
public val image: ImageVector, public val image: ImageVector,
override val zoomRange: FloatRange = defaultZoomRange, override val zoomRange: FloatRange,
override var attributes: AttributeMap = AttributeMap(), override var attributes: AttributeMap = AttributeMap(),
) : MarkerFeature<T>, PainterFeature<T> { ) : MarkerFeature<T>, PainterFeature<T> {
override fun getBoundingBox(zoom: Float): Rectangle<T> = space.Rectangle(center, zoom, size) override fun getBoundingBox(zoom: Float): Rectangle<T> = space.Rectangle(center, zoom, size)
@ -224,7 +220,7 @@ public data class VectorImageFeature<T : Any>(
override fun withCoordinates(newCoordinates: T): Feature<T> = copy(center = newCoordinates) override fun withCoordinates(newCoordinates: T): Feature<T> = copy(center = newCoordinates)
@Composable @Composable
override fun painter(): VectorPainter = rememberVectorPainter(image) override fun getPainter(): VectorPainter = rememberVectorPainter(image)
} }
/** /**
@ -235,12 +231,12 @@ public data class VectorImageFeature<T : Any>(
public class ScalableImageFeature<T: Any>( public class ScalableImageFeature<T: Any>(
override val space: CoordinateSpace<T>, override val space: CoordinateSpace<T>,
public val rectangle: Rectangle<T>, public val rectangle: Rectangle<T>,
override val zoomRange: FloatRange = defaultZoomRange, override val zoomRange: FloatRange,
override var attributes: AttributeMap = AttributeMap(), override var attributes: AttributeMap = AttributeMap(),
public val painter: @Composable () -> Painter, public val painter: @Composable () -> Painter,
) : Feature<T>, PainterFeature<T>{ ) : Feature<T>, PainterFeature<T>{
@Composable @Composable
override fun painter(): Painter = painter.invoke() override fun getPainter(): Painter = painter.invoke()
override fun getBoundingBox(zoom: Float): Rectangle<T> =rectangle override fun getBoundingBox(zoom: Float): Rectangle<T> =rectangle
} }
@ -252,7 +248,7 @@ public class ScalableImageFeature<T: Any>(
public class FeatureGroup<T : Any>( public class FeatureGroup<T : Any>(
override val space: CoordinateSpace<T>, override val space: CoordinateSpace<T>,
public val children: Map<FeatureId<*>, Feature<T>>, public val children: Map<FeatureId<*>, Feature<T>>,
override val zoomRange: FloatRange = defaultZoomRange, override val zoomRange: FloatRange,
override var attributes: AttributeMap = AttributeMap(), override var attributes: AttributeMap = AttributeMap(),
) : Feature<T> { ) : Feature<T> {
override fun getBoundingBox(zoom: Float): Rectangle<T>? = with(space) { override fun getBoundingBox(zoom: Float): Rectangle<T>? = with(space) {
@ -264,7 +260,7 @@ public class TextFeature<T : Any>(
override val space: CoordinateSpace<T>, override val space: CoordinateSpace<T>,
public val position: T, public val position: T,
public val text: String, public val text: String,
override val zoomRange: FloatRange = defaultZoomRange, override val zoomRange: FloatRange,
public val color: Color = Color.Black, public val color: Color = Color.Black,
override var attributes: AttributeMap = AttributeMap(), override var attributes: AttributeMap = AttributeMap(),
public val fontConfig: FeatureFont.() -> Unit, public val fontConfig: FeatureFont.() -> Unit,

View File

@ -11,11 +11,11 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import center.sciprog.maps.features.Feature.Companion.defaultZoomRange
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlin.jvm.JvmInline
@JvmInline @JvmInline
public value class FeatureId<out F : Feature<*>>(public val id: String) public value class FeatureId<out F : Feature<*>>(public val id: String)
@ -29,6 +29,8 @@ public interface FeatureBuilder<T : Any> {
public fun <F : Feature<T>, V> setAttribute(id: FeatureId<F>, key: Feature.Attribute<V>, value: V?) public fun <F : Feature<T>, V> setAttribute(id: FeatureId<F>, key: Feature.Attribute<V>, value: V?)
public val defaultColor: Color get() = Color.Red public val defaultColor: Color get() = Color.Red
public val defaultZoomRange: FloatRange get() = 0f..Float.POSITIVE_INFINITY
} }
public fun <T : Any, F : Feature<T>> FeatureBuilder<T>.feature(id: FeatureId<F>, feature: F): FeatureId<F> = public fun <T : Any, F : Feature<T>> FeatureBuilder<T>.feature(id: FeatureId<F>, feature: F): FeatureId<F> =

View File

@ -6,7 +6,7 @@ import androidx.compose.ui.graphics.Color
public fun <T : Any> FeatureCollection<T>.draggableLine( public fun <T : Any> FeatureCollection<T>.draggableLine(
aId: FeatureId<MarkerFeature<T>>, aId: FeatureId<MarkerFeature<T>>,
bId: FeatureId<MarkerFeature<T>>, bId: FeatureId<MarkerFeature<T>>,
zoomRange: FloatRange = Feature.defaultZoomRange, zoomRange: FloatRange = defaultZoomRange,
color: Color = Color.Red, color: Color = Color.Red,
id: String? = null, id: String? = null,
): FeatureId<LineFeature<T>> { ): FeatureId<LineFeature<T>> {

View File

@ -0,0 +1,5 @@
package center.sciprog.maps.features
public actual class FeatureFont {
public actual var size: Float = 16f
}

View File

@ -12,7 +12,7 @@ import center.sciprog.maps.features.*
internal fun Pair<Number, Number>.toCoordinates(): XY = XY(first.toFloat(), second.toFloat()) internal fun Pair<Number, Number>.toCoordinates(): XY = XY(first.toFloat(), second.toFloat())
fun FeatureCollection<XY>.background( fun FeatureBuilder<XY>.background(
width: Float, width: Float,
height: Float, height: Float,
offset: XY = XY(0f, 0f), offset: XY = XY(0f, 0f),
@ -25,42 +25,42 @@ fun FeatureCollection<XY>.background(
) )
return feature( return feature(
id, id,
ScalableImageFeature(coordinateSpace, box, painter = painter).apply { ScalableImageFeature(coordinateSpace, box, zoomRange = defaultZoomRange, painter = painter).apply {
z = -100f z = -100f
} }
) )
} }
fun FeatureCollection<XY>.circle( fun FeatureBuilder<XY>.circle(
centerCoordinates: Pair<Number, Number>, centerCoordinates: Pair<Number, Number>,
zoomRange: FloatRange = Feature.defaultZoomRange, zoomRange: FloatRange = defaultZoomRange,
size: Dp = 5.dp, size: Dp = 5.dp,
color: Color = Color.Red, color: Color = Color.Red,
id: String? = null, id: String? = null,
): FeatureId<CircleFeature<XY>> = circle(centerCoordinates.toCoordinates(), zoomRange, size, color, id = id) ): FeatureId<CircleFeature<XY>> = circle(centerCoordinates.toCoordinates(), zoomRange, size, color, id = id)
fun FeatureCollection<XY>.draw( fun FeatureBuilder<XY>.draw(
position: Pair<Number, Number>, position: Pair<Number, Number>,
zoomRange: FloatRange = Feature.defaultZoomRange, zoomRange: FloatRange = defaultZoomRange,
id: String? = null, id: String? = null,
draw: DrawScope.() -> Unit, draw: DrawScope.() -> Unit,
): FeatureId<DrawFeature<XY>> = draw(position.toCoordinates(), zoomRange = zoomRange, id = id, draw = draw) ): FeatureId<DrawFeature<XY>> = draw(position.toCoordinates(), zoomRange = zoomRange, id = id, draw = draw)
fun FeatureCollection<XY>.line( fun FeatureBuilder<XY>.line(
aCoordinates: Pair<Number, Number>, aCoordinates: Pair<Number, Number>,
bCoordinates: Pair<Number, Number>, bCoordinates: Pair<Number, Number>,
scaleRange: FloatRange = Feature.defaultZoomRange, scaleRange: FloatRange = defaultZoomRange,
color: Color = Color.Red, color: Color = Color.Red,
id: String? = null, id: String? = null,
): FeatureId<LineFeature<XY>> = line(aCoordinates.toCoordinates(), bCoordinates.toCoordinates(), scaleRange, color, id) ): FeatureId<LineFeature<XY>> = line(aCoordinates.toCoordinates(), bCoordinates.toCoordinates(), scaleRange, color, id)
public fun FeatureCollection<XY>.arc( public fun FeatureBuilder<XY>.arc(
center: Pair<Double, Double>, center: Pair<Double, Double>,
radius: Float, radius: Float,
startAngle: Float, startAngle: Float,
arcLength: Float, arcLength: Float,
zoomRange: FloatRange = Feature.defaultZoomRange, zoomRange: FloatRange = defaultZoomRange,
color: Color = Color.Red, color: Color = Color.Red,
id: String? = null, id: String? = null,
): FeatureId<ArcFeature<XY>> = arc( ): FeatureId<ArcFeature<XY>> = arc(
@ -71,19 +71,19 @@ public fun FeatureCollection<XY>.arc(
color = color color = color
) )
fun FeatureCollection<XY>.image( fun FeatureBuilder<XY>.image(
position: Pair<Number, Number>, position: Pair<Number, Number>,
image: ImageVector, image: ImageVector,
size: DpSize = DpSize(image.defaultWidth, image.defaultHeight), size: DpSize = DpSize(image.defaultWidth, image.defaultHeight),
zoomRange: FloatRange = Feature.defaultZoomRange, zoomRange: FloatRange = defaultZoomRange,
id: String? = null, id: String? = null,
): FeatureId<VectorImageFeature<XY>> = ): FeatureId<VectorImageFeature<XY>> =
image(position.toCoordinates(), image, size = size, zoomRange = zoomRange, id = id) image(position.toCoordinates(), image, size = size, zoomRange = zoomRange, id = id)
fun FeatureCollection<XY>.text( fun FeatureBuilder<XY>.text(
position: Pair<Number, Number>, position: Pair<Number, Number>,
text: String, text: String,
zoomRange: FloatRange = Feature.defaultZoomRange, zoomRange: FloatRange = defaultZoomRange,
color: Color = Color.Red, color: Color = Color.Red,
id: String? = null, id: String? = null,
): FeatureId<TextFeature<XY>> = text(position.toCoordinates(), text, zoomRange, color, id = id) ): FeatureId<TextFeature<XY>> = text(position.toCoordinates(), text, zoomRange, color, id = id)

View File

@ -37,7 +37,7 @@ public fun SchemeView(
} }
with(state) { with(state) {
val painterCache: Map<PainterFeature<XY>, Painter> = key(featuresState) { val painterCache: Map<PainterFeature<XY>, Painter> = key(featuresState) {
featuresState.features.values.filterIsInstance<PainterFeature<XY>>().associateWith { it.painter() } featuresState.features.values.filterIsInstance<PainterFeature<XY>>().associateWith { it.getPainter() }
} }
Canvas(modifier = modifier.mapControls(state).fillMaxSize()) { Canvas(modifier = modifier.mapControls(state).fillMaxSize()) {

View File

@ -24,7 +24,7 @@ class FeatureStateSnapshot<T : Any>(
@Composable @Composable
fun <T: Any> FeatureCollection<T>.snapshot(): FeatureStateSnapshot<T> = FeatureStateSnapshot( fun <T: Any> FeatureCollection<T>.snapshot(): FeatureStateSnapshot<T> = FeatureStateSnapshot(
features, features,
features.values.filterIsInstance<PainterFeature<T>>().associateWith { it.painter() } features.values.filterIsInstance<PainterFeature<T>>().associateWith { it.getPainter() }
) )
fun FeatureStateSnapshot<XY>.generateSvg( fun FeatureStateSnapshot<XY>.generateSvg(