Bugfixes calendar auto scroll
This commit is contained in:
parent
5cf089dd72
commit
73c4190231
|
@ -3,15 +3,16 @@ package de.kif.frontend.views.calendar
|
|||
import de.kif.frontend.launch
|
||||
import de.kif.frontend.repository.RoomRepository
|
||||
import de.kif.frontend.repository.ScheduleRepository
|
||||
import de.westermann.kwebview.View
|
||||
import de.westermann.kwebview.createHtmlView
|
||||
import de.westermann.kwebview.iterator
|
||||
import de.westermann.kwebview.*
|
||||
import de.westermann.robots.website.toolkit.view.TouchEvent
|
||||
import org.w3c.dom.*
|
||||
import org.w3c.dom.events.Event
|
||||
import org.w3c.dom.events.EventListener
|
||||
import org.w3c.dom.events.MouseEvent
|
||||
import org.w3c.dom.events.WheelEvent
|
||||
import kotlin.browser.document
|
||||
import kotlin.browser.window
|
||||
import kotlin.js.Date
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
|
@ -80,6 +81,41 @@ class Calendar(calendar: HTMLElement) : View(calendar) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun scroll(horizontal: Double, vertical: Double, event: Event? = null) {
|
||||
var horizontalScroll = horizontal
|
||||
var verticalScroll = vertical
|
||||
|
||||
if (verticalScroll > 0) {
|
||||
val x = html.offsetTop - htmlBody.scrollTop
|
||||
if (x > 0) {
|
||||
val bodyScroll = min(x, verticalScroll)
|
||||
verticalScroll -= bodyScroll
|
||||
htmlBody.scrollBy(ScrollToOptions(0.0, bodyScroll, ScrollBehavior.INSTANT))
|
||||
} else {
|
||||
if (calendarTable.scrollTop + calendarTable.clientHeight + 5 >= calendarTable.scrollHeight) {
|
||||
htmlBody.scrollBy(ScrollToOptions(0.0, verticalScroll, ScrollBehavior.INSTANT))
|
||||
}
|
||||
}
|
||||
} else if (verticalScroll < 0) {
|
||||
val x = html.offsetTop - htmlBody.scrollTop
|
||||
if (x < 0) {
|
||||
val bodyScroll = max(x, verticalScroll)
|
||||
verticalScroll -= bodyScroll
|
||||
htmlBody.scrollBy(ScrollToOptions(0.0, bodyScroll, ScrollBehavior.INSTANT))
|
||||
} else {
|
||||
if (calendarTable.scrollTop == 0.0) {
|
||||
htmlBody.scrollBy(ScrollToOptions(0.0, verticalScroll, ScrollBehavior.INSTANT))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scrollHorizontalBy(horizontalScroll, ScrollBehavior.INSTANT)
|
||||
scrollVerticalBy(verticalScroll, ScrollBehavior.INSTANT)
|
||||
|
||||
event?.preventDefault()
|
||||
event?.stopPropagation()
|
||||
}
|
||||
|
||||
init {
|
||||
scroll += calendarTable
|
||||
|
||||
|
@ -113,52 +149,61 @@ class Calendar(calendar: HTMLElement) : View(calendar) {
|
|||
}
|
||||
}
|
||||
|
||||
onWheel {
|
||||
document.addEventListener("wheel", EventListener {
|
||||
val event = it as? WheelEvent ?: return@EventListener
|
||||
|
||||
autoScroll = false
|
||||
|
||||
val multiplier = when (it.deltaMode) {
|
||||
val multiplier = when (event.deltaMode) {
|
||||
1 -> 16.0
|
||||
2 -> window.innerHeight.toDouble()
|
||||
else -> 1.0
|
||||
}
|
||||
|
||||
var verticalScroll = it.deltaY * multiplier
|
||||
scroll(event.deltaX * multiplier, event.deltaY * multiplier, event)
|
||||
})
|
||||
|
||||
if (verticalScroll > 0) {
|
||||
val x = html.offsetTop - htmlBody.scrollTop
|
||||
if (x > 0) {
|
||||
val bodyScroll = min(x, verticalScroll)
|
||||
verticalScroll -= bodyScroll
|
||||
htmlBody.scrollBy(ScrollToOptions(0.0, bodyScroll, ScrollBehavior.INSTANT))
|
||||
} else {
|
||||
if (calendarTable.scrollTop + calendarTable.clientHeight + 5 >= calendarTable.scrollHeight) {
|
||||
htmlBody.scrollBy(ScrollToOptions(0.0, verticalScroll, ScrollBehavior.INSTANT))
|
||||
}
|
||||
}
|
||||
} else if (verticalScroll < 0) {
|
||||
val x = html.offsetTop - htmlBody.scrollTop
|
||||
if (x < 0) {
|
||||
val bodyScroll = max(x, verticalScroll)
|
||||
verticalScroll -= bodyScroll
|
||||
htmlBody.scrollBy(ScrollToOptions(0.0, bodyScroll, ScrollBehavior.INSTANT))
|
||||
} else {
|
||||
if (calendarTable.scrollTop == 0.0) {
|
||||
htmlBody.scrollBy(ScrollToOptions(0.0, verticalScroll, ScrollBehavior.INSTANT))
|
||||
}
|
||||
}
|
||||
}
|
||||
var mousePoint: Point? = null
|
||||
|
||||
scrollHorizontalBy(it.deltaX * multiplier, ScrollBehavior.INSTANT)
|
||||
scrollVerticalBy(verticalScroll, ScrollBehavior.INSTANT)
|
||||
|
||||
it.preventDefault()
|
||||
}
|
||||
|
||||
onMouseDown {
|
||||
document.addEventListener("mousedown", EventListener {
|
||||
val event = it as? MouseEvent ?: return@EventListener
|
||||
mousePoint = event.toPoint()
|
||||
})
|
||||
document.addEventListener("mouseup", EventListener {
|
||||
mousePoint = null
|
||||
})
|
||||
document.addEventListener("mousemove", EventListener {
|
||||
val event = it as? MouseEvent ?: return@EventListener
|
||||
autoScroll = false
|
||||
}
|
||||
|
||||
html.addEventListener("touchstart", EventListener {
|
||||
val mp = mousePoint ?: return@EventListener
|
||||
val p = event.toPoint()
|
||||
|
||||
scroll(mp.x - p.x, mp.y - p.y, event)
|
||||
|
||||
mousePoint = p
|
||||
})
|
||||
|
||||
document.addEventListener("touchstart", EventListener {
|
||||
val event = it as? TouchEvent ?: return@EventListener
|
||||
mousePoint = event.toPoint()
|
||||
})
|
||||
document.addEventListener("touchend", EventListener {
|
||||
mousePoint = null
|
||||
})
|
||||
document.addEventListener("touchmove", EventListener {
|
||||
val event = it as? TouchEvent ?: return@EventListener
|
||||
autoScroll = false
|
||||
|
||||
val mp = mousePoint ?: return@EventListener
|
||||
val p = event.toPoint() ?: return@EventListener
|
||||
|
||||
scroll(mp.x - p.x, mp.y - p.y, event)
|
||||
|
||||
mousePoint = p
|
||||
})
|
||||
|
||||
document.addEventListener("scroll", EventListener {
|
||||
autoScroll = false
|
||||
})
|
||||
|
||||
|
|
39
src/jsMain/kotlin/de/westermann/kwebview/TouchPolyfill.kt
Normal file
39
src/jsMain/kotlin/de/westermann/kwebview/TouchPolyfill.kt
Normal file
|
@ -0,0 +1,39 @@
|
|||
package de.westermann.robots.website.toolkit.view
|
||||
|
||||
import org.w3c.dom.events.EventTarget
|
||||
import org.w3c.dom.events.UIEvent
|
||||
|
||||
/**
|
||||
* @author lars
|
||||
*/
|
||||
|
||||
open external class TouchEvent(type: String) : UIEvent {
|
||||
open val changedTouches: TouchList
|
||||
open val targetTouches: TouchList
|
||||
open val touches: TouchList
|
||||
open val ctrlKey: Boolean
|
||||
open val shiftKey: Boolean
|
||||
open val altKey: Boolean
|
||||
open val metaKey: Boolean
|
||||
fun getModifierState(keyArg: String): Boolean
|
||||
}
|
||||
|
||||
open external class TouchList() {
|
||||
open val length: Int
|
||||
open fun item(index: Int): Touch?
|
||||
}
|
||||
|
||||
open external class Touch() {
|
||||
open val identifier: Int
|
||||
open val target: EventTarget
|
||||
open val screenX: Int
|
||||
open val screenY: Int
|
||||
open val clientX: Int
|
||||
open val clientY: Int
|
||||
open val pageX: Int
|
||||
open val pageY: Int
|
||||
}
|
||||
|
||||
operator fun TouchList.get(index: Int) = item(index)
|
||||
fun TouchList.all(): List<Touch> = (0..length).map { item(it) }.filterNotNull()
|
||||
fun TouchList.find(identifier: Int): Touch? = all().find { it.identifier == identifier }
|
|
@ -1,6 +1,8 @@
|
|||
package de.westermann.kwebview
|
||||
|
||||
import de.westermann.kobserve.event.EventHandler
|
||||
import de.westermann.robots.website.toolkit.view.TouchEvent
|
||||
import de.westermann.robots.website.toolkit.view.get
|
||||
import org.w3c.dom.*
|
||||
import org.w3c.dom.events.Event
|
||||
import org.w3c.dom.events.EventListener
|
||||
|
@ -72,6 +74,7 @@ inline fun <reified T> EventHandler<T>.bind(element: HTMLElement, event: String)
|
|||
}
|
||||
|
||||
fun MouseEvent.toPoint(): Point = Point(clientX, clientY)
|
||||
fun TouchEvent.toPoint(): Point? = touches[0]?.let { Point(it.clientX, it.clientY) }
|
||||
fun DOMRect.toDimension(): Dimension = Dimension(x, y, width, height)
|
||||
|
||||
fun Number.format(digits: Int): String = this.asDynamic().toFixed(digits)
|
||||
|
|
Loading…
Reference in a new issue