Last active
June 9, 2024 15:15
-
-
Save elkraneo/cac508c753923724c5d1b21fae7f411e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension Measurement where UnitType == UnitTemperature { | |
var color: Color { | |
/// Convert input temperature to Celsius for consistency | |
let temperatureInCelsius = self.converted(to: .celsius) | |
/// Find the two closest color values in Celsius | |
var lowerIndex = 0 | |
var upperIndex = 0 | |
for i in 0..<colorSteps.count { | |
let stepTemperatureInCelsius = colorSteps[i].temperature.converted(to: .celsius) | |
if stepTemperatureInCelsius <= temperatureInCelsius { | |
lowerIndex = i | |
} | |
if stepTemperatureInCelsius >= temperatureInCelsius { | |
upperIndex = i | |
break | |
} | |
} | |
/// Interpolate the color in the HSBA color space | |
let lowerValue = colorSteps[lowerIndex].temperature.converted(to: .celsius) | |
let lowerColor = colorSteps[lowerIndex].color | |
let upperValue = colorSteps[upperIndex].temperature.converted(to: .celsius) | |
let upperColor = colorSteps[upperIndex].color | |
let progress: Double | |
if upperValue == lowerValue { | |
progress = 0.5 // Set progress to 0.5 if the values are the same | |
} else { | |
progress = (temperatureInCelsius - lowerValue).value / (upperValue - lowerValue).value | |
} | |
/// Interpolating hue with wrap-around handling | |
/// When interpolating between two hue values, ensure that you take the shortest path around the color wheel. | |
let deltaHue = upperColor.hue - lowerColor.hue | |
let interpolatedHue: Double | |
if deltaHue > 0.5 { | |
interpolatedHue = lowerColor.hue + (deltaHue - 1.0) * progress | |
} else if deltaHue < -0.5 { | |
interpolatedHue = lowerColor.hue + (deltaHue + 1.0) * progress | |
} else { | |
interpolatedHue = lowerColor.hue + deltaHue * progress | |
} | |
/// Wrap the hue around | |
let wrappedHue = interpolatedHue.truncatingRemainder(dividingBy: 1.0) | |
let interpolatedSaturation = | |
lowerColor.saturation + (upperColor.saturation - lowerColor.saturation) * progress | |
let interpolatedBrightness = | |
lowerColor.brightness + (upperColor.brightness - lowerColor.brightness) * progress | |
let interpolatedAlpha = lowerColor.alpha + (upperColor.alpha - lowerColor.alpha) * progress | |
return Color( | |
hue: wrappedHue, | |
saturation: interpolatedSaturation, | |
brightness: interpolatedBrightness, | |
opacity: interpolatedAlpha | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment