1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-11-22 04:53:29 +01:00

Added ColorExtensions.ToHsl and ColorHelper.FromHsl

This commit is contained in:
Ell 2024-07-29 19:57:33 +02:00
parent dd3fc6b85d
commit 943a9cbd77
3 changed files with 118 additions and 2 deletions

View file

@ -16,7 +16,9 @@ Jump to version:
## 7.0.1 (In Development) ## 7.0.1 (In Development)
No code changes ### MLEM
Additions
- Added ColorExtensions.ToHsl and ColorHelper.FromHsl
## 7.0.0 ## 7.0.0

View file

@ -58,6 +58,39 @@ namespace MLEM.Graphics {
return $"{(hash ? "#" : string.Empty)}{color.R:X2}{color.G:X2}{color.B:X2}"; return $"{(hash ? "#" : string.Empty)}{color.R:X2}{color.G:X2}{color.B:X2}";
} }
/// <summary>
/// Converts the given <paramref name="color"/> into HSL representation and returns the result as a value tuple with values between 0 and 1.
/// </summary>
/// <remarks>This code is adapted from https://gist.github.com/mjackson/5311256.</remarks>
/// <param name="color">The color to convert.</param>
/// <returns>The resulting HSL color as a value tuple containing H, S and L, each between 0 and 1.</returns>
public static (float H, float S, float L) ToHsl(this Color color) {
var r = color.R / 255F;
var g = color.G / 255F;
var b = color.B / 255F;
var max = Math.Max(Math.Max(r, g), b);
var min = Math.Min(Math.Min(r, g), b);
float h, s, l = (max + min) / 2;
if (max == min) {
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5F ? d / (2 - max - min) : d / (max + min);
if (r == max) {
h = (g - b) / d + (g < b ? 6 : 0);
} else if (g == max) {
h = (b - r) / d + 2;
} else {
h = (r - g) / d + 4;
}
h /= 6;
}
return (h, s, l);
}
} }
/// <summary> /// <summary>
@ -116,5 +149,54 @@ namespace MLEM.Graphics {
return false; return false;
} }
/// <summary>
///Converts the given HSL color to an RGB <see cref="Color"/> and returns the result.
/// </summary>
/// <remarks>This code is adapted from https://gist.github.com/mjackson/5311256.</remarks>
/// <param name="color">The HSL color to convert, as a value tuple that contains H, S and L values, each between 0 and 1.</param>
/// <returns>The resulting RGB color.</returns>
public static Color FromHsl((float H, float S, float L) color) {
return ColorHelper.FromHsl(color.H, color.S, color.L);
}
/// <summary>
///Converts the given HSL values to an RGB <see cref="Color"/> and returns the result.
/// </summary>
/// <remarks>This code is adapted from https://gist.github.com/mjackson/5311256.</remarks>
/// <param name="h">The H component of the HSL color, between 0 and 1.</param>
/// <param name="s">The S component of the HSL color, between 0 and 1.</param>
/// <param name="l">The L component of the HSL color, between 0 and 1.</param>
/// <returns>The resulting RGB color.</returns>
public static Color FromHsl(float h, float s, float l) {
float r, g, b;
if (s == 0) {
r = g = b = l; // achromatic
} else {
var q = l < 0.5F ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = ColorHelper.HueToRgb(p, q, h + 1 / 3F);
g = ColorHelper.HueToRgb(p, q, h);
b = ColorHelper.HueToRgb(p, q, h - 1 / 3F);
}
return new Color(r, g, b);
}
private static float HueToRgb(float p, float q, float t) {
if (t < 0)
t += 1;
if (t > 1)
t -= 1;
if (t < 1 / 6F)
return p + (q - p) * 6 * t;
if (t < 1 / 2F)
return q;
if (t < 2 / 3F)
return p + (q - p) * (2 / 3F - t) * 6;
return p;
}
} }
} }

View file

