wpfxamlrectangleswpf-animation

How to dynamically size a rectangular path with animated stroke thickness?


I have a Rectangle and a Path defined by a RectangleGeometry:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Rectangle Grid.Row="0" Stroke="Red" Width="{Binding RctWidth}"/>
    <Path Grid.Row="1" Stroke="Red">
        <Path.Data>
            <RectangleGeometry Rect="0,0,50,10"/>
        </Path.Data>
        <Path.Triggers>
            <EventTrigger RoutedEvent="Path.Loaded">
                <BeginStoryboard>
                    <Storyboard TargetProperty="StrokeThickness">
                        <DoubleAnimation RepeatBehavior="Forever" From="1" To="3" Duration="0:0:0.5"/>
                    </Storyboard>
                </BeginStoryboard>          
            </EventTrigger>
        </Path.Triggers>
    </Path>
</Grid>

The rectangle changes its width dynamically according to the binding. The rectangular Path has an animation applied on its StrokeThickness. I want the rectangular Path to exactly match that rectangle in size, but in such a manner that the stroke thickness animation won't affect that (the thicker stroke should make the Path actually a little bit bigger than the Rectangle - that's the intended behavior).

How can I do that?

Note, that I cannot use the Stretch="Fill" property on the Path. In that case, the stroke thickness will grow only inside the Paths bounds, but I want to keep the default behavior of stroke's growing both in the inner and outer directions.

Furthermore, I cannot change the view model the Rectangle's width is bound to. It's an external component that I'm not allowed to modify.

I could get rid of that Rectangle actually. The important thing for me is the Path and its dynamically changing width.


Solution

  • As commented, the effect of stroke thickness growing only to the inside can be canceled by negative margins.

    For an animation that changes the thickness from 1 to 3, the margin needs to change from 0 to -1 (compensate for half of the thickness change):

    <BeginStoryboard>
        <Storyboard>
            <DoubleAnimation Storyboard.TargetProperty="StrokeThickness" RepeatBehavior="Forever" From="1" To="3" Duration="0:0:0.5"/>
            <ThicknessAnimation Storyboard.TargetProperty="Margin" RepeatBehavior="Forever" From="0" To="-1" Duration="0:0:0.5"/>
        </Storyboard>
    </BeginStoryboard>
    

    With this, you can use your solution with Stretch="Fill", whatever it might look like.