2011-01-29 138 views
13

我需要建立沿圓形路徑的多步梯度,如下面的圖像中創建漸變畫筆:沿圓形路徑

Wheel Gradient

有沒有人對如何這可能是任何想法用XAML而不是代碼完成?是否可以使用現有的漸變刷或以某種方式將它們合成以實現這種效果?

+0

爲什麼顏色選擇?這與我以前見過的任何音調顏色映射都不一致,無論如何,synesthesics [傾向於認爲這是完全不同的](http://rhythmiclight.com/archives/ideas/colorscales.html)。您也看起來完全不符合[彩色鋼琴項目](http://colorpiano.com/)。 – 2011-01-30 10:54:59

+0

顏色的選擇是任意的,只是出於美學原因而選擇的。與音高沒有相關性。 – Charlie 2011-01-30 20:37:11

回答

15

通過使用非仿射變換(如透視變換)可以獲得交叉徑向效果。我用想法本文由Charles彼佐爾德中:

用交徑向梯度創建XAML的僅環形區域。這裏是標記:

<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> 

,這裏是視覺效果:

enter image description here

的影響使用數據源收集與具有兩個屬性,角度和電刷的項目。它爲每個象限使用不同的畫筆繪製四個象限(向上,向右,向下和向左)。然後將整個東西用不透明面具夾在環形區域。

0

看看Shazzam您可以編寫一個呈現此漸變的像素着色器。

我認爲從長遠來看,這比組合線性漸變更容易。另一種選擇是簡單地繪製位圖並使用它。

+0

感謝您的建議,但像素着色器似乎對這種情況過度殺傷 - 爲什麼編寫C/HLSL時,我只需編寫一些C#代碼來更直接地完成此操作?但我的真正目標是看看它是否可以在XAML中完成。 – Charlie 2011-01-29 23:44:57

+0

正如你所看到的(Rick Sladkey的答案),它可以做到,但我認爲他的解決方案(3D轉換)會慢很多,pixelshader的代碼會非常緊湊。 – 2011-01-30 07:13:49

1

在GDI + /的WinForms,你可以使用PathGradientBrush做到這一點:

http://www.bobpowell.net/pgb.htm

http://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.pathgradientbrush.aspx

不幸的是,在WPF一個PathGradientBrush不支持,但有幾個人問在這裏:

http://dotnet.uservoice.com/forums/40583-wpf-feature-suggestions/suggestions/480949-add-a-pathgradientbrush-like-in-winforms-

(可能是值得件,鑄件g)

由於缺乏支持,您無法直接在XAML中執行此操作,但可以使用GDI +代碼創建映像,然後在XAML中使用映像。與使用非仿射變換相比,這可能會帶來更好的性能。