Upgrade knob interaction logic and dependency versions.

Reworked knob value adjustment to use precise mouse coordinates via `setValueByMouseCoords`. Improved user interaction by enhancing activation handling and CSS styling. Updated project dependencies, removed unused packages, and set version to 1.2.0 for compatibility and feature stability.
This commit is contained in:
2024-12-23 12:17:18 +01:00
parent 20e06b8fb9
commit 618dd52865
6 changed files with 65 additions and 27 deletions

View File

@@ -2,6 +2,8 @@ package nl.astraeus.vst.ui.components
import kotlinx.html.classes
import kotlinx.html.js.onMouseDownFunction
import kotlinx.html.js.onMouseLeaveFunction
import kotlinx.html.js.onMouseMoveFunction
import kotlinx.html.js.onMouseUpFunction
import kotlinx.html.js.onWheelFunction
import kotlinx.html.org.w3c.dom.events.Event
@@ -12,11 +14,14 @@ import nl.astraeus.css.properties.Color
import nl.astraeus.css.properties.Position
import nl.astraeus.css.properties.TextAlign
import nl.astraeus.css.properties.em
import nl.astraeus.css.properties.hsla
import nl.astraeus.css.properties.prc
import nl.astraeus.css.properties.px
import nl.astraeus.css.properties.rem
import nl.astraeus.css.style.cls
import nl.astraeus.komp.HtmlBuilder
import nl.astraeus.komp.Komponent
import nl.astraeus.komp.currentElement
import nl.astraeus.vst.ui.css.ActiveCls
import nl.astraeus.vst.ui.css.Css
import nl.astraeus.vst.ui.css.Css.defineCss
@@ -25,6 +30,8 @@ import nl.astraeus.vst.ui.css.CssName
import nl.astraeus.vst.ui.util.arc
import nl.astraeus.vst.ui.util.height
import nl.astraeus.vst.ui.util.width
import org.w3c.dom.Element
import org.w3c.dom.HTMLElement
import org.w3c.dom.events.MouseEvent
import org.w3c.dom.events.WheelEvent
import kotlin.math.PI
@@ -65,10 +72,15 @@ open class BaseKnobComponent(
val actualMaximumValue = valueToActual(maxValue)
var actualValue = valueToActual(value)
var activated = false
var activated: Boolean = false
set(value) {
field = value
requestUpdate()
}
var mouseX = 0.0
var mouseY = 0.0
var startValue = 0.0
var knobElement: Element? = null
private fun getMiddleX() = width / 2
private fun getMiddleY() = ((height - 16) / 2) + 16
@@ -77,6 +89,11 @@ open class BaseKnobComponent(
override fun HtmlBuilder.render() {
span(KnobCls.name) {
style = "width: ${width}px; height: ${height}px"
knobElement = currentElement()
if (activated) {
classes += ActiveCls.name
}
svg(KnobSvgCls.name) {
if (activated) {
@@ -87,7 +104,7 @@ open class BaseKnobComponent(
height(height)
val actToVal = actualToValue(actualValue)
console.log("actualValue", actualValue, "actToVal", actToVal)
val middle = (
((ANGLE_RANGE_DEG.toFloat() *
(actToVal - minValue)) /
@@ -159,17 +176,27 @@ open class BaseKnobComponent(
onMouseDownFunction = {
if (it is MouseEvent) {
activated = true
setValueByMouseCoords(it, minValue, maxValue, callback)
setValueByMouseCoords(it, callback)
}
}
onMouseMoveFunction = {
if (activated && it is MouseEvent) {
setValueByMouseCoords(it, callback)
}
}
onMouseUpFunction = {
if (it is MouseEvent) {
activated = false
requestUpdate()
}
}
onMouseLeaveFunction = {
if (it is MouseEvent) {
activated = false
}
}
}
}
@@ -200,12 +227,15 @@ open class BaseKnobComponent(
private fun setValueByMouseCoords(
it: MouseEvent,
minValue: Double = 0.0,
maxValue: Double = 5.0,
callback: (value: Double) -> Unit
) {
val deltaX = it.offsetX - getMiddleX()
val deltaY = it.offsetY - getMiddleY()
val target = knobElement as? HTMLElement ?: error("Not in an HTMLElement?")
val rect = target.getBoundingClientRect();
val mouseX = it.clientX - rect.left;
val mouseY = it.clientY - rect.top;
val deltaX = mouseX - getMiddleX()
val deltaY = mouseY - getMiddleY()
var angle = atan2(deltaX, deltaY)
@@ -236,9 +266,9 @@ open class BaseKnobComponent(
angle < PI / 2.0 -> newValue = maxValue
}
actualValue = newValue
actualValue = valueToActual(newValue)
callback(newValue.toDouble())
callback(newValue)
requestUpdate()
@@ -290,7 +320,10 @@ open class BaseKnobComponent(
position(Position.relative)
margin(5.px)
and(cls(ActiveCls)) {}
and(cls(ActiveCls)) {
backgroundColor(hsla(178, 70, 55, 0.1))
borderRadius(0.5.rem)
}
select(cls(KnobSvgCls)) {
plain("stroke", "none")