Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I need to create a multi-step gradient along a circular path, as demonstrated in the following image:

Wheel Gradient

Does anyone have any ideas on how this could be accomplished in XAML rather than code? Would it be possible to use the existing gradient brushes or composite them somehow to achieve this effect?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
307 views
Welcome To Ask or Share your Answers For Others

1 Answer

You can get a cross-radial effect by using a non-affine transformation such as a perspective transform. I used the ideas in this article by Charles Petzold:

to create a XAML-only annular region with a cross-radial gradient. Here is the markup:

<Canvas x:Name="LayoutRoot">
    <Canvas.Resources>
        <x:Array x:Key="sampleData" Type="sys:Object">
            <x:Array Type="sys:Object">
                <sys:Double>0</sys:Double>
                <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                    <GradientStop Color="Red" Offset="0"/>
                    <GradientStop Color="Yellow" Offset="0.5"/>
                    <GradientStop Color="Blue" Offset="1"/>
                </LinearGradientBrush>
            </x:Array>
            <x:Array Type="sys:Object">
                <sys:Double>90</sys:Double>
                <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                    <GradientStop Color="Blue" Offset="0"/>
                    <GradientStop Color="Green" Offset="0.5"/>
                    <GradientStop Color="Red" Offset="1"/>
                </LinearGradientBrush>
            </x:Array>
            <x:Array Type="sys:Object">
                <sys:Double>180</sys:Double>
                <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                    <GradientStop Color="Red" Offset="0"/>
                    <GradientStop Color="Yellow" Offset="0.5"/>
                    <GradientStop Color="Blue" Offset="1"/>
                </LinearGradientBrush>
            </x:Array>
            <x:Array Type="sys:Object">
                <sys:Double>270</sys:Double>
                <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                    <GradientStop Color="Blue" Offset="0"/>
                    <GradientStop Color="Green" Offset="0.5"/>
                    <GradientStop Color="Red" Offset="1"/>
                </LinearGradientBrush>
            </x:Array>
        </x:Array>
    </Canvas.Resources>
    <ItemsControl ItemsSource="{StaticResource sampleData}">
        <ItemsControl.OpacityMask>
            <RadialGradientBrush>
                <GradientStop Color="Transparent" Offset="0.95"/>
                <GradientStop Color="White" Offset="0.949"/>
                <GradientStop Color="White" Offset="0.501"/>
                <GradientStop Color="Transparent" Offset="0.5"/>
            </RadialGradientBrush>
        </ItemsControl.OpacityMask>
        <ItemsControl.Template>
            <ControlTemplate TargetType="ItemsControl">
                <ItemsPresenter/>
            </ControlTemplate>
        </ItemsControl.Template>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Canvas Width="1" Height="1">
                    <Canvas.RenderTransform>
                        <RotateTransform Angle="{Binding [0]}" CenterX="124" CenterY="124"/>
                    </Canvas.RenderTransform>
                    <Viewport3D Width="250" Height="250">
                        <ModelVisual3D>
                            <ModelVisual3D.Content>
                                <Model3DGroup>
                                    <GeometryModel3D>
                                        <GeometryModel3D.Geometry>
                                            <MeshGeometry3D Positions="0 0 0, 0 1 0, 1 0 0, 1 1 0" TextureCoordinates="0 1, 0 0, 1 1, 1 0" TriangleIndices="0 2 1, 2 3 1"/>
                                        </GeometryModel3D.Geometry>
                                        <GeometryModel3D.Material>
                                            <DiffuseMaterial Brush="{Binding [1]}"/>
                                        </GeometryModel3D.Material>
                                        <GeometryModel3D.Transform>
                                            <MatrixTransform3D Matrix="0.002,0,0,0,-0.499,-0.498,0,-0.998,0,0,1,0,0.499,0.5,0,1"/>
                                        </GeometryModel3D.Transform>
                                    </GeometryModel3D>
                                    <AmbientLight Color="White" />
                                </Model3DGroup>
                            </ModelVisual3D.Content>
                        </ModelVisual3D>
                        <Viewport3D.Camera>
                            <OrthographicCamera Position="0.5 0.5 1" LookDirection="0 0 -1" UpDirection="0 1 0" Width="1"/>
                        </Viewport3D.Camera>
                    </Viewport3D>
                </Canvas>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Canvas>

and here is the visual result:

enter image description here

The effect uses a data source collection with items that have two properties, an angle and a brush. It draw four quadrants (up, right, down and left) using a different brush for each quadrant. Then the whole thing is clipped to the annular region with an opacity mask.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...