@ -19,6 +19,7 @@ using MLEM.Textures;
using MLEM.Ui; using MLEM.Ui;
using MLEM.Ui.Elements; using MLEM.Ui.Elements;
using MLEM.Ui.Style; using MLEM.Ui.Style;
using Group = MLEM.Ui.Elements.Group;
namespace Sandbox; namespace Sandbox;
@ -87,6 +88,7 @@ public class GameImpl : MlemGame {
this.SpriteBatch.End(); this.SpriteBatch.End();
};*/ };*/
/*
var panel = new Panel(Anchor.Center, new Vector2(0, 100), Vector2.Zero) {SetWidthBasedOnChildren = true}; var panel = new Panel(Anchor.Center, new Vector2(0, 100), Vector2.Zero) {SetWidthBasedOnChildren = true};
panel.AddChild(new Button(Anchor.AutoLeft, new Vector2(100, 10))); panel.AddChild(new Button(Anchor.AutoLeft, new Vector2(100, 10)));
panel.AddChild(new Button(Anchor.AutoCenter, new Vector2(80, 10))); panel.AddChild(new Button(Anchor.AutoCenter, new Vector2(80, 10)));
@ -112,17 +114,21 @@ public class GameImpl : MlemGame {
var dir = vec.ToDirection(); var dir = vec.ToDirection();
Console.WriteLine(vec + " -> " + dir); Console.WriteLine(vec + " -> " + dir);
} }
*/
/*
var writer = new StringWriter(); var writer = new StringWriter();
this.Content.GetJsonSerializer().Serialize(writer, obj); this.Content.GetJsonSerializer().Serialize(writer, obj);*/
//Console.WriteLine(writer.ToString()); //Console.WriteLine(writer.ToString());
// {"Vec":"10 20","Point":"20 30","Rectangle":"1 2 3 4","RectangleF":"4 5 6 7"} // {"Vec":"10 20","Point":"20 30","Rectangle":"1 2 3 4","RectangleF":"4 5 6 7"}
// Also: // Also:
//this.Content.AddJsonConverter(new CustomConverter()); //this.Content.AddJsonConverter(new CustomConverter());
/*
var res = this.Content.LoadJson<Test>("Test"); var res = this.Content.LoadJson<Test>("Test");
Console.WriteLine("The res is " + res); Console.WriteLine("The res is " + res);
*/
//var gradient = this.SpriteBatch.GenerateGradientTexture(Color.Green, Color.Red, Color.Blue, Color.Yellow); //var gradient = this.SpriteBatch.GenerateGradientTexture(Color.Green, Color.Red, Color.Blue, Color.Yellow);
/*this.OnDraw += (game, time) => { /*this.OnDraw += (game, time) => {
@ -139,6 +145,7 @@ public class GameImpl : MlemGame {
this.SpriteBatch.End(); this.SpriteBatch.End();
};*/ };*/
/*
var sc = 2; var sc = 2;
var formatter = new TextFormatter(); var formatter = new TextFormatter();
formatter.AddImage("Test", new TextureRegion(tex, 0, 8, 24, 24)); formatter.AddImage("Test", new TextureRegion(tex, 0, 8, 24, 24));
@ -185,6 +192,7 @@ public class GameImpl : MlemGame {
} }
this.tokenized.Update(time); this.tokenized.Update(time);
}; };
*/
/*var testPanel = new Panel(Anchor.Center, new Vector2(0.5F, 100), Vector2.Zero); /*var testPanel = new Panel(Anchor.Center, new Vector2(0.5F, 100), Vector2.Zero);
testPanel.AddChild(new Button(Anchor.AutoLeft, new Vector2(0.25F, -1))); testPanel.AddChild(new Button(Anchor.AutoLeft, new Vector2(0.25F, -1)));
@ -225,6 +233,7 @@ public class GameImpl : MlemGame {
par.OnDrawn = (e, time, batch, a) => batch.DrawRectangle(e.DisplayArea.ToExtended(), Color.Red); par.OnDrawn = (e, time, batch, a) => batch.DrawRectangle(e.DisplayArea.ToExtended(), Color.Red);
this.UiSystem.Add("Load", loadGroup);*/ this.UiSystem.Add("Load", loadGroup);*/
/*
var spillPanel = new Panel(Anchor.Center, new Vector2(100), Vector2.Zero); var spillPanel = new Panel(Anchor.Center, new Vector2(100), Vector2.Zero);
var squishingGroup = spillPanel.AddChild(new SquishingGroup(Anchor.TopLeft, Vector2.One)); var squishingGroup = spillPanel.AddChild(new SquishingGroup(Anchor.TopLeft, Vector2.One));
squishingGroup.AddChild(new Button(Anchor.TopLeft, new Vector2(30), "TL") { squishingGroup.AddChild(new Button(Anchor.TopLeft, new Vector2(30), "TL") {
@ -293,6 +302,7 @@ public class GameImpl : MlemGame {
} }
this.SpriteBatch.End(); this.SpriteBatch.End();
}; };
*/
/*var viewport = new BoxingViewportAdapter(this.Window, this.GraphicsDevice, 1280, 720); /*var viewport = new BoxingViewportAdapter(this.Window, this.GraphicsDevice, 1280, 720);
var newPanel = new Panel(Anchor.TopLeft, new Vector2(200, 100), new Vector2(10, 10)); var newPanel = new Panel(Anchor.TopLeft, new Vector2(200, 100), new Vector2(10, 10));
@ -387,6 +397,28 @@ public class GameImpl : MlemGame {
Console.WriteLine("MouseButtons: " + string.Join(", ", GenericInput.AllMouseButtons)); Console.WriteLine("MouseButtons: " + string.Join(", ", GenericInput.AllMouseButtons));
Console.WriteLine("Buttons: " + string.Join(", ", GenericInput.AllButtons)); Console.WriteLine("Buttons: " + string.Join(", ", GenericInput.AllButtons));
Console.WriteLine("Inputs: " + string.Join(", ", GenericInput.AllInputs));*/ Console.WriteLine("Inputs: " + string.Join(", ", GenericInput.AllInputs));*/
var hsl = new Panel(Anchor.Center, new Vector2(100), true);
var color = Color.Pink.ToHsl();
hsl.AddChild(new Paragraph(Anchor.AutoLeft, 1, "H"));
hsl.AddChild(new Slider(Anchor.AutoLeft, new Vector2(1, 10), 5, 1) {
CurrentValue = color.H,
OnValueChanged = (_, v) => color.H = v
});
hsl.AddChild(new Paragraph(Anchor.AutoLeft, 1, "S"));
hsl.AddChild(new Slider(Anchor.AutoLeft, new Vector2(1, 10), 5, 1) {
CurrentValue = color.S,
OnValueChanged = (_, v) => color.S = v
});
hsl.AddChild(new Paragraph(Anchor.AutoLeft, 1, "L"));
hsl.AddChild(new Slider(Anchor.AutoLeft, new Vector2(1, 10), 5, 1) {
CurrentValue = color.L,
OnValueChanged = (_, v) => color.L = v
});
hsl.AddChild(new Group(Anchor.AutoLeft, new Vector2(1, 40), false) {
OnDrawn = (e, _, batch, _, _) => batch.Draw(batch.GetBlankTexture(), e.DisplayArea, ColorHelper.FromHsl(color))
});
this.UiSystem.Add("HSL", hsl);
} }
protected override void DoUpdate(GameTime gameTime) { protected override void DoUpdate(GameTime gameTime) {