I visited the NoiseTrade website this week and they had a neat looking soundwave icon they are using throughout the site. I doubt it is original to them, but I it works nicely and I thought I would have a go at creating it in XAML.
Its very simple to do. You create a series of concentric circles and then mask off the bit you don’t want with a Polygon.
Here’s the XAML:
<Grid Width="100" Height="100"> <Ellipse Width="10" Height="10" Fill="Orange" /> <Ellipse Width="30" Height="30" Stroke="Orange" StrokeThickness="5" /> <Ellipse Width="50" Height="50" Stroke="Orange" StrokeThickness="5" /> <Ellipse Width="70" Height="70" Stroke="Orange" StrokeThickness="5" /> <Polygon Stretch="Fill" Fill="White" Points="0,0, 1,1 -1,1 -1,-1 1,-1" /> </Grid>
The only really clever thing going on here is that we use the Stretch property of the Polygon to centre our cut-out shape over the centre point of the circles. The Stretch property also means we can use nominal coordinates, making it easier to get the coordinates right. Alternatively we could have used the following:
<Polygon Fill="Red" Points="50,50, 100,100 0,100 0,0 100,0" />
The outer Grid must be sized to be a square so that the angles are 45 degrees when using the Stretch=Fill method. Here’s the whole thing with the cut-out in red to make it more obvious what is going on:
I then tried using Expression Blend to subtract the Polygon from the each of the Ellipses in turn, but it struggled to do what I wanted as it closed the new arcs giving the following effect (not sure why the right-hand sides look clipped):
However, I was able to fix this by first going in and removing the final “z” from each newly created Path, which meant that the shapes were no longer closed. Then using the node editor tool, delete the extra node from each path. This gets us almost there, with the exception that Expression Blend has let the central circle drift slightly out of position:
The resulting XAML isn’t quite so clean as our initial attempt, but it has the advantage of not relying on a white shape covering things up, meaning that it can be placed on top of any background image.
<Grid Width="100" Height="100"> <Path HorizontalAlignment="Right" Margin="0,46.464,45,46.464" Width="5" Fill="Orange" Stretch="Fill" Data="M3.535533,0 C4.4403558,0.90481973 5,2.1548209 5,3.535533 C5,4.916245 4.4403558,6.1662469 3.535533,7.0710659 L0,3.535533 z"/> <Path Margin="0,38.661,34.5,38.339" Stretch="Fill" Stroke="Orange" StrokeThickness="5" Data="M11.338835,2.5 C13.600883,4.7620502 15,7.8870525 15,11.338835 C15,14.790609 13.600889,17.915615 11.338835,20.17767" Width="8.808" HorizontalAlignment="Right"/> <Path Margin="0,31.59,24.5,31.41" Stretch="Fill" Stroke="Orange" StrokeThickness="5" Data="M18.409901,2.5 C22.481602,6.5716963 25,12.19669 25,18.409901 C25,24.623108 22.481606,30.248114 18.409901,34.319801" Width="11.737" HorizontalAlignment="Right"/> <Path Margin="0,24.519,14.5,24.481" Stretch="Fill" Stroke="Orange" StrokeThickness="5" Data="M25.480968,2.5 C31.362314,8.3813419 35,16.506346 35,25.48097 C35,34.455612 31.362314,42.580608 25.480968,48.461937" Width="14.665" HorizontalAlignment="Right"/> </Grid>
Interestingly, rendering this in Kaxaml, the inner segment now appears in the right place: