Git Product home page Git Product logo

mahozad / wavy-slider Goto Github PK

View Code? Open in Web Editor NEW
103.0 1.0 5.0 7.12 MB

Multiplatform wavy slider/progress bar similar to the one in Android 13

Home Page: https://mahozad.ir/wavy-slider

License: Apache License 2.0

Kotlin 98.88% Ruby 0.07% Swift 0.42% HTML 0.42% CSS 0.22%
android compose-multiplatform jetpack-compose material progress-bar slider kotlin sine-wave kotlin-multiplatform jetpack wavy-slider material-design material3 material-you kotlin-multiplatform-sample

wavy-slider's Introduction

Kotlin version Compose Multiplatform version Latest Maven Central release


Real-world demo

Wavy slider

Animated Material wavy slider and progress/seek bar similar to the one used in Android 13 media controls.
It has curly, wobbly, squiggly, wiggly, jiggly, wriggly, dancing movements. Some users call it the sperm.

The library can be used in Jetpack Compose and Compose Multiplatform projects like a regular Material Slider.
Supported target platforms are Android, iOS, Desktop (JVM), and JavaScript (Kotlin/JS and Kotlin/Wasm).

Demo

For a live, interactive Web demo go to https://mahozad.ir/wavy-slider.
For real-world apps in various platforms using the library, see the showcase directory.

Getting started

implementation("ir.mahozad.multiplatform:wavy-slider:1.3.0")
Setup for multiplatform projects

If you target a subset of the library supported platforms, add the library to your common source set:

kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation/* OR api */("ir.mahozad.multiplatform:wavy-slider:1.3.0")
            // ...
        }
// ...

If you have targets that are not supported by the library, add the library separately to each supported target:

kotlin {
    val desktopMain /* OR jvmMain */ by getting {
        dependencies {
            implementation/* OR api */("ir.mahozad.multiplatform:wavy-slider:1.3.0")
            // ...
        }
    }
    androidMain.dependencies {
        implementation/* OR api */("ir.mahozad.multiplatform:wavy-slider:1.3.0")
        // ...
    }
    // Other targets...

Using the WavySlider is much like using the Material Slider (you can even make it a regular flat Slider):

import ir.mahozad.multiplatform.wavyslider.material/*OR material3*/.WavySlider
import ir.mahozad.multiplatform.wavyslider.WaveDirection.*

@Composable
fun MyComposable() {
    var fraction by remember { mutableStateOf(0.5f) }
    WavySlider(
        value = fraction,
        onValueChange = { fraction = it },
        waveLength = 16.dp,     // Set this to 0.dp to get a regular Slider
        waveHeight = 16.dp,     // Set this to 0.dp to get a regular Slider
        waveVelocity = 15.dp to HEAD, // Speed per second and its direction
        waveThickness = 4.dp,   // Defaults to the specified trackThickness
        trackThickness = 4.dp,  // Defaults to 4.dp, same as regular Slider
        incremental = false,    // Whether to gradually increase waveHeight
        // animationSpecs = ... // Customize various animations of the wave
    )
}

Related

wavy-slider's People

Contributors

mahozad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

wavy-slider's Issues

Separate artifacts for material and material3

Can the material and material3 implementations be separated into two distinct artifacts? That way, consumers of wavy-slider would not be exposed to material on their classpath if they're only interested in material3 (and vice versa).

[Question] Value range declaration

Hi! I found this library searching for the implementation in Jetpack Compose of the M3 wavy seekbar.
I'm trying to implement it but I wasn't able to found a parameter to define the range of the bar for when seeking. Could you explain to me a little bit how does this work? (the idea is something like what you have in the GIF of the README)

Material3 1.3 alpha breaks the library: NoSuchMethodError: No virtual method updateDimensions$material3_release

I am trying to integrate this nice library into one of my apps, as you suggested here dokar3/amlv#5.

However, when using it with the latest version of compose material3, it crashed:

java.lang.NoSuchMethodError: No virtual method updateDimensions$material3_release(FI)V in class Landroidx/compose/material3/SliderState; or its super classes (declaration of 'androidx.compose.material3.SliderState' appears in /data/app/~~8QKdEh38z4CLdW726fQCvQ==/com.dokar.upnextgpt-gluA86yOd25GvGrvJB57Yg==/base.apk)
    at ir.mahozad.multiplatform.wavyslider.material3.WavySliderKt$WavySliderImpl$2$1.measure-3p2s80s(WavySlider.kt:596)
    at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:135)
    at androidx.compose.foundation.layout.SizeNode.measure-3p2s80s(Size.kt:838)
    at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:188)
    at androidx.compose.material3.MinimumInteractiveModifierNode.measure-3p2s80s(InteractiveComponentSize.kt:82)
    at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:188)
    at androidx.compose.foundation.layout.FillNode.measure-3p2s80s(Size.kt:699)
    at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:188)
    at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasureBlock$1.invoke(LayoutNodeLayoutDelegate.kt:316)
    at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasureBlock$1.invoke(LayoutNodeLayoutDelegate.kt:315)
    at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:501)

I believe that's because material3 1.3 has changed a lot, I have faced a similar issue due to the material3 API changes dokar3/ChipTextField#145. I hope this will help.

Customizable animation duration

I'd like to increase the animation duration, which is currently hardcoded to 1000ms. Can WaveSlider take in an animationSpec?

Fix the wave height (and the component height) not being accurate

The wave is currently drawn using cubic bezier curves and its control points have simple y-coordinate of waveHeight / 2.
This produces a wave with a height less than the specified waveHeight.

To fix this, do one of the following:

Probably related:

Add screenshot (regression) tests

  • Add automated or manual screenshot tests
    1. When enabled is toggled, the change is smooth (wave animation does not restart)
    2. When flatten is toggled, the change is smooth (wave animation does not restart)
    3. etc.

Desktop App Crash: Cannot round NaN value.

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Cannot round NaN value.
at kotlin.math.MathKt__MathJVMKt.roundToInt(MathJVM.kt:1165)
at ir.mahozad.multiplatform.wavyslider.material3.WavySliderKt$WavySliderImpl$2$1.measure-3p2s80s(WavySlider.kt:602)
at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:126)
at androidx.compose.foundation.layout.SizeNode.measure-3p2s80s(Size.kt:838)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116)
at androidx.compose.material3.MinimumInteractiveModifierNode.measure-3p2s80s(InteractiveComponentSize.kt:84)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116)
at androidx.compose.foundation.layout.FillNode.measure-3p2s80s(Size.kt:699)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:116)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasureBlock$1.invoke(LayoutNodeLayoutDelegate.kt:252)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasureBlock$1.invoke(LayoutNodeLayoutDelegate.kt:251)
image

Suggestion

Instead of changing API daily you should thoroughly think it and then publish.
Maybe utilize ChatGPT, Gemini for brainstorming ideas.

Flatten slider when seeking

In android 13 when you are seeking the slider, the waves disappear to add more focus till you release the thumb and then the waves reappear.
This can be done using dynamic wave height but then the hardcoded track height animation duration (which is 1000ms) makes it awkward.

I suggest two options:

  1. Custom duration for height animation.
  2. Adding flattenOnSeek option to the slider.

I think I can do the suggested options by my self. So if you are OK with it I will start working on it and then create a pull request for them.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.