Skip to content

Commit

Permalink
Add color interpolation helper.
Browse files Browse the repository at this point in the history
  • Loading branch information
nightm4re94 committed Aug 6, 2023
1 parent cf2242f commit 096bec1
Showing 1 changed file with 38 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.logging.Logger;

public final class ColorHelper {

private static final Logger log = Logger.getLogger(ColorHelper.class.getName());
private static final int HEX_STRING_LENGTH = 7;
private static final int HEX_STRING_LENGTH_ALPHA = 9;
Expand All @@ -21,13 +22,12 @@ private ColorHelper() {
* <li>#RRGGBB - For colors without alpha
* <li>#AARRGGBB - For colors with alpha
* </ul>
*
* <p>
* Examples: <br>
* {@code Color.RED} = "#ff0000"<br>
* {@code new Color(255, 0, 0, 200)} = "#c8ff0000"
*
* @param color
* The color that is encoded.
* @param color The color that is encoded.
* @return An hexadecimal string representation of the specified color.
* @see ColorHelper#decode(String)
* @see Color
Expand All @@ -48,7 +48,8 @@ public static String encode(Color color) {
}

/**
* Decodes the specified color string to an actual {@code Color} instance. The accepted format is:
* Decodes the specified color string to an actual {@code Color} instance. The accepted format
* is:
* <p>
* <i>Note: This returns null if the format of the provided color string is invalid.</i>
* </p>
Expand All @@ -57,13 +58,12 @@ public static String encode(Color color) {
* <li>#RRGGBB - For colors without alpha
* <li>#AARRGGBB - For colors with alpha
* </ul>
*
* <p>
* Examples: <br>
* "#ff0000" = {@code Color.RED}<br>
* "#c8ff0000" = {@code new Color(255, 0, 0, 200)}
*
* @param colorHexString
* The hexadecimal encodes color string representation.
* @param colorHexString The hexadecimal encodes color string representation.
* @return The decoded color.
* @see ColorHelper#encode(Color)
* @see Color
Expand All @@ -81,13 +81,13 @@ public static Color decode(String colorHexString, boolean solid) {

if (!colorHexString.startsWith("#")) {
if (colorHexString.length() == HEX_STRING_LENGTH - 1
|| colorHexString.length() == HEX_STRING_LENGTH_ALPHA - 1) {
|| colorHexString.length() == HEX_STRING_LENGTH_ALPHA - 1) {
colorHexString = "#" + colorHexString;
} else {
log.log(
Level.SEVERE,
"Could not parse color string \"{0}\". A color string needs to start with a \"#\" character.",
colorHexString);
Level.SEVERE,
"Could not parse color string \"{0}\". A color string needs to start with a \"#\" character.",
colorHexString);
return null;
}
}
Expand All @@ -99,33 +99,31 @@ public static Color decode(String colorHexString, boolean solid) {
return decodeHexStringWithAlpha(colorHexString, solid);
default:
log.log(
Level.SEVERE,
"Could not parse color string \"{0}\". Invalid string length \"{1}\"!\nAccepted lengths:\n\t{2} for Colors without Alpha (#ff0000)\n\t{3} for Colors with Alpha (#c8ff0000)",
new Object[] {
colorHexString, colorHexString.length(), HEX_STRING_LENGTH, HEX_STRING_LENGTH_ALPHA
});
Level.SEVERE,
"Could not parse color string \"{0}\". Invalid string length \"{1}\"!\nAccepted lengths:\n\t{2} for Colors without Alpha (#ff0000)\n\t{3} for Colors with Alpha (#c8ff0000)",
new Object[]{
colorHexString, colorHexString.length(), HEX_STRING_LENGTH, HEX_STRING_LENGTH_ALPHA
});
return null;
}
}

/**
* Ensures that the specified value lies within the accepted range for Color values (0-255). Smaller values will be
* forced to be 0 and larger values will result in 255.
* Ensures that the specified value lies within the accepted range for Color values (0-255).
* Smaller values will be forced to be 0 and larger values will result in 255.
*
* @param value
* The value to check for.
* @param value The value to check for.
* @return An integer value that fits the color value restrictions.
*/
public static int ensureColorValueRange(float value) {
return ensureColorValueRange(Math.round(value));
}

/**
* Ensures that the specified value lies within the accepted range for Color values (0-255). Smaller values will be
* forced to be 0 and larger values will result in 255.
* Ensures that the specified value lies within the accepted range for Color values (0-255).
* Smaller values will be forced to be 0 and larger values will result in 255.
*
* @param value
* The value to check for.
* @param value The value to check for.
* @return An integer value that fits the color value restrictions.
*/
public static int ensureColorValueRange(int value) {
Expand All @@ -135,23 +133,33 @@ public static int ensureColorValueRange(int value) {
/**
* Premultiplies the alpha on the given color.
*
* @param color
* The color to premultiply
* @param color The color to premultiply
* @return The color given, with alpha replaced with a black background.
*/
public static Color premultiply(Color color) {
if (color.getAlpha() == 255) {
return color;
}
return new Color(
premultiply(color.getRed(), color.getAlpha()),
premultiply(color.getGreen(), color.getAlpha()),
premultiply(color.getBlue(), color.getAlpha()));
premultiply(color.getRed(), color.getAlpha()),
premultiply(color.getGreen(), color.getAlpha()),
premultiply(color.getBlue(), color.getAlpha()));
}

public static Color interpolate(Color color1, Color color2, double factor) {
factor = MathUtilities.clamp(factor, 0, 1);

int r = (int) (color1.getRed() * (1 - factor) + color2.getRed() * factor);
int g = (int) (color1.getGreen() * (1 - factor) + color2.getGreen() * factor);
int b = (int) (color1.getBlue() * (1 - factor) + color2.getBlue() * factor);
int a = (int) (color1.getAlpha() * (1 - factor) + color2.getAlpha() * factor);

return new Color(r, g, b, a);
}

public static Color getTransparentVariant(Color color, int newAlpha) {
return new Color(
color.getRed(), color.getGreen(), color.getBlue(), ensureColorValueRange(newAlpha));
color.getRed(), color.getGreen(), color.getBlue(), ensureColorValueRange(newAlpha));
}

private static Color decodeWellformedHexString(String hexString) {
Expand Down

0 comments on commit 096bec1

Please sign in to comment.