Open T8RIN opened 1 year ago
What compose version are you using in that project?
Latest, 1.5.0-beta01 ๐
It looks like in the waveslider library we use the compose BOM package so you could try that. It was automatically created by Android Studio as version 2023.05.01
(see libs.versions.toml)
The thing that worked, is that I copied the module to the project, and bumped compose to 1.5.0-beta01, and had to downgrade minSdk to 21, have no idea, why 26 used here, cause compose needs 21 only :(
Oh so it doesn't crash when minSdk is 21?
No, I meant that there is no point in putting 26 if everything works with 21 ๐
And with the latest compose version it also doesn't crash
Merged PR updating mikSdk, and I found that the latest compose BOM is what is currently in the project so I changed it to individual dependencies, however while the compose version and material versions are updated to the latest one, it breaks the current implementation of the steps because they changed some values to be internal only that we were using to calculate the position of each tick :(
Yes! But i found solution, how to fix it ๐
Just copy private function, which creates step fractions, and that's it :)
I found the solution ! In the update of androidx.compose.material3:material3-*:1.2.0-alpha08, they made sliderPositions depreacted and sliderPositions.tickFractions internal, so I copied the WaveSlider function then I replaced this :
sliderPositions.tickFractions.groupBy {
it > sliderPositions.activeRange.endInclusive ||
it < sliderPositions.activeRange.start
}
with this :
stepsToTickFractions(sliderState.steps).groupBy {
it > sliderState.valueRange.endInclusive ||
it < sliderState.valueRange.start
}
Changes : Slider.kt ยท Gerrit Code Review
I found the stepsToTickFractions function : here
Here is the new file, just create new kt file "WaveSlider.kt" and paste this code :
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.interaction.DragInteraction
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Slider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.lerp
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.PointMode
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.Stroke
import com.galaxygoldfish.waveslider.LocalThumbColor
import com.galaxygoldfish.waveslider.PillThumb
import com.galaxygoldfish.waveslider.WaveAnimationOptions
import com.galaxygoldfish.waveslider.WaveOptions
import com.galaxygoldfish.waveslider.WaveSliderColors
import com.galaxygoldfish.waveslider.WaveSliderDefaults
import kotlin.math.sin
private fun stepsToTickFractions(steps: Int): FloatArray {
return if (steps == 0) floatArrayOf() else FloatArray(steps + 2) { it.toFloat() / (steps + 1) }
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun WaveSlider(
value: Float,
onValueChange: (Float) -> Unit,
modifier: Modifier = Modifier,
onValueChangeFinished: (Float) -> Unit = {},
colors: WaveSliderColors = WaveSliderDefaults.colors(),
animationOptions: WaveAnimationOptions = WaveSliderDefaults.animationOptions(),
waveOptions: WaveOptions = WaveSliderDefaults.waveOptions(),
enabled: Boolean = true,
thumb: @Composable () -> Unit = { PillThumb() },
steps: Int = 0
) {
val amplitude = waveOptions.amplitude
val frequency = waveOptions.frequency
var isDragging by remember { mutableStateOf(false) }
val interactionSource = remember { MutableInteractionSource() }
LaunchedEffect(interactionSource) {
interactionSource.interactions.collect { interaction ->
when (interaction) {
is DragInteraction.Start -> {
isDragging = true
}
is DragInteraction.Stop -> {
isDragging = false
}
}
}
}
val infiniteTransition = rememberInfiniteTransition(label = "Wave infinite transition")
val phaseShiftFloat = infiniteTransition.animateFloat(
label = "Wave phase shift",
initialValue = 0F,
targetValue = 90f,
animationSpec = infiniteRepeatable(
animation = keyframes {
durationMillis = 1000
},
repeatMode = RepeatMode.Restart
)
).value
Slider(
steps = steps,
value = value,
onValueChangeFinished = {
onValueChangeFinished(value)
},
onValueChange = onValueChange,
interactionSource = interactionSource,
enabled = enabled,
modifier = modifier,
thumb = {
CompositionLocalProvider(
LocalThumbColor provides animateColorAsState(
targetValue = if (enabled) {
colors.thumbColor
} else {
colors.disabledThumbColor
},
label = "Thumb color"
).value
) {
thumb()
}
},
track = { sliderState ->
val animatedAmplitude = animateFloatAsState(
targetValue = if (animationOptions.flatlineOnDrag) {
if (animationOptions.reverseFlatline) {
if (isDragging) amplitude else 0F
} else {
if (isDragging) 0F else amplitude
}
} else {
amplitude
},
label = "Wave amplitude"
).value
Canvas(modifier = Modifier.fillMaxWidth()) {
val centerY = size.height / 2f
val startX = 0F
val endX = size.width * value
val path = Path()
for (x in startX.toInt()..endX.toInt()) {
var modifiedX = x.toFloat()
if (animationOptions.animateWave && enabled) {
if (animationOptions.reverseDirection) {
modifiedX += phaseShiftFloat
} else {
modifiedX -= phaseShiftFloat
}
}
val y = (animatedAmplitude * sin(frequency * modifiedX))
path.moveTo(x.toFloat(), centerY - y)
path.lineTo(x.toFloat(), centerY - y)
}
drawPath(
path = path,
color = if (enabled) {
colors.activeTrackColor
} else {
colors.disabledActiveTrackColor
},
style = Stroke(width = 8f, cap = StrokeCap.Round)
)
drawLine(
color = if (enabled) {
colors.inactiveTrackColor
} else {
colors.disabledInactiveTrackColor
},
strokeWidth = 8F,
cap = StrokeCap.Round,
start = Offset(endX + 1, centerY),
end = Offset(size.width, centerY)
)
stepsToTickFractions(sliderState.steps).groupBy {
it > sliderState.valueRange.endInclusive ||
it < sliderState.valueRange.start
}.forEach { (outsideFraction, list) ->
drawPoints(
points = list.map {
Offset(
x = lerp(
start = Offset(startX, centerY),
stop = Offset(size.width, centerY),
fraction = it
).x,
y = center.y
)
},
pointMode = PointMode.Points,
color = if (outsideFraction) {
if (enabled) {
colors.inactiveTickColor
} else {
colors.disabledInactiveTickColor
}
} else {
if (animatedAmplitude == 0F) {
if (enabled) {
colors.activeTickColor
} else {
colors.disabledActiveTickColor
}
} else {
Color.Transparent
}
},
strokeWidth = 10F,
cap = StrokeCap.Round
)
}
}
}
)
}
I hope the developer implement it as soon as possible
I found the solution ! In the update of androidx.compose.material3:material3-*:1.2.0-alpha08, they made sliderPositions depreacted and sliderPositions.tickFractions internal, so I copied the WaveSlider function then I replaced this :
sliderPositions.tickFractions.groupBy { it > sliderPositions.activeRange.endInclusive || it < sliderPositions.activeRange.start }
with this :
stepsToTickFractions(sliderState.steps).groupBy { it > sliderState.valueRange.endInclusive || it < sliderState.valueRange.start }
Changes : Slider.kt ยท Gerrit Code Review
I found the stepsToTickFractions function : here
Here is the new file, just create new kt file "WaveSlider.kt" and paste this code :
import androidx.compose.animation.animateColorAsState import androidx.compose.animation.core.RepeatMode import androidx.compose.animation.core.animateFloat import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.infiniteRepeatable import androidx.compose.animation.core.keyframes import androidx.compose.animation.core.rememberInfiniteTransition import androidx.compose.foundation.Canvas import androidx.compose.foundation.interaction.DragInteraction import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Slider import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.lerp import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.PointMode import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.drawscope.Stroke import com.galaxygoldfish.waveslider.LocalThumbColor import com.galaxygoldfish.waveslider.PillThumb import com.galaxygoldfish.waveslider.WaveAnimationOptions import com.galaxygoldfish.waveslider.WaveOptions import com.galaxygoldfish.waveslider.WaveSliderColors import com.galaxygoldfish.waveslider.WaveSliderDefaults import kotlin.math.sin private fun stepsToTickFractions(steps: Int): FloatArray { return if (steps == 0) floatArrayOf() else FloatArray(steps + 2) { it.toFloat() / (steps + 1) } } @OptIn(ExperimentalMaterial3Api::class) @Composable fun WaveSlider( value: Float, onValueChange: (Float) -> Unit, modifier: Modifier = Modifier, onValueChangeFinished: (Float) -> Unit = {}, colors: WaveSliderColors = WaveSliderDefaults.colors(), animationOptions: WaveAnimationOptions = WaveSliderDefaults.animationOptions(), waveOptions: WaveOptions = WaveSliderDefaults.waveOptions(), enabled: Boolean = true, thumb: @Composable () -> Unit = { PillThumb() }, steps: Int = 0 ) { val amplitude = waveOptions.amplitude val frequency = waveOptions.frequency var isDragging by remember { mutableStateOf(false) } val interactionSource = remember { MutableInteractionSource() } LaunchedEffect(interactionSource) { interactionSource.interactions.collect { interaction -> when (interaction) { is DragInteraction.Start -> { isDragging = true } is DragInteraction.Stop -> { isDragging = false } } } } val infiniteTransition = rememberInfiniteTransition(label = "Wave infinite transition") val phaseShiftFloat = infiniteTransition.animateFloat( label = "Wave phase shift", initialValue = 0F, targetValue = 90f, animationSpec = infiniteRepeatable( animation = keyframes { durationMillis = 1000 }, repeatMode = RepeatMode.Restart ) ).value Slider( steps = steps, value = value, onValueChangeFinished = { onValueChangeFinished(value) }, onValueChange = onValueChange, interactionSource = interactionSource, enabled = enabled, modifier = modifier, thumb = { CompositionLocalProvider( LocalThumbColor provides animateColorAsState( targetValue = if (enabled) { colors.thumbColor } else { colors.disabledThumbColor }, label = "Thumb color" ).value ) { thumb() } }, track = { sliderState -> val animatedAmplitude = animateFloatAsState( targetValue = if (animationOptions.flatlineOnDrag) { if (animationOptions.reverseFlatline) { if (isDragging) amplitude else 0F } else { if (isDragging) 0F else amplitude } } else { amplitude }, label = "Wave amplitude" ).value Canvas(modifier = Modifier.fillMaxWidth()) { val centerY = size.height / 2f val startX = 0F val endX = size.width * value val path = Path() for (x in startX.toInt()..endX.toInt()) { var modifiedX = x.toFloat() if (animationOptions.animateWave && enabled) { if (animationOptions.reverseDirection) { modifiedX += phaseShiftFloat } else { modifiedX -= phaseShiftFloat } } val y = (animatedAmplitude * sin(frequency * modifiedX)) path.moveTo(x.toFloat(), centerY - y) path.lineTo(x.toFloat(), centerY - y) } drawPath( path = path, color = if (enabled) { colors.activeTrackColor } else { colors.disabledActiveTrackColor }, style = Stroke(width = 8f, cap = StrokeCap.Round) ) drawLine( color = if (enabled) { colors.inactiveTrackColor } else { colors.disabledInactiveTrackColor }, strokeWidth = 8F, cap = StrokeCap.Round, start = Offset(endX + 1, centerY), end = Offset(size.width, centerY) ) stepsToTickFractions(sliderState.steps).groupBy { it > sliderState.valueRange.endInclusive || it < sliderState.valueRange.start }.forEach { (outsideFraction, list) -> drawPoints( points = list.map { Offset( x = lerp( start = Offset(startX, centerY), stop = Offset(size.width, centerY), fraction = it ).x, y = center.y ) }, pointMode = PointMode.Points, color = if (outsideFraction) { if (enabled) { colors.inactiveTickColor } else { colors.disabledInactiveTickColor } } else { if (animatedAmplitude == 0F) { if (enabled) { colors.activeTickColor } else { colors.disabledActiveTickColor } } else { Color.Transparent } }, strokeWidth = 10F, cap = StrokeCap.Round ) } } } ) }
I hope the developer implement it as soon as possible
Wow, thanks for that, i'll be waiting too, maybe you can open PR?
I found the solution ! In the update of androidx.compose.material3:material3-*:1.2.0-alpha08, they made sliderPositions depreacted and sliderPositions.tickFractions internal, so I copied the WaveSlider function then I replaced this :
sliderPositions.tickFractions.groupBy { it > sliderPositions.activeRange.endInclusive || it < sliderPositions.activeRange.start }
with this :
stepsToTickFractions(sliderState.steps).groupBy { it > sliderState.valueRange.endInclusive || it < sliderState.valueRange.start }
Changes : Slider.kt ยท Gerrit Code Review I found the stepsToTickFractions function : here Here is the new file, just create new kt file "WaveSlider.kt" and paste this code :
import androidx.compose.animation.animateColorAsState import androidx.compose.animation.core.RepeatMode import androidx.compose.animation.core.animateFloat import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.infiniteRepeatable import androidx.compose.animation.core.keyframes import androidx.compose.animation.core.rememberInfiniteTransition import androidx.compose.foundation.Canvas import androidx.compose.foundation.interaction.DragInteraction import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Slider import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.lerp import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.PointMode import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.drawscope.Stroke import com.galaxygoldfish.waveslider.LocalThumbColor import com.galaxygoldfish.waveslider.PillThumb import com.galaxygoldfish.waveslider.WaveAnimationOptions import com.galaxygoldfish.waveslider.WaveOptions import com.galaxygoldfish.waveslider.WaveSliderColors import com.galaxygoldfish.waveslider.WaveSliderDefaults import kotlin.math.sin private fun stepsToTickFractions(steps: Int): FloatArray { return if (steps == 0) floatArrayOf() else FloatArray(steps + 2) { it.toFloat() / (steps + 1) } } @OptIn(ExperimentalMaterial3Api::class) @Composable fun WaveSlider( value: Float, onValueChange: (Float) -> Unit, modifier: Modifier = Modifier, onValueChangeFinished: (Float) -> Unit = {}, colors: WaveSliderColors = WaveSliderDefaults.colors(), animationOptions: WaveAnimationOptions = WaveSliderDefaults.animationOptions(), waveOptions: WaveOptions = WaveSliderDefaults.waveOptions(), enabled: Boolean = true, thumb: @Composable () -> Unit = { PillThumb() }, steps: Int = 0 ) { val amplitude = waveOptions.amplitude val frequency = waveOptions.frequency var isDragging by remember { mutableStateOf(false) } val interactionSource = remember { MutableInteractionSource() } LaunchedEffect(interactionSource) { interactionSource.interactions.collect { interaction -> when (interaction) { is DragInteraction.Start -> { isDragging = true } is DragInteraction.Stop -> { isDragging = false } } } } val infiniteTransition = rememberInfiniteTransition(label = "Wave infinite transition") val phaseShiftFloat = infiniteTransition.animateFloat( label = "Wave phase shift", initialValue = 0F, targetValue = 90f, animationSpec = infiniteRepeatable( animation = keyframes { durationMillis = 1000 }, repeatMode = RepeatMode.Restart ) ).value Slider( steps = steps, value = value, onValueChangeFinished = { onValueChangeFinished(value) }, onValueChange = onValueChange, interactionSource = interactionSource, enabled = enabled, modifier = modifier, thumb = { CompositionLocalProvider( LocalThumbColor provides animateColorAsState( targetValue = if (enabled) { colors.thumbColor } else { colors.disabledThumbColor }, label = "Thumb color" ).value ) { thumb() } }, track = { sliderState -> val animatedAmplitude = animateFloatAsState( targetValue = if (animationOptions.flatlineOnDrag) { if (animationOptions.reverseFlatline) { if (isDragging) amplitude else 0F } else { if (isDragging) 0F else amplitude } } else { amplitude }, label = "Wave amplitude" ).value Canvas(modifier = Modifier.fillMaxWidth()) { val centerY = size.height / 2f val startX = 0F val endX = size.width * value val path = Path() for (x in startX.toInt()..endX.toInt()) { var modifiedX = x.toFloat() if (animationOptions.animateWave && enabled) { if (animationOptions.reverseDirection) { modifiedX += phaseShiftFloat } else { modifiedX -= phaseShiftFloat } } val y = (animatedAmplitude * sin(frequency * modifiedX)) path.moveTo(x.toFloat(), centerY - y) path.lineTo(x.toFloat(), centerY - y) } drawPath( path = path, color = if (enabled) { colors.activeTrackColor } else { colors.disabledActiveTrackColor }, style = Stroke(width = 8f, cap = StrokeCap.Round) ) drawLine( color = if (enabled) { colors.inactiveTrackColor } else { colors.disabledInactiveTrackColor }, strokeWidth = 8F, cap = StrokeCap.Round, start = Offset(endX + 1, centerY), end = Offset(size.width, centerY) ) stepsToTickFractions(sliderState.steps).groupBy { it > sliderState.valueRange.endInclusive || it < sliderState.valueRange.start }.forEach { (outsideFraction, list) -> drawPoints( points = list.map { Offset( x = lerp( start = Offset(startX, centerY), stop = Offset(size.width, centerY), fraction = it ).x, y = center.y ) }, pointMode = PointMode.Points, color = if (outsideFraction) { if (enabled) { colors.inactiveTickColor } else { colors.disabledInactiveTickColor } } else { if (animatedAmplitude == 0F) { if (enabled) { colors.activeTickColor } else { colors.disabledActiveTickColor } } else { Color.Transparent } }, strokeWidth = 10F, cap = StrokeCap.Round ) } } } ) }
I hope the developer implement it as soon as possible
Wow, thanks for that, i'll be waiting too, maybe you can open PR?
Do you mean pull request ? I know it's silly question but I'm new in Github
@YounesBouhouche did you noticed Layout Node not attached to owner exception after updating to 1.2.0-06 or 07-08 ?
I found the solution ! In the update of androidx.compose.material3:material3-*:1.2.0-alpha08, they made sliderPositions depreacted and sliderPositions.tickFractions internal, so I copied the WaveSlider function then I replaced this :
sliderPositions.tickFractions.groupBy { it > sliderPositions.activeRange.endInclusive || it < sliderPositions.activeRange.start }
with this :
stepsToTickFractions(sliderState.steps).groupBy { it > sliderState.valueRange.endInclusive || it < sliderState.valueRange.start }
Changes : Slider.kt ยท Gerrit Code Review I found the stepsToTickFractions function : here Here is the new file, just create new kt file "WaveSlider.kt" and paste this code :
import androidx.compose.animation.animateColorAsState import androidx.compose.animation.core.RepeatMode import androidx.compose.animation.core.animateFloat import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.infiniteRepeatable import androidx.compose.animation.core.keyframes import androidx.compose.animation.core.rememberInfiniteTransition import androidx.compose.foundation.Canvas import androidx.compose.foundation.interaction.DragInteraction import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Slider import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.lerp import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.PointMode import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.drawscope.Stroke import com.galaxygoldfish.waveslider.LocalThumbColor import com.galaxygoldfish.waveslider.PillThumb import com.galaxygoldfish.waveslider.WaveAnimationOptions import com.galaxygoldfish.waveslider.WaveOptions import com.galaxygoldfish.waveslider.WaveSliderColors import com.galaxygoldfish.waveslider.WaveSliderDefaults import kotlin.math.sin private fun stepsToTickFractions(steps: Int): FloatArray { return if (steps == 0) floatArrayOf() else FloatArray(steps + 2) { it.toFloat() / (steps + 1) } } @OptIn(ExperimentalMaterial3Api::class) @Composable fun WaveSlider( value: Float, onValueChange: (Float) -> Unit, modifier: Modifier = Modifier, onValueChangeFinished: (Float) -> Unit = {}, colors: WaveSliderColors = WaveSliderDefaults.colors(), animationOptions: WaveAnimationOptions = WaveSliderDefaults.animationOptions(), waveOptions: WaveOptions = WaveSliderDefaults.waveOptions(), enabled: Boolean = true, thumb: @Composable () -> Unit = { PillThumb() }, steps: Int = 0 ) { val amplitude = waveOptions.amplitude val frequency = waveOptions.frequency var isDragging by remember { mutableStateOf(false) } val interactionSource = remember { MutableInteractionSource() } LaunchedEffect(interactionSource) { interactionSource.interactions.collect { interaction -> when (interaction) { is DragInteraction.Start -> { isDragging = true } is DragInteraction.Stop -> { isDragging = false } } } } val infiniteTransition = rememberInfiniteTransition(label = "Wave infinite transition") val phaseShiftFloat = infiniteTransition.animateFloat( label = "Wave phase shift", initialValue = 0F, targetValue = 90f, animationSpec = infiniteRepeatable( animation = keyframes { durationMillis = 1000 }, repeatMode = RepeatMode.Restart ) ).value Slider( steps = steps, value = value, onValueChangeFinished = { onValueChangeFinished(value) }, onValueChange = onValueChange, interactionSource = interactionSource, enabled = enabled, modifier = modifier, thumb = { CompositionLocalProvider( LocalThumbColor provides animateColorAsState( targetValue = if (enabled) { colors.thumbColor } else { colors.disabledThumbColor }, label = "Thumb color" ).value ) { thumb() } }, track = { sliderState -> val animatedAmplitude = animateFloatAsState( targetValue = if (animationOptions.flatlineOnDrag) { if (animationOptions.reverseFlatline) { if (isDragging) amplitude else 0F } else { if (isDragging) 0F else amplitude } } else { amplitude }, label = "Wave amplitude" ).value Canvas(modifier = Modifier.fillMaxWidth()) { val centerY = size.height / 2f val startX = 0F val endX = size.width * value val path = Path() for (x in startX.toInt()..endX.toInt()) { var modifiedX = x.toFloat() if (animationOptions.animateWave && enabled) { if (animationOptions.reverseDirection) { modifiedX += phaseShiftFloat } else { modifiedX -= phaseShiftFloat } } val y = (animatedAmplitude * sin(frequency * modifiedX)) path.moveTo(x.toFloat(), centerY - y) path.lineTo(x.toFloat(), centerY - y) } drawPath( path = path, color = if (enabled) { colors.activeTrackColor } else { colors.disabledActiveTrackColor }, style = Stroke(width = 8f, cap = StrokeCap.Round) ) drawLine( color = if (enabled) { colors.inactiveTrackColor } else { colors.disabledInactiveTrackColor }, strokeWidth = 8F, cap = StrokeCap.Round, start = Offset(endX + 1, centerY), end = Offset(size.width, centerY) ) stepsToTickFractions(sliderState.steps).groupBy { it > sliderState.valueRange.endInclusive || it < sliderState.valueRange.start }.forEach { (outsideFraction, list) -> drawPoints( points = list.map { Offset( x = lerp( start = Offset(startX, centerY), stop = Offset(size.width, centerY), fraction = it ).x, y = center.y ) }, pointMode = PointMode.Points, color = if (outsideFraction) { if (enabled) { colors.inactiveTickColor } else { colors.disabledInactiveTickColor } } else { if (animatedAmplitude == 0F) { if (enabled) { colors.activeTickColor } else { colors.disabledActiveTickColor } } else { Color.Transparent } }, strokeWidth = 10F, cap = StrokeCap.Round ) } } } ) }
I hope the developer implement it as soon as possible
Wow, thanks for that, i'll be waiting too, maybe you can open PR?
Me too, but what's PR? how to open it?
You need to fork the project and then apply your changes in your fork, and then open pull request on GitHub
@YounesBouhouche did you noticed Layout Node not attached to owner exception after updating to 1.2.0-06 or 07-08 ?
No I didn't
@YounesBouhouche did you noticed Layout Node not attached to owner exception after updating to 1.2.0-06 or 07-08 ?
No I didn't
:(
Hi all, got back to maintaining this project and I have updated WaveSlider.kt with the fix in this commit [cbab52b]
@T8RIN @YounesBouhouche Does this address the issue?
I have no idea, why this happens, maybe that's because i use newer compose version...