using Azimuth; using Annulus; using Blacklight.Core; using Glass.Blacklight; using System; using System.Drawing; namespace Glass.Testbed { /// /// A flat fill that cycles through the rainbow by age. /// public record RainbowMaterial : Material { public Scalar SecondsPerCycle { get; init; } = 4; private static readonly SolidColorMaterial Fill = new SolidColorMaterial(); /// /// Red at zero, running through the spectrum and back. A hue sweep at full saturation rather than three /// phase-shifted sines, which never fully clear a channel and so wash out to pastels. /// public static System.Drawing.Color ColorAt(TimeSpan age, Scalar secondsPerCycle) { double turns = age.TotalSeconds / secondsPerCycle; // Floor rather than % so a negative age wraps forwards instead of mirroring. double hue = 6 * (turns - Math.Floor(turns)); int segment = Math.Min(5, (int)hue); int ramp = (int)Math.Round(255 * (1 - Math.Abs(hue % 2 - 1))); switch (segment) { case 0: return System.Drawing.Color.FromArgb(255, ramp, 0); case 1: return System.Drawing.Color.FromArgb(ramp, 255, 0); case 2: return System.Drawing.Color.FromArgb(0, 255, ramp); case 3: return System.Drawing.Color.FromArgb(0, ramp, 255); case 4: return System.Drawing.Color.FromArgb(ramp, 0, 255); default: return System.Drawing.Color.FromArgb(255, 0, ramp); } } public static void Render(Renderer renderer, Cel context, RainbowMaterial material, Rect rect, DrawState drawState) { drawState.TintColor = ColorAt(drawState.Age, material.SecondsPerCycle); renderer.Render(context, Fill, rect, drawState); } } }