簡體   English   中英

Wpf ArcSegment 具有 3 種顏色漸變

[英]Wpf ArcSegment with 3 color gradient

我嘗試在我的 WPF 控件中繪制一個 ArcSegment,該控件用作循環進度條並具有三色漸變。 它應該從 0% 的紅色開始,50% 的黃色和 100% 的綠色。 所以對於 75%,它應該是這樣的:

喜歡是應該看起來像

我用 LinearGradientBrush 試試這個

<Path StrokeThickness="25">
    <Path.Data>
        <PathGeometry>
            <PathFigure StartPoint="50, 12.5">

                <ArcSegment RotationAngle="0" SweepDirection="Clockwise"
                            IsLargeArc="true"
                            Point="12.5, 75" 
                            Size="62.5, 62.5">
                </ArcSegment>
            </PathFigure>
        </PathGeometry>
    </Path.Data>
    <Path.Stroke>
        <LinearGradientBrush StartPoint="0, 0.5" EndPoint="1, 0.5">
            <GradientStop Offset="0" Color="Green" />
            <GradientStop Offset="0.5" Color="Red" />
            <GradientStop Offset="1.0" Color="Yellow"/>
        </LinearGradientBrush>
    </Path.Stroke>
</Path>

或者在其他方向:

<Path.Stroke>
    <LinearGradientBrush StartPoint="0.5, 0" EndPoint="0.5, 1">
        <GradientStop Offset="0" Color="Green" />
        <GradientStop Offset="0.5" Color="Red" />
        <GradientStop Offset="1.0" Color="Yellow"/>
    </LinearGradientBrush>
</Path.Stroke>

但問題是漸變用於整個表面,所以我用紅色畫了兩個而不是一次,並且在循環開始時不正確:

看純色漸變

我嘗試使用帶有我想要的漸變的圖片的圖片畫筆。

<Path.Stroke>
    <ImageBrush ImageSource="../brush.png"  />
</Path.Stroke>

這適用於大於 75% 的值,但對於較低的值,綠色部分也會繪制不應該是什么。

在此處輸入圖片說明

任何想法我能做些什么來使這項工作?

我讓它與 ImageBrush 一起工作。 ting 是僅使用需要通過裁剪來繪制的圖像部分。

為此,我使用了一個 Converter,它返回一個 ImageBrush 或當前百分比值。

public class ValueToImageBrush : IValueConverter
{
    private const string _filePath = "pack://application:,,,/XXX;component/brush.png";
    private BitmapImage _baseImage;

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var doubleValue = value as double?;
        if (doubleValue == null) return new SolidColorBrush(Colors.LightSlateGray);

        var baseImg = LoadImage();           
        var img = CutImage(baseImg, doubleValue.Value);

        return InitImageBrush(img);
    }       


    private BitmapImage LoadImage()
    {
        if (_baseImage == null)
        {
            _baseImage = new BitmapImage();
            _baseImage.BeginInit();
            _baseImage.UriSource = new Uri(_filePath);
            _baseImage.EndInit();
        }
        return _baseImage;
    }

    private static ImageSource CutImage(BitmapImage baseImg, double doubleValue)
    {
        var img = baseImg as ImageSource;
        if (doubleValue < 50)
        {
            var usedHight = Math.Max(25.0, baseImg.PixelHeight * (doubleValue * 2 / 100));
            img = new CroppedBitmap(baseImg,
                new Int32Rect(baseImg.PixelWidth / 2, 0, baseImg.PixelWidth / 2, (int)usedHight));
        }
        else if (doubleValue < 75)
        {
            var usedWidth = baseImg.PixelWidth * (doubleValue / 100);
            img = new CroppedBitmap(baseImg, new Int32Rect(200 - (int)usedWidth, 0, (int)usedWidth, baseImg.PixelHeight));
        }

        return img;
    }
    private static object InitImageBrush(ImageSource img)
    {
        ImageBrush imgBrush = new ImageBrush();
        imgBrush.ImageSource = img;
        imgBrush.Stretch = Stretch.None;
        return imgBrush;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我不確定這是否是最聰明的解決方案,但它執行速度很快,而且實施起來並不復雜。 可能其他人有更好的解決方案。

我認為使用線性漸變畫筆不可能實現這種顯示。

我的解決方案是將控件分成許多小的楔形元素,每個元素都有單一的純色。 每個元素的顏色是根據它的角度和控件的開始/結束角度計算的(如果你要努力創建這樣一個控件,你最好讓它更通用一點)和所需的顏色停止。

您不能只使用紅色/綠色/藍色顏色空間並為單個元素插入顏色 - 您必須使用色相/飽和度/亮度之類的東西。

我意識到,這有點棘手,但如果起點位於頂部、底部、左側或右側,則最多將 ArcSegment 分成四部分會有所幫助。 我明天可以解釋更多,但棘手的部分是找到從每個 ArcSegment 的起點到終點的對角線上的梯度步驟。 如果起點在任何地方,投影線將更難找到,因為它可能具有非矩形角度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM