From 2c3e64c58880f449d4803d2b369c2c203d1b0bdb Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 29 Mar 2021 19:46:30 +0200 Subject: [PATCH] Color gradients - Added API for requesting a seamless gradient --- .../Models/Profile/Colors/ColorGradient.cs | 79 +++++++++++++------ 1 file changed, 55 insertions(+), 24 deletions(-) diff --git a/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs b/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs index 06cdab520..4f630fcda 100644 --- a/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs +++ b/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs @@ -40,17 +40,24 @@ namespace Artemis.Core /// Gets all the colors in the color gradient /// /// The amount of times to repeat the colors - /// - public SKColor[] GetColorsArray(int timesToRepeat = 0) + /// + /// A boolean indicating whether to make the gradient seamless by adding the first color behind the + /// last color + /// + /// An array containing each color in the gradient + public SKColor[] GetColorsArray(int timesToRepeat = 0, bool seamless = false) { - if (timesToRepeat == 0) - return Stops.Select(c => c.Color).ToArray(); - - List colors = Stops.Select(c => c.Color).ToList(); List result = new(); - - for (int i = 0; i <= timesToRepeat; i++) - result.AddRange(colors); + if (timesToRepeat == 0) + result = Stops.Select(c => c.Color).ToList(); + else + { + List colors = Stops.Select(c => c.Color).ToList(); + for (int i = 0; i <= timesToRepeat; i++) + result.AddRange(colors); + } + if (seamless && !IsSeamless()) + result.Add(result[0]); return result.ToArray(); } @@ -59,24 +66,39 @@ namespace Artemis.Core /// Gets all the positions in the color gradient /// /// - /// The amount of times to repeat the positions, positions will get squished together and - /// always stay between 0.0 and 1.0 + /// The amount of times to repeat the positions /// - /// - public float[] GetPositionsArray(int timesToRepeat = 0) + /// + /// A boolean indicating whether to make the gradient seamless by adding the first color behind the + /// last color + /// + /// An array containing a position for each color between 0.0 and 1.0 + public float[] GetPositionsArray(int timesToRepeat = 0, bool seamless = false) { - if (timesToRepeat == 0) - return Stops.Select(c => c.Position).ToArray(); - - // Create stops and a list of divided stops - List stops = Stops.Select(c => c.Position / (timesToRepeat + 1)).ToList(); List result = new(); - - // For each repeat cycle, add the base stops to the end result - for (int i = 0; i <= timesToRepeat; i++) + if (timesToRepeat == 0) + result = Stops.Select(c => c.Position).ToList(); + else { - List localStops = stops.Select(s => s + result.LastOrDefault()).ToList(); - result.AddRange(localStops); + // Create stops and a list of divided stops + List stops = Stops.Select(c => c.Position / (timesToRepeat + 1)).ToList(); + + // For each repeat cycle, add the base stops to the end result + for (int i = 0; i <= timesToRepeat; i++) + { + float lastStop = result.LastOrDefault(); + result.AddRange(stops.Select(s => s + lastStop)); + } + } + + if (seamless && !IsSeamless()) + { + // Compress current points evenly + float compression = 1f - 1f / result.Count; + for (int index = 0; index < result.Count; index++) + result[index] = result[index] * compression; + // Add one extra point at the end + result.Add(1f); } return result.ToArray(); @@ -140,8 +162,17 @@ namespace Artemis.Core float position = 1f / (FastLedRainbow.Length - 1f) * index; gradient.Stops.Add(new ColorGradientStop(skColor, position)); } - + return gradient; } + + /// + /// Determines whether the gradient is seamless + /// + /// if the gradient is seamless; otherwise + public bool IsSeamless() + { + return Stops.Count == 0 || Stops.First().Color.Equals(Stops.Last().Color); + } } } \ No newline at end of file