Compose Virtual Joystick Multiplatform


A customizable virtual joystick library for Compose Multiplatform that provides touch-based directional controls with configurable dead zones, multiple direction types, and customizable visual styles.
Features
- Multiplatform Support: Works on Android, iOS, Desktop (JVM), Web (JS), and WASM
- Fully Customizable: Control appearance with custom drawing scopes
Installation
Add the dependency to your build.gradle.kts:
commonMain.dependencies {
implementation("io.github.yoimerdr.compose:virtualjoystick:x.x.x")
}
Quick Start
Simple Usage
@Composable
fun SampleJoystick() {
val joystickState = rememberJoystickState()
VirtualJoystick(
state = joystickState,
modifier = Modifier.size(200.dp),
properties = CircleDrawDefaults.properties()
) { snapshot ->
println("Direction: ${snapshot.direction}, Strength: ${snapshot.strength}")
}
}
Usage with Events
{
joystickState = rememberJoystickState(
invalidRadius = Radius.Ratio(),
directionType = DirectionType.Complete
)
eventHolder = rememberJoystickEventHolder(joystickState)
LaunchedEffect(eventHolder) {
eventHolder.events.collect { event ->
(event) {
JoystickMoveStart -> println()
JoystickMoving -> println()
JoystickMoveHeld -> println()
JoystickMoveEnd -> println()
}
}
}
VirtualJoystick(
state = joystickState,
modifier = Modifier.size(dp),
properties = CircleDrawDefaults.properties(),
holder = eventHolder
)
}
Custom Appearance
@Composable
fun CustomStyledJoystick() {
val state = rememberJoystickState()
BaseVirtualJoystick(
state = state,
modifier = Modifier.size(200.dp),
onMove = {
}
) {
Canvas(
modifier = Modifier.fillMaxSize()
) {
drawCircle(
brush = SolidColor(Color.Gray.copy(alpha = 0.3f)),
radius = state.radius
)
}
JoystickCanvas {
drawCircle(
properties = CircleDrawDefaults.properties(
brush = SolidColor(Color.Yellow),
radius = Radius.Fixed(state.radius * ),
)
)
}
}
}
Documentation
Direction Types
DirectionType.Complete: Returns all 8 directions (Right, DownRight, Down, DownLeft, Left, UpLeft, Up, UpRight, None)
DirectionType.Simple: Returns only 4 cardinal directions (Right, Down, Left, Up, None)
Background Types
The library includes several pre-built background styles:
BackgroundType.Default: The default background style
BackgroundType.Modern: Modern styled background
BackgroundType.Classic: Standard circular background
BackgroundType.DpadModern: Modern D-pad style
Joystick State
The JoystickState provides:
offset: Current joystick offset position
direction: Current direction enum value
strength: Movement strength (0.0 to 1.0)
angle: Current angle in degrees
Event Types
JoystickMoveStart: Triggered when touch begins
JoystickMoving: Triggered during movement
JoystickMoveHeld: Triggered when held in position
JoystickMoveEnd: Triggered when touch ends
Sample App
The composeApp module contains a comprehensive demo application showcasing:
- Different drawing types (Circle, Arc, Wedge, etc.)
- Customizable colors and styles
- Event handling examples
- Direction type switching
- Real-time state visualization
Run the sample:
./gradlew :composeApp:run
Platform Support
iOS Note: The iOS 13+ minimum version is inherited from the default Kotlin Multiplatform configuration. The library has not been fully tested on all iOS versions, so compatibility with iOS 13+ is not 100% guaranteed. If you encounter any issues on specific iOS versions, please report them in the issue tracker.
Building from Source
git clone https://github.com/yoimerdr/compose-virtualjoystick-multiplatform.git
./gradlew :library:build
./gradlew :library:test
./gradlew :library:publishToMavenLocal
Requirements
- Kotlin 2.2.21+
- Compose Multiplatform 1.9.3+
- Android minSdk 21+
- iOS 13+
- JVM 11+
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Open a Pull Request
License
This project is licensed under the Apache 2.0 License - see the LICENSE file for details.
Links
Acknowledgments
If you find this library useful, please consider giving it a ⭐ on GitHub!