Unrotate final path of path that has multiple translates and rotations - wpf
I'm working in WPF, but SVG would probably be the same so I've tagged it. I have some paths that I am rotating/translating multiple times and in it's final rendered position, I would like to take the path and "unrotate" at that position. The issue is that I can't find the right CenterX/CenterY for this (renderTransformOrigin="0.5, 0.5" doesn't work because the final rendered path has been translated). Finding the boundingbox of the final rendered shape also doesn't not work to rotate it back.
Here's what the non-rotated paths look like:
And here's what they look like when rotated:
To get this, here's my XAML.
<Canvas>
<Rectangle Fill="DarkGray" Opacity=".3" Canvas.Left="168.48" Width="100.08" Height="200.16" Canvas.Top="164.88"/>
<!-- ////////////////// -->
<!-- ///shape/// -->
<Path Stroke="Purple" x:Name="purpleShape" Data="M0,150 25,150 25,0 75,0 75,150 100,150 50,200 Z" StrokeThickness="2">
<Path.RenderTransform >
<TransformGroup>
<!--shape transforms-->
<RotateTransform Angle="30" CenterX="50" CenterY="100"/>
<TranslateTransform X="46.08" Y="0"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
<!-- ///childGroup/// -->
<!-- ///childGroup.shape/// -->
<Path Stroke="Green" x:Name="greenShape" Data="M0,25 150,25 150,0 200,50 150,100 150,75 0,75 Z" StrokeThickness="2">
<Path.RenderTransform >
<TransformGroup>
<!--shape transforms-->
<RotateTransform Angle="330" CenterX="100" CenterY="50"/>
<TranslateTransform X="50" Y="200" />
<!--childgroup transforms-->
<RotateTransform Angle="60" CenterX="150" CenterY="150"/>
<TranslateTransform X="0" Y="96.46" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<!-- ///childGroup.shape/// -->
<Path Stroke="Red" x:Name="redShape" Data="M0,150 25,150 25,0 75,0 75,150 100,150 50,200 Z " StrokeThickness="2">
<Path.RenderTransform >
<TransformGroup>
<!--shape transforms-->
<RotateTransform Angle="330" CenterX="50" CenterY="100"/>
<TranslateTransform X="150" Y="0" />
<!--childgroup transforms-->
<RotateTransform Angle="60" CenterX="150" CenterY="150"/>
<TranslateTransform X="0" Y="96.46"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Canvas>
Notice in this code <Rectangle Fill="DarkGray" .... as the first element. This is where I am hoping to "unrotate" the red path to, so that it fits in this bounding box (the size of this is the size of the non-rotated bounding box).
Here's what this looks like:
The final render path of the red shape is: Data="M150,283.064 171.651,295.564 246.651,165.66 289.952,190.66 214.952,320.564 236.603,333.064 168.301,351.365 Z " and now I want to unrotate that (-30 degrees) so that it is pointing down again - again, at this same exact location. (again, getting the bounding box of the red shape doesn't work as it has a different center x/y than I need in order to unrotate).
So using another shape (orange shape) and the path data above, I place it on the red shape and try to rotate it back (i.e. so it doesn't appear rotated).
<Path RenderTransformOrigin="0.5,0.5" Stroke="Orange" x:Name="unrotatedShape" Data="M150,283.064 171.651,295.564 246.651,165.66 289.952,190.66 214.952,320.564 236.603,333.064 168.301,351.365 Z " StrokeThickness="4">
<Path.RenderTransform >
<TransformGroup>
<RotateTransform Angle="-30" CenterX="0.5" CenterY="0.5"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
And this is the result:
This is obviously getting rotated from the path as it is both rotated and translated (e.g. Data="M150,283.064...). It's that 150,283.064 that are causing the issue.
So I'm asking for solutions that allow me to "unrotate" the "red shape" (the rendering of which is the "orange shape") at the same position so that it looks like the following (blue shape).
Caveat
Your grey rectangle is not the same size as the red arrow. I'll place the center of the red arrow on the center of the grey box.
Setup
Rotating around some point, P, is equivalent to translating P to the origin, rotating around the origin, and then translating the origin back to P again.
Define a function which does that, and check how it modifies the individual coordinates. (Below is Mathematica.)
In[1] :=
RotateVAroundP[V_, \[Theta]_, Px_, Py_] := {{Cos[\[Theta]], -Sin[\[Theta]]}, {Sin[\[Theta]], Cos[\[Theta]]}} . (V - {{Px}, {Py}}) + {{Px}, {Py}}
MatrixForm[Simplify[RotateVAroundP[{{x}, {y}}, \[Theta], Px, Py]]]
Out[2]//MatrixForm =
MatrixForm[{{Px + (-Px + x)*Cos[\[Theta]] + (Py - y)*Sin[\[Theta]]}, {Py + (-Py + y)*Cos[\[Theta]] + (-Px + x)*Sin[\[Theta]]}}]
Testing
Rotate the point (1,0), 90 degrees around the point (1,1) to (2,1).
In[3] :=
MatrixForm[RotateVAroundP[{{1}, {0}}, 90*Degree, 1, 1]]
Out[3]//MatrixForm =
MatrixForm[{{2}, {1}}]
Solving
Start with the center of the original red arrow: V1 = (50, 100). Apply all the transformations. The final transformation has the desired -30 degrees, around an unknown point (x,y). This final rotation needs to place the center of the arrow on the center of the box, which is (168.48 + 100.08/2, 164.88 + 200.16/2).
In[5] :=
V1 = {{50}, {100}};
V2 = RotateVAroundP[V1, 330*Degree, 50, 100];
V3 = V2 + {{150}, {0}};
V4 = RotateVAroundP[V3, 60*Degree, 150, 150];
V5 = FullSimplify[V4 + {{0}, {96.46}}];
Solve[RotateVAroundP[V5, -30*Degree, x, y] == {{168.48 + 100.08/2}, {164.88 + 200.16/2}}]
Out[10] =
{{x -> 218.78146997001204, y -> 264.4524797111341}}
Verifying
I don't know anything about WPF, but I dabble in SVG. Working from the initial opaque arrow to the transparent one, the subsequent transformations in each element are applied from right to left.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink" viewBox="-25 -25 350 425" width="560" height="680">
<rect xmlns="http://www.w3.org/2000/svg" fill="none" stroke="black" x="0" y="0" width="300" height="375"/>
<rect fill="darkgray" fill-opacity=".3" x="168.48" width="100.08" height="200.16" y="164.88"/>
<path stroke="red" id="redShape" d="M0,150 25,150 25,0 75,0 75,150 100,150 50,200 Z " stroke-width="2" fill=" red"/>
<use href="#redShape" transform="rotate(330, 50, 100)" fill-opacity=".8"/>
<use href="#redShape" transform="translate(150,0) rotate(330, 50, 100)" fill-opacity=".6"/>
<use href="#redShape" transform="rotate(60,150,150) translate(150,0) rotate(330, 50, 100)" fill-opacity=".4"/>
<use href="#redShape" transform="translate(0,96.46) rotate(60,150,150) translate(150,0) rotate(330, 50, 100)" fill-opacity=".2"/>
<use href="#redShape" transform="rotate(-30, 218.781, 264.452) translate(0,96.46) rotate(60,150,150) translate(150,0) rotate(330, 50, 100)" fill-opacity="0"/>
</svg>
Generalizing
If you want to rotate the point V to the point W by applying a rotation θ around a point P, the coordinates for P are the expressions below.
In[11] :=
FullSimplify[Solve[RotateVAroundP[{{Vx}, {Vy}}, \[Theta], Px, Py] == {{Wx}, {Wy}}, {Px, Py}]]
Out[11] =
{{Px -> (1/2)*(Vx + Wx + (Vy - Wy)*Cot[\[Theta]/2]), Py -> (1/2)*(Vy + Wy + (-Vx + Wx)*Cot[\[Theta]/2])}}
Related
How to draw an arrowhead line with svg in react native
Original question: Like in this picture but with a full triangle. And i need to be able to set the line x1,y1,x2,y2. Thanks! this image (can't post it because I ain't got enogh reputation) EDIT: Im using "react-native-svg" here's what I have: a plain line :( <Svg height="1000" width="1000" > <Line x1={this.state.circle1.x} y1={this.state.circle1.y} x2={this.state.circle2.x} y2={this.state.circle2.y} stroke="#1abc9c" strokeWidth="10" /> </Svg>
OK so I figure it out. This is probably a really bad implementation but it works. If someone can improve this answer please do: <Svg height="1000" width="1000" > <G rotation={(Math.atan2(this.state.point2.y - this.state.point1.y, this.state.point2.x - this.state.point1.x) * 180 / Math.PI)+45} origin={`${this.state.point1.x}, ${this.state.point1.y}`} > <Path d={`M ${this.state.point1.x+8} ${this.state.point1.y+8} L ${this.state.point1.x-10} ${this.state.point1.y+10} L ${this.state.point1.x-8} ${this.state.point1.y-8} z`} fill="#1abc9c" stroke="#1abc9c" /> </G> <G rotation={(Math.atan2(this.state.point2.y - this.state.point1.y, this.state.point2.x - this.state.point1.x) * 180 / Math.PI)-135} origin={`${this.state.point2.x}, ${this.state.point2.y}`} > <Path d={`M ${this.state.point2.x+8} ${this.state.point2.y+8} L ${this.state.point2.x-10} ${this.state.point2.y+10} L ${this.state.point2.x-8} ${this.state.point2.y-8} z`} fill="#1abc9c" stroke="#1abc9c" /> </G> <Line x1={this.state.point1.x} y1={this.state.point1.y} x2={this.state.point2.x} y2={this.state.point2.y} stroke="#1abc9c" strokeWidth="10" /> </Svg>
How do I combine a bunch of xaml-based vector image files into a single dictionary?
Is there a facility for automatically converting and combining several xaml-based objects into a single ResourceDictionary in VS, Blend or even third-party app. Here's a vector image file I would like turned into a resource: <Canvas Width="94.936523" Height="177.207031" Name="AmericanImage"> <Path Fill="#ff000000" Data="F1 M 67.072266,6.236816 C 67.069336,6.233398 68.373047,2.524414 71.210938,2.522949 C 71.210938,2.521484 75.245117,2.520996 75.248047,2.520996 C 75.248047,2.521484 79.283203,2.521484 79.284180,2.523926 C 82.116211,2.525391 83.424805,6.233887 83.422852,6.238281 C 83.425781,6.269043 84.953125,42.543457 84.953125,42.543457 L 65.763672,42.540527 C 65.763672,42.540527 67.072266,6.241699 67.072266,6.236816 Z"/> </Canvas> It would be nice to right-click on the file and select something like "Add to dictionary..." and it would automatically add a Key and insert it into the data dictionary either inlined or linked to a file. Is there anything like this? It's hard to believe that ResourceDictionaries have to be built manually.
There are few possible ways: 1) Use of data template You are packing your image in DataTemplate and then use like this: <DataTemplate x:Key="TheIcon"> <Canvas Width="94.936523" Height="177.207031" Name="AmericanImage"> <Path Fill="#ff000000" Data="F1 M 67.072266,6.236816 C 67.069336,6.233398 68.373047,2.524414 71.210938,2.522949 C 71.210938,2.521484 75.245117,2.520996 75.248047,2.520996 C 75.248047,2.521484 79.283203,2.521484 79.284180,2.523926 C 82.116211,2.525391 83.424805,6.233887 83.422852,6.238281 C 83.425781,6.269043 84.953125,42.543457 84.953125,42.543457 L 65.763672,42.540527 C 65.763672,42.540527 67.072266,6.241699 67.072266,6.236816 Z"/> </Canvas> </DataTemplate> And then use like this <ContentControl ContentTemplate="{StaticResource TheIcon}"/> 2)Almost same approach, but you save in dictionary only Geometry <ResourceDictionary> <Geometry x:Key="Geometry"> F1 M 67.072266,6.236816 C 67.069336,6.233398 68.373047,2.524414 71.210938,2.522949 C 71.210938,2.521484 75.245117,2.520996 75.248047,2.520996 C 75.248047,2.521484 79.283203,2.521484 79.284180,2.523926 C 82.116211,2.525391 83.424805,6.233887 83.422852,6.238281 C 83.425781,6.269043 84.953125,42.543457 84.953125,42.543457 L 65.763672,42.540527 C 65.763672,42.540527 67.072266,6.241699 67.072266,6.236816 Z </Geometry> </ResourceDictionary> and usage: <Canvas Width="94.936523" Height="177.207031" Name="AmericanImage"> <Path Data="{StaticResource Geometry}"/> </Canvas> also you can pack solution #2 into custom control.
Accessing the fill color of a path in a resource dictionary, directly in the XAML file
In my XAML, I have a button like this: <Button Name="btnName" Width="194" TabIndex="3514" Click="btnName_Click" Margin="5,10,0,10" > <StackPanel Orientation="Horizontal"> <ContentControl Width="16" Height="16" VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Content="{StaticResource iconFolderOpen}" /> <Label>Click Me</Label> </StackPanel> </Button> In my resource dictionary, I have a style defined to draw out the icon: <Viewbox x:Key="iconFolderOpen" x:Shared="False" Stretch="Uniform"> <Path Fill="#ff2d66b0" Data="F1 M 15.736,7.579 L 12.875,10.950 C 12.381,11.530 11.377,11.990 10.627,11.990 L 1.362,11.990 C 1.056,11.990 0.622,11.896 0.622,11.513 C 0.622,11.308 0.750,11.104 0.885,10.950 L 3.747,7.579 C 4.241,6.999 5.245,6.540 5.995,6.540 L 15.259,6.540 C 15.566,6.540 16.000,6.634 16.000,7.016 C 16.000,7.221 15.872,7.426 15.736,7.579 Z M 13.079,5.450 L 5.995,5.450 C 4.931,5.450 3.610,6.054 2.921,6.872 L 0.051,10.244 L 0.009,10.295 C 0.009,10.227 0.000,10.150 0.000,10.082 L 0.000,1.907 C 0.000,0.860 0.860,0.000 1.907,0.000 L 4.632,0.000 C 5.679,0.000 6.540,0.860 6.540,1.907 L 6.540,2.180 L 11.172,2.180 C 12.219,2.180 13.079,3.040 13.079,4.087 L 13.079,5.450 Z"/> </Viewbox> Now, you'll notice on the icon above, I have a Fill="#ff2d66b0" Is there a way I can get to this attribute directly in my XAML code? Reason being, I would obviously like to control the fill color for different designs. I can obviously make an iconFolderOpenBlue, iconFolderOpenRed, and so on, but that does not seem very efficient. Any thoughts? Thanks!
You can change the Path.Fill property by binding it to the ContentControl's Background property for example, by using a RelativeSource binding : <Viewbox x:Key="iconFolderOpen" x:Shared="False" Stretch="Uniform"> <Path Fill="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContentControl}},Path=Background}" Data="F1 M 15.736,7.579 L 12.875,10.950 C 12.381,11.530 11.377,11.990 10.627,11.990 L 1.362,11.990 C 1.056,11.990 0.622,11.896 0.622,11.513 C 0.622,11.308 0.750,11.104 0.885,10.950 L 3.747,7.579 C 4.241,6.999 5.245,6.540 5.995,6.540 L 15.259,6.540 C 15.566,6.540 16.000,6.634 16.000,7.016 C 16.000,7.221 15.872,7.426 15.736,7.579 Z M 13.079,5.450 L 5.995,5.450 C 4.931,5.450 3.610,6.054 2.921,6.872 L 0.051,10.244 L 0.009,10.295 C 0.009,10.227 0.000,10.150 0.000,10.082 L 0.000,1.907 C 0.000,0.860 0.860,0.000 1.907,0.000 L 4.632,0.000 C 5.679,0.000 6.540,0.860 6.540,1.907 L 6.540,2.180 L 11.172,2.180 C 12.219,2.180 13.079,3.040 13.079,4.087 L 13.079,5.450 Z"/> </Viewbox> and to change the fill just set the ContentControl Background <Button Name="btnName" Width="194" TabIndex="3514" Click="btnName_Click" Margin="5,10,0,10" > <StackPanel Orientation="Horizontal"> <ContentControl Width="16" Background="Red" Height="16" VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Content="{StaticResource iconFolderOpen}" /> <Label>Click Me</Label> </StackPanel> </Button>
Window Background VisualBrush DynamicResource
I have two projects, a resourcelibrary which holds a xaml file that simply has a visualbrush inside of it with a key called Theme. Inside this element is the Visual element and so on so forth. My main project is pulling in the xaml file like this <Window.Background> <VisualBrush Visual={DynamicResource Theme}" /> </Window.Background If I manually put the xaml code in this area it works perfect but I want the user to be able to flip through different xaml "themes". The problem is that right now because visualbrush in the xaml file has the key property the visual property won't convert to visualbrush... obviously... is there a way to set the visualbrush to the dynamicresource of the visualbrush element in the xaml file in resourcelibrary? This would give the effect I want to achieve. Thanks. EDIT Main Window <Window x:Class="OASYS_View.MainWindow" Name="V_Window" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:ResourceLibrary;assembly=ResourceLibrary" controls:ThemeManager.Theme="{Binding ElementName=themes, Path=SelectedItem}" Title="V" Height="1080" Width="1920" WindowStyle="None" AllowsTransparency="True" ResizeMode="NoResize"> <Window.Background> <VisualBrush Visual="{DynamicResource Theme}" /> </Window.Background> <Window.Triggers> <EventTrigger RoutedEvent="Window.Loaded"> <BeginStoryboard> <Storyboard Name="WindowFade" Completed="WindowFade_Completed"> <DoubleAnimation Name="WindowFadeAnimation" Storyboard.TargetName="V_Window" Storyboard.TargetProperty="(Window.Opacity)" From="0.0" To="1.0" Duration="0:0:1" AutoReverse="False" RepeatBehavior="1x" /> </Storyboard> </BeginStoryboard> </EventTrigger> <EventTrigger RoutedEvent="Window.Unloaded"> <BeginStoryboard> <Storyboard Name="WindowFadeOut" Completed="WindowFadeOut_Completed"> <DoubleAnimation Name="WindowFadeOutAnimation" Storyboard.TargetName="V_Window" Storyboard.TargetProperty="(Window.Opacity)" From="1.0" To="0.0" Duration="0:0:1" AutoReverse="False" RepeatBehavior="1x" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Window.Triggers> <Grid> <ComboBox x:Name="themes" Width="150" Height="20" SelectionChanged="themes_SelectionChanged" SelectedIndex="0" /> <controls:ProgressIndicator x:Name="Progress" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,50" Foreground="White" /> </Grid> The Themed xaml file <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:ResourceLibrary"> <VisualBrush x:Key="Theme"> <VisualBrush.Visual> <Viewbox Width="1920" Height="1080"> <Canvas x:Name="PART_Canvas" Width="1920" Height="1080"> <Canvas> <Path Data="F1 M 1920.000,1079.906 L 0.000,1080.000 L 0.000,0.094 L 1920.000,0.000 L 1920.000,1079.906 Z"> <Path.Fill> <LinearGradientBrush MappingMode="Absolute" StartPoint="959.917,-1324.218" EndPoint="959.916,-55.456"> <LinearGradientBrush.GradientStops> <GradientStop Offset="0.00" Color="#ff5090cd"/> <GradientStop Offset="0.66" Color="#ff5090cd"/> <GradientStop Offset="0.76" Color="#ff5090cd"/> <GradientStop Offset="0.95" Color="#ff287bbf"/> <GradientStop Offset="1.00" Color="#ff0067b1"/> </LinearGradientBrush.GradientStops> <LinearGradientBrush.Transform> <MatrixTransform Matrix="1.000,0.000,-0.000,-1.000,0.084,0.631" /> </LinearGradientBrush.Transform> </LinearGradientBrush> </Path.Fill> </Path> <Path Data="F1 M 1920.000,1080.789 L 0.001,1080.789 L 0.001,983.908 L 1920.000,983.908 L 1920.000,1080.789 Z"> <Path.Fill> <LinearGradientBrush MappingMode="Absolute" StartPoint="959.917,-1102.122" EndPoint="959.917,-988.308"> <LinearGradientBrush.GradientStops> <GradientStop Offset="0.00" Color="#ff5090cd"/> <GradientStop Offset="0.87" Color="#ff5090cd"/> <GradientStop Offset="1.00" Color="#ff5090cd"/> </LinearGradientBrush.GradientStops> <LinearGradientBrush.Transform> <MatrixTransform Matrix="1.000,0.000,-0.000,-1.000,0.084,0.631" /> </LinearGradientBrush.Transform> </LinearGradientBrush> </Path.Fill> </Path> <Canvas> <Path Fill="#ff0067b1" Data="F1 M 51.500,1042.869 C 51.500,1038.111 50.352,1034.229 48.053,1031.217 C 45.751,1028.203 42.730,1026.695 38.986,1026.695 C 35.227,1026.695 32.205,1028.203 29.921,1031.217 C 27.640,1034.229 26.498,1038.111 26.498,1042.869 C 26.498,1047.592 27.631,1051.420 29.899,1054.344 C 32.166,1057.268 35.195,1058.732 38.986,1058.732 C 42.764,1058.732 45.794,1057.268 48.075,1054.344 C 50.359,1051.420 51.500,1047.592 51.500,1042.869 Z M 56.825,1042.869 C 56.825,1047.979 55.179,1052.160 51.887,1055.408 C 48.595,1058.654 44.296,1060.277 38.986,1060.277 C 33.678,1060.277 29.382,1058.654 26.097,1055.408 C 22.813,1052.160 21.174,1047.979 21.174,1042.869 C 21.174,1037.744 22.824,1033.510 26.135,1030.166 C 29.441,1026.818 33.727,1025.148 38.986,1025.148 C 44.263,1025.148 48.556,1026.818 51.863,1030.166 C 55.172,1033.510 56.825,1037.744 56.825,1042.869 Z"/> <Canvas> <Path StrokeThickness="0.5" Stroke="#ff0067b1" StrokeMiterLimit="1.0" Data="F1 M 21.224,1018.291 L 290.490,1018.291"/> <Path Data="F1 M 135.245,1003.188 L 135.060,1009.395 L 137.035,1009.199 L 135.245,1003.188 Z M 130.846,1012.207 L 124.915,1008.137 L 129.871,1013.525 L 130.846,1012.207 Z M 137.423,1010.262 C 133.455,1010.262 130.202,1013.304 129.860,1017.178 L 144.985,1017.178 C 144.644,1013.304 141.391,1010.262 137.423,1010.262 Z M 133.857,1009.986 L 127.557,1002.258 L 132.096,1011.004 L 133.857,1009.986 Z M 145.892,1016.332 L 151.180,1014.025 L 145.482,1014.719 L 145.892,1016.332 Z M 142.287,999.391 L 138.402,1009.178 L 140.571,1009.801 L 142.287,999.391 Z M 128.842,1016.477 L 129.334,1014.762 L 118.275,1012.311 L 128.842,1016.477 Z M 143.382,1011.316 L 146.301,1004.479 L 141.899,1010.357 L 143.382,1011.316 Z M 144.091,1012.125 L 145.122,1013.596 L 151.921,1005.924 L 144.091,1012.125 Z"> <Path.Fill> <RadialGradientBrush MappingMode="Absolute" GradientOrigin="706.543,618.713" Center="706.543,618.713" RadiusX="5.469" RadiusY="5.469"> <RadialGradientBrush.GradientStops> <GradientStop Offset="0.00" Color="#ffffffff"/> <GradientStop Offset="0.43" Color="#ffcccccc"/> <GradientStop Offset="1.00" Color="#ff999999"/> </RadialGradientBrush.GradientStops> <RadialGradientBrush.Transform> <MatrixTransform Matrix="1.238,0.000,0.000,1.237,-737.613,251.618" /> </RadialGradientBrush.Transform> </RadialGradientBrush> </Path.Fill> </Path> <Path Fill="#ff0067b1" Data="F1 M 77.781,1044.465 L 73.531,1032.145 L 68.950,1044.465 L 77.781,1044.465 Z M 92.457,1058.824 C 92.457,1059.277 92.327,1059.504 92.068,1059.504 C 90.953,1059.504 89.695,1059.453 88.289,1059.357 C 87.076,1059.262 86.045,1059.215 85.189,1059.215 C 84.203,1059.215 82.982,1059.262 81.530,1059.357 C 79.996,1059.453 78.689,1059.504 77.606,1059.504 C 77.351,1059.504 77.222,1059.283 77.222,1058.838 C 77.222,1058.396 77.318,1058.174 77.512,1058.174 C 78.947,1058.109 79.980,1057.920 80.611,1057.604 C 81.238,1057.289 81.553,1056.795 81.553,1056.133 C 81.553,1055.711 81.393,1055.037 81.070,1054.113 L 78.311,1046.012 L 68.371,1046.012 L 65.604,1053.508 C 65.248,1054.516 65.071,1055.291 65.071,1055.844 C 65.071,1057.266 66.377,1058.045 68.993,1058.174 C 69.187,1058.174 69.281,1058.396 69.281,1058.838 C 69.281,1059.283 69.152,1059.504 68.896,1059.504 C 67.928,1059.504 66.854,1059.453 65.676,1059.357 C 64.563,1059.262 63.570,1059.215 62.703,1059.215 C 62.008,1059.215 61.137,1059.262 60.090,1059.357 C 58.994,1059.453 58.060,1059.504 57.285,1059.504 C 57.042,1059.504 56.924,1059.303 56.924,1058.898 C 56.924,1058.449 57.107,1058.207 57.480,1058.174 C 58.818,1058.047 59.879,1057.676 60.662,1057.061 C 61.443,1056.449 62.256,1055.199 63.097,1053.314 L 74.422,1025.533 C 74.518,1025.277 74.745,1025.148 75.102,1025.148 C 75.486,1025.148 75.730,1025.270 75.826,1025.510 L 85.822,1053.314 C 86.388,1054.879 87.151,1056.031 88.109,1056.773 C 89.069,1057.512 90.359,1057.980 91.971,1058.174 C 92.295,1058.207 92.457,1058.424 92.457,1058.824 Z"/> <Path Fill="#ff0067b1" Data="F1 M 115.325,1049.783 C 115.325,1052.994 114.372,1055.545 112.467,1057.439 C 110.561,1059.330 107.982,1060.277 104.736,1060.277 C 103.299,1060.277 101.580,1060.020 99.578,1059.504 C 97.750,1059.021 96.256,1058.779 95.093,1058.779 C 94.995,1056.039 94.803,1053.299 94.512,1050.561 C 94.512,1050.303 94.755,1050.174 95.238,1050.174 C 95.576,1050.174 95.787,1050.303 95.867,1050.561 C 96.740,1053.557 97.855,1055.670 99.215,1056.893 C 100.570,1058.117 102.473,1058.732 104.923,1058.732 C 106.874,1058.732 108.386,1058.166 109.459,1057.039 C 110.530,1055.910 111.064,1054.330 111.064,1052.301 C 111.064,1050.994 110.598,1049.781 109.663,1048.660 C 108.728,1047.537 106.734,1046.094 103.686,1044.320 C 100.184,1042.305 97.893,1040.596 96.811,1039.193 C 95.730,1037.791 95.191,1036.236 95.191,1034.527 C 95.191,1031.902 96.163,1029.682 98.109,1027.869 C 100.057,1026.055 102.525,1025.148 105.513,1025.148 C 106.645,1025.148 107.946,1025.301 109.414,1025.607 C 110.787,1025.883 111.977,1026.020 112.977,1026.020 C 113.171,1028.854 113.429,1031.354 113.752,1033.512 C 113.752,1033.770 113.544,1033.902 113.124,1033.902 C 112.674,1033.902 112.422,1033.770 112.375,1033.512 C 111.840,1031.096 111.029,1029.355 109.947,1028.289 C 108.867,1027.229 107.368,1026.695 105.457,1026.695 C 103.641,1026.695 102.197,1027.229 101.127,1028.289 C 100.057,1029.355 99.522,1030.791 99.522,1032.596 C 99.522,1033.736 99.971,1034.828 100.871,1035.869 C 101.770,1036.908 103.714,1038.301 106.707,1040.041 C 110.253,1042.104 112.574,1043.828 113.676,1045.215 C 114.774,1046.600 115.325,1048.123 115.325,1049.783 Z"/> <Path Fill="#ff0067b1" Data="F1 M 154.821,1026.537 C 154.821,1026.713 154.766,1026.865 154.652,1027.002 C 154.539,1027.133 154.418,1027.205 154.289,1027.205 C 152.691,1027.379 151.486,1027.711 150.671,1028.203 C 149.855,1028.688 148.893,1029.740 147.779,1031.361 L 138.728,1044.369 L 138.728,1054.090 C 138.728,1055.188 138.820,1055.959 139.006,1056.408 C 139.193,1056.859 139.619,1057.229 140.291,1057.508 C 140.959,1057.793 141.979,1058.014 143.350,1058.174 C 143.609,1058.207 143.738,1058.424 143.738,1058.824 C 143.738,1059.277 143.609,1059.504 143.350,1059.504 C 142.271,1059.504 141.051,1059.453 139.695,1059.357 C 138.387,1059.262 137.238,1059.215 136.248,1059.215 C 135.273,1059.215 134.076,1059.262 132.652,1059.357 C 131.152,1059.453 129.862,1059.504 128.782,1059.504 C 128.523,1059.504 128.395,1059.277 128.395,1058.824 C 128.395,1058.424 128.523,1058.207 128.782,1058.174 C 130.734,1057.949 132.061,1057.586 132.762,1057.086 C 133.463,1056.588 133.814,1055.590 133.814,1054.090 L 133.814,1044.465 L 125.443,1031.336 C 124.297,1029.715 123.289,1028.662 122.418,1028.176 C 121.545,1027.689 120.375,1027.365 118.908,1027.205 C 118.649,1027.205 118.520,1026.980 118.520,1026.537 C 118.520,1026.094 118.649,1025.873 118.908,1025.873 C 119.663,1025.873 120.693,1025.920 122.000,1026.020 C 123.418,1026.115 124.563,1026.164 125.430,1026.164 C 126.254,1026.164 127.388,1026.115 128.838,1026.020 C 130.531,1025.920 131.941,1025.873 133.070,1025.873 C 133.328,1025.873 133.459,1026.094 133.459,1026.537 C 133.459,1026.980 133.328,1027.205 133.070,1027.205 C 130.975,1027.494 129.926,1028.047 129.926,1028.861 C 129.926,1029.512 130.257,1030.350 130.916,1031.373 L 137.921,1042.266 L 145.232,1031.336 C 145.752,1030.572 146.010,1029.908 146.010,1029.344 C 146.010,1028.725 145.725,1028.260 145.148,1027.945 C 144.576,1027.629 143.604,1027.379 142.234,1027.205 C 142.039,1027.205 141.941,1026.980 141.941,1026.537 C 141.941,1026.094 142.072,1025.873 142.329,1025.873 C 143.283,1025.873 144.444,1025.920 145.816,1026.020 C 147.153,1026.115 148.268,1026.164 149.155,1026.164 C 149.980,1026.164 150.852,1026.115 151.771,1026.020 C 152.707,1025.920 153.594,1025.873 154.436,1025.873 C 154.693,1025.873 154.821,1026.094 154.821,1026.537 Z"/> <Path Fill="#ff0067b1" Data="F1 M 177.619,1049.783 C 177.619,1052.994 176.666,1055.545 174.762,1057.439 C 172.855,1059.330 170.278,1060.277 167.031,1060.277 C 165.594,1060.277 163.875,1060.020 161.871,1059.504 C 160.046,1059.021 158.551,1058.779 157.389,1058.779 C 157.291,1056.039 157.098,1053.299 156.807,1050.561 C 156.807,1050.303 157.048,1050.174 157.533,1050.174 C 157.872,1050.174 158.081,1050.303 158.162,1050.561 C 159.035,1053.557 160.148,1055.670 161.506,1056.893 C 162.863,1058.117 164.767,1058.732 167.219,1058.732 C 169.169,1058.732 170.682,1058.166 171.753,1057.039 C 172.823,1055.910 173.360,1054.330 173.360,1052.301 C 173.360,1050.994 172.893,1049.781 171.957,1048.660 C 171.021,1047.537 169.029,1046.094 165.979,1044.320 C 162.480,1042.305 160.188,1040.596 159.105,1039.193 C 158.025,1037.791 157.482,1036.236 157.482,1034.527 C 157.482,1031.902 158.459,1029.682 160.403,1027.869 C 162.352,1026.055 164.819,1025.148 167.809,1025.148 C 168.939,1025.148 170.238,1025.301 171.709,1025.607 C 173.082,1025.883 174.268,1026.020 175.271,1026.020 C 175.466,1028.854 175.725,1031.354 176.048,1033.512 C 176.048,1033.770 175.836,1033.902 175.418,1033.902 C 174.965,1033.902 174.717,1033.770 174.666,1033.512 C 174.135,1031.096 173.325,1029.355 172.244,1028.289 C 171.158,1027.229 169.661,1026.695 167.748,1026.695 C 165.935,1026.695 164.492,1027.229 163.422,1028.289 C 162.352,1029.355 161.817,1030.791 161.817,1032.596 C 161.817,1033.736 162.266,1034.828 163.163,1035.869 C 164.061,1036.908 166.010,1038.301 169.002,1040.041 C 172.547,1042.104 174.868,1043.828 175.971,1045.215 C 177.070,1046.600 177.619,1048.123 177.619,1049.783 Z"/> <Path StrokeThickness="0.5" Stroke="#ff0067b1" StrokeMiterLimit="1.0" Data="F1 M 21.224,1066.850 L 290.490,1066.850"/> <Canvas> <Path Opacity="0.5" Fill="#ff4b4d4d" Data="F1 M 199.003,1053.682 L 199.088,1053.682 L 208.492,1026.553 L 210.516,1026.553 L 198.961,1059.369 L 187.532,1026.553 L 189.557,1026.553 L 199.003,1053.682 Z"/> <Path Opacity="0.5" Fill="#ff4b4d4d" Data="F1 M 216.168,1058.316 L 214.143,1058.316 L 214.143,1026.553 L 216.168,1026.553 L 216.168,1058.316 Z"/> <Path Opacity="0.5" Fill="#ff4b4d4d" Data="F1 M 225.024,1028.445 L 225.024,1039.990 L 237.844,1039.990 L 237.844,1041.887 L 225.024,1041.887 L 225.024,1056.420 L 238.181,1056.420 L 238.181,1058.316 L 223.000,1058.316 L 223.000,1026.553 L 238.181,1026.553 L 238.181,1028.445 L 225.024,1028.445 Z"/> <Path Opacity="0.5" Fill="#ff4b4d4d" Data="F1 M 252.436,1053.850 L 264.327,1024.949 L 276.219,1053.850 L 285.033,1026.553 L 287.057,1026.553 L 276.347,1059.369 L 264.201,1030.004 L 252.098,1059.369 L 241.471,1026.553 L 243.495,1026.553 L 252.436,1053.850 Z"/> </Canvas> </Canvas> </Canvas> </Canvas> </Canvas> </Viewbox> </VisualBrush.Visual> </VisualBrush> </ResourceDictionary> You'll see that VisualBrush has the keyname but in mainwindow.background I need to bind to visual property of visualbrush. {"Unable to cast object of type 'System.Windows.Media.VisualBrush' to type 'System.Windows.Media.Visual'."}
Edit Try this <Window Background="{DynamicResource Theme}" ...>
Try adding your resource dictionary file to the Window's resources and then point to the visual in the background. <Window> <Window.Resources> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Theme.xaml"/> </ResourceDictionary.MergedDictionaries> </Window.Resources> <Window.Background> <VisualBrush Visual="{VisualKey}"/> </Window.Background> </Window>
Move auto-generated Custom XAML Paths to Top left?
I'm not sure the best way to do this... I've created some 'Icons' using tools suck as Inkscape and then saved them as XAML files. For an example find the code at the end of the post. The problem is, if I place these items in my application they don't appear at the top left of the canvas, and I can't seem to get Inkscape to save it there (when it does eventually save correctly). Is there an easy way I can force all my custom xaml canvases/paths to start at the top left corner without having to change all the co-ordinates as they can be quite complicated & confusing... <?xml version="1.0" encoding="UTF-8"?> <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Name="svg2" Width="744.09448819" Height="1052.3622047"> <Canvas.Resources/> <Canvas Name="layer1"> <Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path2527" Fill="#000000" Data="M 124.57143 280.5848 C 11.688854 257.94335 13.010144 92.855956 126.2267 73.767996 C 136.54132 72.028986 139.57845 55.076466 129.57538 55.076466 C 124.50146 55.076466 124.50146 55.076466 124.78645 44.826466 C 125.07143 34.576466 125.07143 34.576466 143.82143 34.304396 C 162.57143 34.032336 162.57143 34.032336 162.57143 44.554406 C 162.57143 55.076466 162.57143 55.076466 158.07143 55.076466 C 149.91303 55.076466 151.22222 72.552346 159.45035 73.483256 C 172.00506 74.903666 188.51464 81.047016 199.44208 88.364526 C 206.81274 93.300246 206.81274 93.300246 217.19163 82.956666 C 227.57053 72.613096 227.57053 72.613096 237.57098 82.576016 C 249.65906 94.618746 249.65278 92.540446 237.63732 104.51083 C 227.70321 114.40766 227.70321 114.40766 230.73475 118.81385 C 282.21093 193.63191 213.44867 298.41137 124.57143 280.5848 z M 165.13275 259.10241 C 211.76596 247.42014 241.46874 194.32531 225.28586 151.57647 C 197.66068 78.601586 100.64894 72.395856 67.053854 141.45456 C 36.048994 205.18873 95.530924 276.53864 165.13275 259.10241 z"/> </Canvas> </Canvas> EDIT XAML from my Application <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Background="Black"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <!-- Text Content --> <Viewbox Grid.Column="1" Grid.Row="0" Grid.RowSpan="3" Stretch="Fill"> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Stretch" Text="" Foreground="{Binding Path=ForegroundColour, UpdateSourceTrigger=PropertyChanged}" FontWeight="UltraBlack"> <TextBlock.BitmapEffect> <OuterGlowBitmapEffect GlowColor="LightGray" GlowSize="1"/> </TextBlock.BitmapEffect> </TextBlock> </Viewbox> <!-- Clock Button --> <StackPanel x:Name="clockCanvas" Grid.Column="0" Grid.Row="0"> <Canvas> <Path Fill="White" Data="M 80.585224 169.88705 C 56.848634 164.45281 37.130464 149.09974 26.612084 127.86218 C 20.776944 116.08051 19.042194 109.26026 18.411614 95.621693 C 17.742034 81.139423 20.281694 69.295703 26.900484 56.033923 C 30.763404 48.293953 33.052344 45.284343 41.563214 36.754743 C 50.357724 27.940853 52.863904 26.058063 61.145654 22.043263 C 73.472574 16.067443 80.302404 14.275203 93.142854 13.646783 C 132.17775 11.736373 165.41602 36.874653 174.2177 74.964123 C 176.01638 82.747923 176.30366 86.330733 175.87409 95.621693 C 175.2441 109.24748 173.51166 116.06778 167.6846 127.86218 C 160.22115 142.96872 147.81411 155.37079 132.64285 162.88988 C 127.69285 165.34317 120.94285 168.08165 117.64285 168.97539 C 109.48593 171.18453 88.506924 171.70064 80.585224 169.88705 z M 114.33298 158.38025 C 138.19458 152.1303 157.00356 133.27793 163.19039 109.4101 C 166.24789 97.614743 165.60682 81.400023 161.63261 70.008973 C 154.86102 50.599923 138.9022 34.730683 118.97777 27.593553 C 112.42367 25.245813 110.15251 24.960583 97.642854 24.914143 C 85.595274 24.869433 82.666644 25.185343 76.642854 27.179453 C 56.153434 33.962263 38.951554 51.025423 32.100934 71.362183 C 28.991204 80.593743 28.279904 97.872723 30.607314 107.64549 C 36.460274 132.22201 55.481524 151.84134 79.816004 158.40146 C 89.349244 160.97144 104.47558 160.96214 114.33298 158.38025 z M 74.257654 127.73004 C 73.060584 126.89157 72.142854 125.16053 72.142854 123.74105 C 72.142854 122.3618 76.475084 113.43931 81.770024 103.9133 L 91.397194 86.593283 L 116.42452 73.227733 C 130.18955 65.876683 142.25911 59.721423 143.24577 59.549393 C 148.78735 58.583143 151.36312 65.507203 146.77616 69.039603 C 145.47447 70.042023 134.28893 76.221633 121.91939 82.772073 L 99.429314 94.681963 L 90.655084 110.50835 C 85.829254 119.21286 81.377304 126.72105 80.761854 127.19322 C 78.425624 128.98557 76.300574 129.16095 74.257654 127.73004 z"/> </Canvas> <Label Content="{Binding Path=Clock.Value, UpdateSourceTrigger=PropertyChanged}" Foreground="{Binding Path=ClockColor, UpdateSourceTrigger=PropertyChanged}" FontSize="16" HorizontalAlignment="Center" /> </StackPanel> <!-- Stopwatch Button --> <StackPanel x:Name="stopwatchCanvas" Grid.Column="0" Grid.Row="1"> <Canvas> <Path Fill="White" Data="M 456.57143 413.78623 C 424.76159 407.88318 401.40597 387.81419 391.66856 358.01656 C 384.49111 336.05271 385.90264 312.2971 395.58282 292.14081 C 406.57688 269.24875 424.36364 255.18414 450.55979 248.66861 C 459.23591 246.51068 462.57143 243.62752 462.57143 238.28601 C 462.57143 234.57209 461.26377 233.0759 457.57143 232.56515 C 455.22815 232.24101 455.05312 231.80606 454.77933 225.62672 C 454.37878 216.58659 454.93673 216.21933 469.07143 216.21933 C 483.20612 216.21933 483.76408 216.58659 483.36353 225.62672 C 483.08974 231.80606 482.91471 232.24101 480.57143 232.56515 C 476.87909 233.0759 475.57143 234.57209 475.57143 238.28601 C 475.57143 243.64517 478.90235 246.50952 487.67076 248.69052 C 502.09593 252.27856 512.33883 257.28334 522.40939 265.66414 L 528.25588 270.52964 L 535.04617 266.59033 C 538.78083 264.42372 541.98531 262.79988 542.16724 262.9818 C 542.34916 263.16373 542.9491 270.82985 543.50044 280.01764 C 544.05177 289.20542 544.92955 297.51996 545.45104 298.49439 C 549.41462 305.9004 551.92828 326.46599 550.47372 339.58755 C 545.74863 382.21245 513.72136 412.69968 472.07143 414.21983 C 466.02143 414.44064 459.04643 414.24553 456.57143 413.78623 z M 484.11133 396.19916 C 509.12004 389.82047 527.09509 372.4139 534.18028 347.71372 C 536.52938 339.52434 536.76107 337.34058 536.28612 327.86563 C 535.41996 310.58629 536.13953 311.65678 516.46559 298.37892 L 499.40597 286.86545 L 506.06393 283.04239 L 512.7219 279.21933 L 509.39667 276.41622 C 504.79657 272.53843 493.35075 267.07396 485.57143 265.04156 C 476.97393 262.79541 461.16894 262.79541 452.57143 265.04156 C 416.00978 274.59352 393.80739 312.70351 404.104 348.23497 C 412.69338 377.87512 438.26527 397.46778 468.61133 397.65916 C 474.07293 397.69361 480.69917 397.06946 484.11133 396.19916 z"/> </Canvas> <Label Content="{Binding Path=Stopwatch.Value, UpdateSourceTrigger=PropertyChanged}" Foreground="{Binding Path=StopwatchColor, UpdateSourceTrigger=PropertyChanged}" FontSize="16" HorizontalAlignment="Center" /> </StackPanel> <!-- Countdown Button --> <StackPanel x:Name="countdownCanvas" Grid.Column="0" Grid.Row="2"> <Canvas> <Path Fill="White" Data="M 287 376.64338 C 261.09905 371.83686 240.66626 357.53966 228.20794 335.50549 C 220.52484 321.91692 216.26208 300.74934 217.94551 284.54537 C 218.83809 275.95377 221.36371 264.63392 223.12038 261.35154 C 223.64188 260.37711 224.51966 252.06257 225.07099 242.87479 C 225.62232 233.687 226.22227 226.02088 226.40419 225.83895 C 226.58612 225.65703 229.7906 227.28087 233.52525 229.44748 L 240.31554 233.38679 L 246.16204 228.52129 C 256.23259 220.14049 266.47549 215.13571 280.90066 211.54767 C 289.66907 209.36667 293 206.50232 293 201.14316 C 293 197.42924 291.69234 195.93305 288 195.4223 C 285.65671 195.09816 285.48168 194.66321 285.20789 188.48387 C 284.80735 179.44374 285.3653 179.07648 299.5 179.07648 C 313.63469 179.07648 314.19264 179.44374 313.7921 188.48387 C 313.51831 194.66321 313.34328 195.09816 311 195.4223 C 307.30766 195.93305 306 197.42924 306 201.14316 C 306 206.48467 309.33552 209.36783 318.01164 211.52576 C 344.20779 218.04129 361.99455 232.1059 372.98861 254.99796 C 379.97773 269.55087 382.72366 286.01418 380.90229 302.4447 C 376.1772 345.0696 344.14993 375.55683 302.5 377.07698 C 296.45 377.29779 289.475 377.10268 287 376.64338 z M 314.5399 359.05631 C 339.3313 352.73304 357.44235 335.33418 364.46743 311.09212 C 374.76404 275.56066 352.56165 237.45067 316 227.89871 C 307.40249 225.65256 291.5975 225.65256 283 227.89871 C 275.22067 229.93111 263.77485 235.39558 259.17476 239.27337 L 255.84952 242.07648 L 262.50749 245.89954 L 269.16546 249.7226 L 252.10584 261.23607 C 232.4319 274.51393 233.15146 273.44344 232.28531 290.72278 C 231.81036 300.19773 232.04205 302.38149 234.39115 310.57087 C 243.02502 340.67005 268.46417 360.32348 299.0399 360.51631 C 304.5015 360.55076 311.12774 359.92661 314.5399 359.05631 z"/> </Canvas> <Label Content="{Binding Path=Countdown.Value, UpdateSourceTrigger=PropertyChanged}" Foreground="{Binding Path=CountdownColor, UpdateSourceTrigger=PropertyChanged}" FontSize="16" HorizontalAlignment="Center" /> </StackPanel> <Canvas x:Name="helpCanvas" Grid.Row="0" Grid.Column="0" Grid.RowSpan="3" Grid.ColumnSpan="3" Background="Black" Visibility="Collapsed"> </Canvas> </Grid> </Page> Change the Text property of the TextBox within the ViewBox to see what it looks like with content.
Apply a TranslateTransform using the upper left point to move the content to the upper left corner of the canvas.
If you remove Width and Height from the canvas that seems to shift the content. (Would that be enough or does that entail other problems?) You can also drop all the wrapping canvases as the Path can be on its own here.