diff --git a/README.md b/README.md index 0f4b676..d41d599 100644 --- a/README.md +++ b/README.md @@ -26,13 +26,13 @@ Add the following dependency to your `build.gradle` / `build.gradle.kts` file: For Groovy - `build.gradle`: ```` dependencies { - implementation 'com.github.KvColorPalette:KvColorPalette-Android:2.2.0' + implementation 'com.github.KvColorPalette:KvColorPalette-Android:3.0.0' } ```` For Kotlin DSL - `build.gradle.kts`: ```` dependencies { - implementation("com.github.KvColorPalette:KvColorPalette-Android:2.2.0") + implementation("com.github.KvColorPalette:KvColorPalette-Android:3.0.0") } ```` @@ -60,12 +60,27 @@ KvColorPalette.instance.generateThemeColorSchemePalette(givenColor = MatPackage( ### Advance Usage If you wants to use `KvColorPalette-Android` to generate your theme color palette when your application start-up, then you have to initiate the library in Application level. -To initiate you have to pass one base color that you think your application will use. Use following code to initiate the library package. +There are two ways to initiate the library. These two methods for two different scenarios. First is to initiate the library with one base color and other is to initiate the library with two base colors. +In two color method, there are additional parameters like `bias` and `themeGenPattern`. +If your application styling with one base color then you can use following method to initialized, ```` override fun onCreate() { super.onCreate() // Initialize the KvColorPalette-Android - KvColorPalette.initialize(Color.blue) + KvColorPalette.initialize(baseColor = Color.blue) +} +```` +If your application has two base colors, then you can use following method to initialized, +```` +override fun onCreate() { + super.onCreate() + // Initialize the KvColorPalette-Android + KvColorPalette.initialize( + baseColor = Color.blue, + secondColor = Color.red, + themeGenPattern = ThemeGenMode.BLEND // The way to generate the theme palette using two colors. + bias = 0.5f, // How bias to first or second color + ) } ```` This initiation create a color schemas for a theme using the given color at the initiation. This generated color schemas will available for light and dark theme variants. diff --git a/kv-color-palette/gradle.properties b/kv-color-palette/gradle.properties index f14c3a8..a88d77d 100644 --- a/kv-color-palette/gradle.properties +++ b/kv-color-palette/gradle.properties @@ -1,3 +1,3 @@ kvColorPaletteGroupId=com.github.KvColorPalette kvColorPaletteArtifactId=KvColorPalette-Android -kvColorPaletteVersion=2.2.0 +kvColorPaletteVersion=3.0.0 diff --git a/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/KvColorPalette.kt b/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/KvColorPalette.kt index a92fd8c..6d0137e 100644 --- a/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/KvColorPalette.kt +++ b/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/KvColorPalette.kt @@ -12,9 +12,9 @@ import com.kavi.droid.color.palette.color.Mat800Package import com.kavi.droid.color.palette.color.Mat900Package import com.kavi.droid.color.palette.color.MatPackage import com.kavi.droid.color.palette.extension.hsl -import com.kavi.droid.color.palette.model.AppThemePalette import com.kavi.droid.color.palette.model.ColorSchemeThemePalette import com.kavi.droid.color.palette.model.KvColor +import com.kavi.droid.color.palette.model.ThemeGenMode import com.kavi.droid.color.palette.util.ColorUtil import com.kavi.droid.color.palette.util.ThemeGenUtil @@ -29,32 +29,48 @@ class KvColorPalette { * provide a theme color palette. Consumer can use this as a singleton. */ var instance: KvColorPalette = KvColorPalette() - @Deprecated("This field is deprecated. This is replaced by colorSchemeThemePalette") - lateinit var appThemePalette: AppThemePalette lateinit var colorSchemeThemePalette: ColorSchemeThemePalette /** * KvColorPalette initialization. Consumer can use this to initialize the KvColorPalette from their application, if they need a * Theme color palette at the application start-up. * - * On this initiation of KvColorPalette, we generate a theme color palette using the given color. - * `basicColor` is mandatory parameter while initiate the library. + * On this initiation of KvColorPalette, library generate a theme color palette using the given color. + * `baseColor` is mandatory parameter while initiate the library. * - * @param basicColor: Color: Given color for generate theme palette. + * @param baseColor: Color: Given color for generate theme palette. */ - fun initialize(basicColor: Color) { - val closestColor = ColorUtil.findClosestColor(givenColor = basicColor) - appThemePalette = instance.generateThemeColorPalette(givenColor = closestColor.color) - colorSchemeThemePalette = instance.generateThemeColorSchemePalette(givenColor = closestColor.color) + fun initialize(baseColor: Color) { + colorSchemeThemePalette = instance.generateThemeColorSchemePalette(givenColor = baseColor) } - } - init { /** - * This generate theme-palette with color transparent. This is un-usable. + * KvColorPalette initialization. Consumer can use this to initialize the KvColorPalette from their application, if they need a + * Theme color palette at the application start-up. + * + * On this initiation of KvColorPalette, library generate a theme color palette using the given base color and second color. + * `baseColor` and `secondColor` are mandatory parameter while initiate the library. Other two parameters are optional. + * + * @param baseColor: Color: Given first for generate theme palette. + * @param secondColor: Color: Given second color for generate theme palette. + * @param bias: Float: The bias value to blend the two colors. In default that is 0.5f. This accept float value in a range of 0.0 - 1.0. + * 0f means full bias to first color and 1f means full bias to second color. + * @param themeGenMode: ThemeGenPattern: The pattern to generate the theme color palette. + * Default is [ThemeGenMode.SEQUENCE] and available options are [ThemeGenMode.SEQUENCE] and [ThemeGenMode.BLEND] + * - [ThemeGenMode.SEQUENCE] will add base color & primary & second color as secondary, rest of the colors will generate by using given base color. + * - [ThemeGenMode.BLEND] will add base color & primary & second color as primary, rest of the colors will generate by after generating new color blend first and second colors. */ - appThemePalette = generateThemeColorPalette(Color.Transparent) + fun initialize(baseColor: Color, secondColor: Color, bias: Float = .5f, themeGenMode: ThemeGenMode = ThemeGenMode.SEQUENCE) { + colorSchemeThemePalette = instance.generateMultiColorThemeColorSchemePalette( + givenColor = baseColor, + secondColor = secondColor, + bias = bias, + themeGenMode = themeGenMode + ) + } + } + init { /** * This generate theme-palette with color transparent. This is un-usable. */ @@ -146,25 +162,30 @@ class KvColorPalette { /** * Generate a theme color palette. According to the feeding color, - * this method generate a theme color palette. + * this method generate a color scheme theme color palette. * * @param givenColor The color to generate the theme color palette for. - * @return A theme color palette. + * @return A color scheme theme palette. [ColorSchemeThemePalette] */ - @Deprecated("This method is deprecated and replaced by generateThemeColorSchemePalette method", replaceWith = ReplaceWith( - "KvColorPalette.instance.generateThemeColorSchemePalette(givenColor = givenColor)" - )) - fun generateThemeColorPalette(givenColor: Color): AppThemePalette = ThemeGenUtil.generateThemeColorSet(givenColor = givenColor) + fun generateThemeColorSchemePalette(givenColor: Color): ColorSchemeThemePalette = ThemeGenUtil.singleColorThemeColorScheme(givenColor = givenColor) /** * Generate a theme color palette. According to the feeding color, * this method generate a color scheme theme color palette. * * @param givenColor The color to generate the theme color palette for. + * @param secondColor The secondary color to generate the theme color palette blending with first color. + * @param bias The bias value to blend the two colors. In default that is 0.5f. This accept float value in a range of 0.0 - 1.0. + * 0f means full bias to first color and 1f means full bias to second color. + * @param themeGenMode: ThemeGenPattern: The pattern to generate the theme color palette. + * Default is [ThemeGenMode.SEQUENCE] and available options are [ThemeGenMode.SEQUENCE] and [ThemeGenMode.BLEND] + * - [ThemeGenMode.SEQUENCE] will add base color & primary & second color as secondary, rest of the colors will generate by using given base color. + * - [ThemeGenMode.BLEND] will add base color & primary & second color as primary, rest of the colors will generate by after generating new color blend first and second colors. * @return A color scheme theme palette. [ColorSchemeThemePalette] */ - fun generateThemeColorSchemePalette(givenColor: Color): ColorSchemeThemePalette = ThemeGenUtil.generateThemeColorScheme(givenColor = givenColor) - + fun generateMultiColorThemeColorSchemePalette(givenColor: Color, secondColor: Color, bias: Float = .5f, themeGenMode: ThemeGenMode = ThemeGenMode.SEQUENCE): ColorSchemeThemePalette { + return ThemeGenUtil.multiColorInputThemeColorScheme(givenColor = givenColor, secondColor = secondColor, bias = bias, themeGenMode = themeGenMode) + } /** * This method finds the closest KvColor available in the KvColorPalette-Android to the given color * diff --git a/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/model/ThemeColorPalette.kt b/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/model/ThemeColorPalette.kt index 2318ca6..26f8187 100644 --- a/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/model/ThemeColorPalette.kt +++ b/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/model/ThemeColorPalette.kt @@ -3,17 +3,6 @@ package com.kavi.droid.color.palette.model import androidx.compose.material3.ColorScheme import androidx.compose.ui.graphics.Color -/** - * Application theme palette for light and dark mode. - */ -@Deprecated(message = "This model is deprecated", - ReplaceWith("ColorSchemeThemePalette(lightColorScheme = lightScheme, darkColorScheme = darkScheme)") -) -data class AppThemePalette( - val light: ThemeColorPalette, - val dark: ThemeColorPalette -) - /** * Application [ColorScheme] theme palette for light and dark mode. */ diff --git a/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/model/ThemeGenMode.kt b/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/model/ThemeGenMode.kt new file mode 100644 index 0000000..2ac89b9 --- /dev/null +++ b/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/model/ThemeGenMode.kt @@ -0,0 +1,5 @@ +package com.kavi.droid.color.palette.model + +enum class ThemeGenMode { + SEQUENCE, BLEND +} \ No newline at end of file diff --git a/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/util/ColorUtil.kt b/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/util/ColorUtil.kt index 6d58e4a..49336d4 100644 --- a/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/util/ColorUtil.kt +++ b/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/util/ColorUtil.kt @@ -51,6 +51,21 @@ object ColorUtil { return String.format("#%02x%02x%02x%02x", (color.alpha * 255).toInt(),(color.red * 255).toInt(), (color.green * 255).toInt(), (color.blue * 255).toInt()) } + /** + * This method is to blend given two colors and return new color + * + * @param firstColor [Color] First color to blend + * @param secondColor [Color] Second color to blend + * @param bias [Float] Bias to the new color for first / second color. + */ + internal fun blendColors(firstColor: Color, secondColor: Color, bias: Float = 0.5f): Color { + val blendRed = colorBlendingComponent(firstColor.red, secondColor.red, bias) + val blendGreen = colorBlendingComponent(firstColor.green, secondColor.green, bias) + val blendBlue = colorBlendingComponent(firstColor.blue, secondColor.blue, bias) + + return Color(blendRed / 255, blendGreen / 255, blendBlue / 255) + } + /** * Get closest color to the given color from available color packages. * This compares the available colors and find out the closest `KvColor` to the given color. @@ -130,4 +145,26 @@ object ColorUtil { */ internal fun validateAndReviseColorCount(colorCount: Int): Int = if (colorCount >= 30) { 30 } else if (colorCount <= 1) { 1 } else { colorCount } + + /** + * This method can return the color value of red/green/blue according to the blending bias + * with given first color's red/green/blue value and second color's red/green/blue value. + * + * @param firstColor The first color's red/green/blue value + * @param secondColor The second color's red/green/blue value + * @param bias The blending bias value. + * + */ + private fun colorBlendingComponent(firstColor: Float, secondColor: Float, bias: Float): Float { + val difference = abs(firstColor * 255 - secondColor * 255) + val blending = difference * bias // How bias to the blending colors, first or second + + return if (firstColor < secondColor) { + (firstColor * 255) + blending // First color is in lower end, therefore adding bias + } else if (firstColor > secondColor) { + (firstColor * 255) - blending // First color is in higher end, therefore subtracting bias + } else { + (firstColor * 255) // This means, first component and second component are same. Therefore, returns same value. + } + } } \ No newline at end of file diff --git a/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/util/ThemeGenUtil.kt b/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/util/ThemeGenUtil.kt index 3ce8855..32f07bb 100644 --- a/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/util/ThemeGenUtil.kt +++ b/kv-color-palette/src/main/kotlin/com/kavi/droid/color/palette/util/ThemeGenUtil.kt @@ -8,11 +8,8 @@ import androidx.compose.material3.lightColorScheme import androidx.compose.ui.graphics.Color import com.kavi.droid.color.palette.extension.base import com.kavi.droid.color.palette.extension.hsl -import com.kavi.droid.color.palette.extension.quaternary -import com.kavi.droid.color.palette.extension.shadow -import com.kavi.droid.color.palette.model.AppThemePalette import com.kavi.droid.color.palette.model.ColorSchemeThemePalette -import com.kavi.droid.color.palette.model.ThemeColorPalette +import com.kavi.droid.color.palette.model.ThemeGenMode object ThemeGenUtil { @@ -40,27 +37,39 @@ object ThemeGenUtil { /** * Generate theme color set for given color. * @param givenColor The color to generate theme color set. - * @return A theme color set. [AppThemePalette] + * @return A theme color set. [ColorSchemeThemePalette] */ - @Deprecated( - message = "This method is deprecated and replaced by generateThemeColorScheme.", - replaceWith = ReplaceWith("ThemeGenUtil.generateThemeColorScheme(givenColor = givenColor)") - ) - internal fun generateThemeColorSet(givenColor: Color): AppThemePalette { - val lightColorPalette = generateLightThemeColorSet(givenColor) - val darkColorPalette = generateDarkThemeColorSet(givenColor) + internal fun singleColorThemeColorScheme(givenColor: Color): ColorSchemeThemePalette { + val lightColorPalette = generateThemeLightColorScheme(givenColor) + val darkColorPalette = generateThemeDarkColorScheme(givenColor) - return AppThemePalette(light = lightColorPalette, dark = darkColorPalette) + return ColorSchemeThemePalette(lightColorScheme = lightColorPalette, darkColorScheme = darkColorPalette) } /** - * Generate theme color set for given color. - * @param givenColor The color to generate theme color set. - * @return A theme color set. [ColorSchemeThemePalette] + * Generate a theme color palette. According to the feeding color, + * this method generate a color scheme theme color palette. + * + * @param givenColor The color to generate the theme color palette for. + * @param secondColor The secondary color to generate the theme color palette blending with first color. + * @param bias The bias value to blend the two colors. In default that is 0.5f. This accept float value in a range of 0.0 - 1.0. + * 0f means full bias to first color and 1f means full bias to second color. + * @param themeGenMode: ThemeGenPattern: The pattern to generate the theme color palette. + * Default is [ThemeGenMode.SEQUENCE] and available options are [ThemeGenMode.SEQUENCE] and [ThemeGenMode.BLEND] + * - [ThemeGenMode.SEQUENCE] will add base color & primary & second color as secondary, rest of the colors will generate by using given base color. + * - [ThemeGenMode.BLEND] will add base color & primary & second color as primary, rest of the colors will generate by after generating new color blend first and second colors. + * @return A color scheme theme palette. [ColorSchemeThemePalette] */ - internal fun generateThemeColorScheme(givenColor: Color): ColorSchemeThemePalette { - val lightColorPalette = generateThemeLightColorScheme(givenColor) - val darkColorPalette = generateThemeDarkColorScheme(givenColor) + internal fun multiColorInputThemeColorScheme(givenColor: Color, secondColor: Color, bias: Float = 0.5f, themeGenMode: ThemeGenMode = ThemeGenMode.SEQUENCE): ColorSchemeThemePalette { + var blendColor: Color? = null + + blendColor = when (themeGenMode) { + ThemeGenMode.SEQUENCE -> { null } + ThemeGenMode.BLEND -> { ColorUtil.blendColors(firstColor = givenColor, secondColor = secondColor, bias = bias) } + } + + val lightColorPalette = generateMultiInputThemeLightColorScheme(givenColor = givenColor, secondColor = secondColor, blendColor = blendColor, themeGenMode = themeGenMode) + val darkColorPalette = generateMultiInputThemeDarkColorScheme(givenColor = givenColor, secondColor = secondColor, blendColor = blendColor, themeGenMode = themeGenMode) return ColorSchemeThemePalette(lightColorScheme = lightColorPalette, darkColorScheme = darkColorPalette) } @@ -81,29 +90,6 @@ object ThemeGenUtil { internal fun generateDarkQuaternaryColor(givenColor: Color): Color = generateDarkSecondaryColor(givenColor) - /** - * Generate light theme color set for given color. - * @param givenColor The color to generate theme color set. - * @return A light theme color set. [ThemeColorPalette] - */ - @Deprecated( - message = "This method is deprecated and replaced by generateThemeLightColorScheme.", - replaceWith = ReplaceWith("ThemeGenUtil.generateThemeLightColorScheme(givenColor = givenColor)") - ) - private fun generateLightThemeColorSet(givenColor: Color): ThemeColorPalette { - return ThemeColorPalette( - base = givenColor, - primary = givenColor, - secondary = generateLightSecondaryColor(givenColor), - tertiary = generateLightTertiaryColor(givenColor), - quaternary = givenColor, // This is for use light theme primary color dark theme contrast color - background = generateLightBackgroundColor(givenColor), - onPrimary = Color.White, - onSecondary = Color.White, - shadow = Color.Gray - ) - } - /** * Generate light theme color set for given color. * @param givenColor The color to generate theme color set. @@ -124,26 +110,42 @@ object ThemeGenUtil { } /** - * Generate dark theme color set for given color. - * @param givenColor he color to generate theme color set. - * @return A dark theme color set. [ThemeColorPalette] - */ - @Deprecated( - message = "This method is deprecated and replaced by generateThemeDarkColorScheme.", - replaceWith = ReplaceWith("ThemeGenUtil.generateThemeDarkColorScheme(givenColor = givenColor)") - ) - private fun generateDarkThemeColorSet(givenColor: Color): ThemeColorPalette { - return ThemeColorPalette( - base = givenColor, - primary = generateDarkPrimaryColor(givenColor), - secondary = generateDarkSecondaryColor(givenColor), - tertiary = generateDarkTertiaryColor(givenColor), - quaternary = generateDarkSecondaryColor(givenColor), // This is for use light theme primary color dark theme contrast color - background = generateDarkBackgroundColor(givenColor), - onPrimary = Color.White, - onSecondary = Color.Black, - shadow = Color.White - ) + * Generate light theme color set for given colors. + * @param givenColor The color to generate the theme color palette for. + * @param secondColor The secondary color to generate the theme color palette blending with first color. + * @param themeGenMode: ThemeGenPattern: The pattern to generate the theme color palette. + * @return A light theme color set. [ColorScheme] + */ + private fun generateMultiInputThemeLightColorScheme(givenColor: Color, secondColor: Color, blendColor: Color? = null, themeGenMode: ThemeGenMode = ThemeGenMode.SEQUENCE): ColorScheme { + when (themeGenMode) { + ThemeGenMode.SEQUENCE -> { + val light = lightColorScheme( + primary = givenColor, + secondary = secondColor, + tertiary = generateLightTertiaryColor(givenColor), + background = generateLightBackgroundColor(givenColor), + onPrimary = Color.White, + onSecondary = Color.White + ) + light.base = givenColor + + return light + } + ThemeGenMode.BLEND -> { + val blend = blendColor ?: run { givenColor } + val light = lightColorScheme( + primary = givenColor, + secondary = secondColor, + tertiary = generateLightTertiaryColor(blend), + background = generateLightBackgroundColor(blend), + onPrimary = Color.White, + onSecondary = Color.White + ) + light.base = blend + + return light + } + } } /** @@ -166,6 +168,45 @@ object ThemeGenUtil { return darkColorScheme } + /** + * Generate dark theme color set for given color. + * @param givenColor The color to generate the theme color palette for. + * @param secondColor The secondary color to generate the theme color palette blending with first color. + * @param themeGenMode: ThemeGenPattern: The pattern to generate the theme color palette. + * @return A dark theme color set. [ColorScheme] + */ + private fun generateMultiInputThemeDarkColorScheme(givenColor: Color, secondColor: Color, blendColor: Color? = null, themeGenMode: ThemeGenMode = ThemeGenMode.SEQUENCE): ColorScheme { + when (themeGenMode) { + ThemeGenMode.SEQUENCE -> { + val dark = darkColorScheme( + primary = generateDarkPrimaryColor(givenColor), + secondary = generateDarkSecondaryColor(secondColor), + tertiary = generateDarkTertiaryColor(givenColor), + background = generateDarkBackgroundColor(givenColor), + onPrimary = Color.White, + onSecondary = Color.White, + ) + dark.base = givenColor + + return dark + } + ThemeGenMode.BLEND -> { + val blend = blendColor ?: run { givenColor } + val dark = darkColorScheme( + primary = generateDarkPrimaryColor(givenColor), + secondary = generateDarkSecondaryColor(secondColor), + tertiary = generateDarkTertiaryColor(blend), + background = generateDarkBackgroundColor(blend), + onPrimary = Color.White, + onSecondary = Color.White, + ) + dark.base = blend + + return dark + } + } + } + /** * Generate light secondary color for given color. */