dynamically update tiles every 1 second

This commit is contained in:
Adam 2022-05-14 12:27:32 +02:00
parent 7e267b82b5
commit c48d01b220
2 changed files with 64 additions and 6 deletions

View file

@ -9,11 +9,16 @@ import io.kvision.CoreModule
import io.kvision.FontAwesomeModule
import io.kvision.html.div
import io.kvision.maps.Maps
import io.kvision.maps.externals.leaflet.layer.tile.GridLayer
import io.kvision.module
import io.kvision.panel.root
import io.kvision.redux.ReduxStore
import io.kvision.require
import io.kvision.startApplication
import kotlin.time.Duration.Companion.seconds
import kotlinx.js.timers.setInterval
import org.w3c.dom.Image
import org.w3c.dom.asList
class App(
@ -37,10 +42,47 @@ class App(
override fun start(state: Map<String, Any>) {
this.appState = state.toMutableMap()
root("kvapp") {
val root = root("kvapp") {
div("Kafkatorio Web Map")
add(kvMaps)
}
kvMaps.leafletMap {
invalidateSize(true)
eachLayer({
if (it is GridLayer<*>) {
it.redraw()
}
})
// this.asDynamic()._fadeAnimated = false
}
setInterval(1.seconds) {
val doc = root.getElement()?.ownerDocument
val window = doc!!.defaultView!!
doc
.querySelectorAll("img.leaflet-tile-loaded")
.asList()
.filterIsInstance<Image>()
.map { img ->
val imgSrc = img.src.substringBeforeLast('?')
println("fetching $imgSrc")
val newImg = Image()
newImg.onload = {
window.requestAnimationFrame {
println("image loaded ${newImg.src}")
img.setAttribute("dynamic-reload", "true")
img.src = newImg.src
Unit
}
}
newImg.src = imgSrc //+ "?t=${currentTimeMillis()}"
}
}
}
override fun dispose(): Map<String, Any> {
@ -49,7 +91,6 @@ class App(
}
fun main() {
startApplication(
{
@ -69,6 +110,6 @@ fun main() {
BootstrapIconsModule,
FontAwesomeModule,
ChartModule,
CoreModule
CoreModule,
)
}

View file

@ -2,9 +2,12 @@ package dev.adamko.kafkatorio.webmap
import io.kvision.maps.Maps
import io.kvision.maps.Maps.Companion.L
import io.kvision.maps.externals.leaflet.DoneCallback
import io.kvision.maps.externals.leaflet.geo.CRS
import io.kvision.maps.externals.leaflet.geo.LatLng
import io.kvision.maps.externals.leaflet.layer.tile.TileLayer
import io.kvision.utils.px
import org.w3c.dom.HTMLElement
//
//val polyline = Maps.L.polyline(
@ -19,6 +22,8 @@ import io.kvision.utils.px
// noClip = true
//}
private const val tileUrlTemplate = """http://localhost:9073/tiles/s1/z{z}/x{x}/y{y}.png"""
fun createFactorioMap() = Maps {
width = 800.px
height = 800.px
@ -27,8 +32,8 @@ fun createFactorioMap() = Maps {
configureLeafletMap {
setView(center = LatLng(0, 0), zoom = 0)
L.tileLayer(
"""http://localhost:9073/tiles/s1/z{z}/x{x}/y{y}.png"""
val baseTileLayer: TileLayer<TileLayer.TileLayerOptions> = L.tileLayer(
tileUrlTemplate
) {
attribution = "kafkatorio"
tileSize = 256
@ -43,8 +48,19 @@ fun createFactorioMap() = Maps {
noWrap = true
updateWhenIdle = false
updateWhenZooming = true
}.addTo(this)
}
val currentTileOnLoad: (DoneCallback, HTMLElement) -> Unit =
baseTileLayer.asDynamic()._tileOnLoad as (DoneCallback, HTMLElement) -> Unit
baseTileLayer.asDynamic()._tileOnLoad = { done: DoneCallback, tile: HTMLElement ->
if (tile.hasAttribute("dynamic-reload")) {
tile.removeAttribute("dynamic-reload")
} else {
currentTileOnLoad(done, tile)
}
}
baseTileLayer.addTo(this)
L.scale {
metric = true
@ -56,5 +72,6 @@ fun createFactorioMap() = Maps {
options.zoomSnap = 0
options.zoomDelta = 0.1
// options.fadeAnimation = false
}
}