【问题标题】:Transition from Green to Red in c#在 C# 中从绿色过渡到红色
【发布时间】:2021-02-26 03:50:58
【问题描述】:

我正在尝试为问答游戏创建一个计时器栏,它会在 10 秒内缩小尺寸并从绿色变为红色。

这是我现有的代码:

                double timerWidth = 600;
                double dblRed = 0;
                double dblGreen = 255;
                int intRed = 0;
                int intGreen = 255;

                for (int t = 1000; t != -1; t--) // gives player 10 seconds to select the right answer
                {
                    string strTime = intTime.ToString();
                    lblTime.Text = strTime;
                    intTime--;
                    int intTimerWidth = Convert.ToInt32(timerWidth);
                    imgTimer.Size = new Size(intTimerWidth, 30);
                    dblRed = dblRed + 0.23;
                    dblGreen = dblGreen - 0.23;
                    intRed = Convert.ToInt32(dblRed);
                    intGreen = Convert.ToInt32(dblGreen);
                    imgTimer.BackColor = Color.FromArgb(intRed, intGreen, 0);

                    wait(1); // wait 0.001 seconds
                    timerWidth = timerWidth - 0.6;

                    if (intTime == 0)
                    {
                        checkAnswer(); // when 10 seconds has ellapsed, ellapsed, checks answer

                    }
                }

它在当前起作用,但使用 RGB 它会从绿色变为棕色再变为红色,这显然不是预期的效果。我希望可以通过 HSL 实现从绿色到黄色、橙色再到红色,但我不知道如何转换。

希望我已经问过了,我不常去这些论坛。

谢谢!

【问题讨论】:

标签: c# winforms


【解决方案1】:

这是用于在 RGB 和 HSL 值之间转换的库类 - 我创建了自己的 RGB 和 HSL 颜色类,以便这些例程可以在 Winforms 和 WPF 中使用

public static class perColorConverter
{
    public static perHsla ToHsl(this perRgba rgba)
    {
        return RgbToHsl(rgba.Red, rgba.Green, rgba.Blue, rgba.Alpha);
    }

    public static perHsla RgbToHsl(byte red, byte green, byte blue, byte alpha = 255)
    {
        var min = Math.Min(Math.Min(red, green), blue);
        var max = Math.Max(Math.Max(red, green), blue);
        var delta = Convert.ToSingle(max - min);

        var luminosity = (max + min) / 510f;

        if (Math.Abs(delta) < 0.001f)
        {
            return new perHsla(0f, 0f, luminosity);
        }

        float hue;
        var saturation = luminosity < 0.5
            ? delta / (max + min)
            : delta / (510 - max - min);

        if (red == max)
        {
            hue = (green - blue) / delta;
        }
        else if (green == max)
        {
            hue = 2f + (blue - red) / delta;
        }
        else
        {
            hue = 4f + (red - green) / delta;
        }

        return new perHsla(hue * 60f, saturation, luminosity, alpha);
    }

    public static perRgba ToRgb(this perHsla hsla)
    {
        return HslToRgb(hsla.Hue, hsla.Saturation, hsla.Luminosity, hsla.Alpha);
    }

    public static perRgba HslToRgb(float hue, float saturation, float luminosity)
    {
        return HslToRgb(hue, saturation, luminosity, 255);
    }

    public static perRgba HslToRgb(float hue, float saturation, float luminosity, byte alpha)
    {
        byte red, green, blue;

        // zero saturation => some shade of grey
        if (Math.Abs(saturation) < 0.001f)
        {
            red = Convert.ToByte(luminosity * 255);
            green = red;
            blue = red;
        }
        else
        {
            var t2 = luminosity < 0.5f
                ? luminosity * (1.0f + saturation)
                : luminosity + saturation - (luminosity * saturation);
            var t1 = (2 * luminosity) - t2;

            red = HueToRgb(t1, t2, hue + 120);
            green = HueToRgb(t1, t2, hue);
            blue = HueToRgb(t1, t2, hue - 120);
        }

        return new perRgba(red, green, blue, alpha);
    }

    private static byte HueToRgb(float t1, float t2, float hue)
    {
        while (hue >= 360)
        {
            hue -= 360;
        }

        while (hue < 0)
        {
            hue += 360;
        }

        float x;
        if (hue < 60)
        {
            x = t1 + (t2 - t1) * hue / 60;
        }
        else if (hue < 180)
        {
            x = t2;
        }
        else if (hue < 240)
        {
            x = t1 + (t2 - t1) * (240 - hue) / 60;
        }
        else
        {
            x = t1;
        }

        return Convert.ToByte(x * 255);
    }
}

根据您的要求,生成适当的开始和结束 HSL 值,并使用线性插值计算过渡的每个步骤的色相、饱和度和亮度值,您可以将其转换为等效的 RGB 值。

我的blog post 上有关 HSL 使用的更多详细信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-08
    • 2014-06-18
    • 1970-01-01
    • 2013-09-27
    • 1970-01-01
    • 2021-07-07
    • 2017-05-28
    • 2011-05-08
    相关资源
    最近更新 更多