Skip to content

Instantly share code, notes, and snippets.

@elkraneo
Last active June 9, 2024 15:15
Show Gist options
  • Save elkraneo/cac508c753923724c5d1b21fae7f411e to your computer and use it in GitHub Desktop.
Save elkraneo/cac508c753923724c5d1b21fae7f411e to your computer and use it in GitHub Desktop.
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