Skip to content

Commit

Permalink
Merge pull request #14 from godaddy/feature/color-wheel-harmony
Browse files Browse the repository at this point in the history
Added a Color Wheel for Harmony Color Modes
  • Loading branch information
Rebecca Franks authored Jan 21, 2022
2 parents 7da1762 + b482aa2 commit 9b1872f
Show file tree
Hide file tree
Showing 23 changed files with 931 additions and 105 deletions.
70 changes: 66 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

![Maven Central](https://img.shields.io/maven-central/v/com.godaddy.android.colorpicker/compose-color-picker?style=flat-square)

A component that provides an HSV color picker, written in Jetpack compose.
A component that provides two different HSV color pickers, written in Jetpack Compose.
1. ClassicColorPicker - Square picker with alpha channel
2. HarmonyColorPicker - Circular wheel with harmony modes (ie complementary, triadic, analogous, shades, monochromatic, tetradic)

<img src="screenshots/ColorPicker.gif" width="200" />
<img src="screenshots/ColorPicker-Harmony.gif" width="200" />

## How to get started

Expand All @@ -21,7 +24,7 @@ implementation 'com.godaddy.android.colorpicker:compose-color-picker-jvm:<latest

Add `ClassicColorPicker` to your Compose hierarchy:

```
```kotlin
import com.godaddy.android.colorpicker.HsvColor

Column {
Expand All @@ -33,13 +36,30 @@ Column {
}
```

Or add the `HarmonyColorPicker` to your Compose hierarchy for an HSV color wheel implementation:

```kotlin
HarmonyColorPicker(
harmonyMode = harmonyMode.value,
modifier = Modifier.size(400.dp),
onColorChanged = { hsvColor ->
currentColor.value = hsvColor.toColor()
extraColors.value = hsvColor.getColors(colorHarmonyMode = harmonyMode.value)
})
```

The `HarmonyColorPicker` allows for you to set a certain `ColorHarmonyMode` on the wheel.
This will then display multiple magnifiers on top of the wheel for the different harmony modes: ie complementary, triadic, analogous, shades, monochromatic, tetradic.
If you wish to not display other magnifiers - set `ColorHarmonyMode.NONE` as your `harmonyMode` on the wheel.

# ClassicColorPicker:
## Customizing the control

### Size

To change the size of the control, pass in the `Modifier` option:

```
```kotlin
import com.godaddy.android.colorpicker.HsvColor

ClassicColorPicker(
Expand All @@ -54,7 +74,7 @@ ClassicColorPicker(

To hide the alpha bar, change the `showAlphaBar` parameter:

```
```kotlin
import com.godaddy.android.colorpicker.HsvColor

ClassicColorPicker(
Expand All @@ -65,3 +85,45 @@ ClassicColorPicker(
)
```

## HarmonyColorPicker

## Customizing the control

### Harmony Mode

To change the harmony mode of the picker, pass in a different mode into the function:

```kotlin
HarmonyColorPicker(
harmonyMode = ColorHarmonyMode.SHADES,
modifier = Modifier.size(400.dp),
onColorChanged = { hsvColor ->
// do stuff with new color
})
```

### Size

To change the size of the control, pass in the `Modifier` option:

```kotlin
import com.godaddy.android.colorpicker.HsvColor

HarmonyColorPicker(
modifier = Modifier.height(200.dp),
onColorChanged = { color: HsvColor ->
// Do something with the color
}
)
```

# Library Contribution Information

### To make a release

1. Update the version number in color-picker/build.gradle.kts
2. Make a PR into main and get that merged
3. Run "Deploy to Sonatype" GitHub Action.
4. Login to Sonatype and "Close" release. After a few minutes, click "Release".
5. Release should then be available for download on maven (might take like 30 min to propagate).

4 changes: 3 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ version = "1.0"
dependencies {
implementation(project(":color-picker"))
implementation ("androidx.activity:activity-compose:1.4.0")
implementation("com.google.android.material:material:1.4.0")
implementation("com.google.android.material:material:1.5.0")
implementation("androidx.navigation:navigation-runtime-ktx:2.3.5")
implementation("androidx.navigation:navigation-compose:2.4.0-rc01")
}

android {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.godaddy.android.colorpicker

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.godaddy.android.colorpicker.theme.BackButton
import com.godaddy.android.colorpicker.theme.ComposeColorPickerTheme

@Composable
fun ClassicColorPickerScreen(navController: NavController) {
Column {
TopAppBar(title = {
Text(stringResource(R.string.classic_color_picker_sample))
},
navigationIcon = {
BackButton { navController.navigateUp() }
})
val currentColor = remember {
mutableStateOf(Color.Black)
}
ColorPreviewInfo(currentColor = currentColor.value)
ClassicColorPicker(
color = currentColor.value,
modifier = Modifier
.height(300.dp)
.padding(16.dp),
onColorChanged = { hsvColor: HsvColor ->
// Triggered when the color changes, do something with the newly picked color here!
currentColor.value = hsvColor.toColor()
}
)
}

}


@Composable
fun ClassicColorPickerPreview() {
ComposeColorPickerTheme {
ClassicColorPicker(
modifier = Modifier.height(300.dp),
color = Color.Green,
onColorChanged = {

})

}
}

@Composable
fun ClassicColorPickerNoAlphaPreview() {
ComposeColorPickerTheme {
ClassicColorPicker(
modifier = Modifier.height(300.dp),
color = Color.Magenta,
showAlphaBar = false,
onColorChanged = {

})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.godaddy.android.colorpicker

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.GridCells
import androidx.compose.foundation.lazy.LazyVerticalGrid
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

@Composable
fun ColorPreviewInfo(currentColor: Color) {
Column(modifier = Modifier.fillMaxWidth()) {
Text(
modifier = Modifier.padding(16.dp),
text = "a: ${currentColor.alpha} \n" +
"r: ${currentColor.red} \n" +
"g: ${currentColor.green} \n" +
"b: ${currentColor.blue}"
)
Spacer(
modifier = Modifier
.background(
currentColor,
shape = CircleShape
)
.size(48.dp)
.align(Alignment.CenterHorizontally)
)
Spacer(Modifier.height(16.dp))
}
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ColorPaletteBar(
modifier: Modifier = Modifier,
colors: List<HsvColor>
) {
LazyVerticalGrid(
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalArrangement = Arrangement.spacedBy(4.dp),
cells = GridCells.Adaptive(48.dp),
modifier = modifier
.fillMaxWidth(),
contentPadding = PaddingValues(16.dp),
content = {
items(colors) { color ->
Canvas(modifier = Modifier.size(48.dp)) {
drawCircle(color.toColor())
}
}
}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.godaddy.android.colorpicker

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.godaddy.android.colorpicker.harmony.ColorHarmonyMode
import com.godaddy.android.colorpicker.harmony.HarmonyColorPicker
import com.godaddy.android.colorpicker.theme.BackButton

@Composable
fun HarmonyColorPickerScreen(navController: NavController) {
Column {
TopAppBar(title = {
Text(stringResource(R.string.harmony_color_picker_sample))
},
navigationIcon = {
BackButton { navController.navigateUp() }
})
val currentColor = remember {
mutableStateOf(Color.Black)
}
val extraColors = remember {
mutableStateOf(emptyList<HsvColor>())
}
ColorPreviewInfo(currentColor = currentColor.value)
val expanded = remember {
mutableStateOf(false)
}
val harmonyMode = remember {
mutableStateOf(ColorHarmonyMode.ANALOGOUS)
}
TextButton(onClick = {
expanded.value = true
}) {
Text(harmonyMode.value.name)
}
DropdownMenu(expanded.value, onDismissRequest = {
expanded.value = false
}) {
ColorHarmonyMode.values().forEach {
DropdownMenuItem(onClick = {
harmonyMode.value = it
expanded.value = false
}) {
Text(it.name)
}
}
}
HarmonyColorPicker(
harmonyMode = harmonyMode.value,
modifier = Modifier.size(400.dp),
onColorChanged = { hsvColor ->
currentColor.value = hsvColor.toColor()
extraColors.value = hsvColor.getColors(colorHarmonyMode = harmonyMode.value)
})
ColorPaletteBar(modifier = Modifier.fillMaxWidth().height(70.dp), colors = extraColors.value)
}

}
7 changes: 7 additions & 0 deletions app/src/main/java/com/godaddy/android/colorpicker/Routes.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.godaddy.android.colorpicker

sealed class Route(val link: String) {
object Picker : Route("picker")
object ClassicColorPicker : Route("classic")
object HarmonyColorPicker : Route("harmony")
}
Loading

0 comments on commit 9b1872f

Please sign in to comment.