From 4ee4857b105798f9eeeacfd44722df6ea31a4849 Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 12 May 2022 23:01:45 +0200 Subject: [PATCH] Core - Added timesToRepeat and seamless arguments to GetColor Core - Optimized GetColorsArray --- .../Models/Profile/Colors/ColorGradient.cs | 58 ++++++++++++------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs b/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs index c621eb5c7..bdda754a0 100644 --- a/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs +++ b/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs @@ -54,9 +54,8 @@ namespace Artemis.Core } else { - List colors = this.Select(c => c.Color).ToList(); for (int i = 0; i <= timesToRepeat; i++) - result.AddRange(colors); + result.AddRange(this.Select(c => c.Color)); } if (seamless && !IsSeamless()) @@ -68,9 +67,7 @@ namespace Artemis.Core /// /// Gets all the positions in the color gradient /// - /// - /// The amount of times to repeat the positions - /// + /// The amount of times to repeat the positions /// /// A boolean indicating whether to make the gradient seamless by adding the first color behind the /// last color @@ -113,19 +110,30 @@ namespace Artemis.Core /// Gets a color at any position between 0.0 and 1.0 using interpolation /// /// A position between 0.0 and 1.0 - public SKColor GetColor(float position) + /// The amount of times to repeat the positions + /// + /// A boolean indicating whether to make the gradient seamless by adding the first color behind the + /// last color + /// + public SKColor GetColor(float position, int timesToRepeat = 0, bool seamless = false) { if (!this.Any()) - return SKColor.Empty; + return new SKColor(255, 255, 255); - ColorGradientStop[] stops = this.ToArray(); - if (position <= 0) return stops[0].Color; - if (position >= 1) return stops[^1].Color; - ColorGradientStop left = stops[0]; - ColorGradientStop? right = null; - foreach (ColorGradientStop stop in stops) + SKColor[] colors = GetColorsArray(timesToRepeat, seamless); + float[] stops = GetPositionsArray(timesToRepeat, seamless); + + // If at or over the edges, return the corresponding edge + if (position <= 0) return colors[0]; + if (position >= 1) return colors[^1]; + + // Walk through the stops until we find the one at or after the requested position, that becomes the right stop + // The left stop is the previous stop before the right one was found. + float left = stops[0]; + float? right = null; + foreach (float stop in stops) { - if (stop.Position >= position) + if (stop >= position) { right = stop; break; @@ -134,14 +142,22 @@ namespace Artemis.Core left = stop; } - if (right == null || left == right) - return left.Color; + // Get the left stop's color + SKColor leftColor = colors[Array.IndexOf(stops, left)]; - position = (float) Math.Round((position - left.Position) / (right.Position - left.Position), 2); - byte a = (byte) ((right.Color.Alpha - left.Color.Alpha) * position + left.Color.Alpha); - byte r = (byte) ((right.Color.Red - left.Color.Red) * position + left.Color.Red); - byte g = (byte) ((right.Color.Green - left.Color.Green) * position + left.Color.Green); - byte b = (byte) ((right.Color.Blue - left.Color.Blue) * position + left.Color.Blue); + // If no right stop was found or the left and right stops are on the same spot, return the left stop's color + if (right == null || left == right) + return leftColor; + + // Get the right stop's color + SKColor rightColor = colors[Array.IndexOf(stops, right)]; + + // Interpolate the position between the left and right color + position = MathF.Round((position - left) / (right.Value - left), 2); + byte a = (byte) ((rightColor.Alpha - leftColor.Alpha) * position + leftColor.Alpha); + byte r = (byte) ((rightColor.Red - leftColor.Red) * position + leftColor.Red); + byte g = (byte) ((rightColor.Green - leftColor.Green) * position + leftColor.Green); + byte b = (byte) ((rightColor.Blue - leftColor.Blue) * position + leftColor.Blue); return new SKColor(r, g, b, a); }