v. 1.2.0
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:
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user