HateDread
Topic Author
Posts: 74
Joined: 06 Feb 2020, 10:27

How to create border around shape that conforms to that shape +- X%?

27 Apr 2023, 14:36

I have a series of shapes I use as object icons in a strategy game, such as triangles, diamonds, squares, etc. I set them up in my object icon user control as a separate Control, defined in my Resources.xaml like so
    <!-- BEGIN OBJECT ICON -->
    <Style x:Key="ObjectIconColourStyle" TargetType="Rectangle">
        <Setter Property="Fill">
            <Setter.Value>
                <SolidColorBrush Color="{StaticResource FactionNeutralColor}"></SolidColorBrush>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <DataTrigger Binding="{Binding [IsRelativeNeutral], Converter={StaticResource IsNotNullConverter}}" Value="True">
                <Setter Property="Fill">
                    <Setter.Value>
                        <SolidColorBrush Color="{StaticResource FactionNeutralColor}"></SolidColorBrush>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
            <DataTrigger Binding="{Binding [IsRelativeAlly], Converter={StaticResource IsNotNullConverter}}" Value="True">
                <Setter Property="Fill">
                    <Setter.Value>
                        <SolidColorBrush Color="{StaticResource FactionAlliedColor}"></SolidColorBrush>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
            <DataTrigger Binding="{Binding [IsRelativeEnemy], Converter={StaticResource IsNotNullConverter}}" Value="True">
                <Setter Property="Fill">
                    <Setter.Value>
                        <SolidColorBrush Color="{StaticResource FactionHostileColor}"></SolidColorBrush>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
            <DataTrigger Binding="{Binding [IsPlayerFlagship], Converter={StaticResource IsNotNullConverter}}" Value="True">
                <Setter Property="Fill">
                    <Setter.Value>
                        <SolidColorBrush Color="{StaticResource FlagshipColor}"></SolidColorBrush>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
    
    <ControlTemplate x:Key="ObjectIconOverrideTemplate">
        <Grid>
            <Image Source="{Binding [IconOverrideComponent].IconName}" Stretch="Uniform" Height="Auto" Width="Auto"/>
            <Rectangle Height="Auto" Width="Auto" Stretch="Uniform" Style="{StaticResource ObjectIconColourStyle}">
                <Rectangle.OpacityMask>
                    <ImageBrush ImageSource="{Binding [IconOverrideComponent].IconName}"/>
                </Rectangle.OpacityMask>
            </Rectangle>
        </Grid>
    </ControlTemplate>

    <ControlTemplate x:Key="ObjectIconDefaultTemplate">
        <Grid>
            <Grid.Resources>
                <ImageSource x:Key="DefaultImageSource">Diamond.png</ImageSource>
            </Grid.Resources>

            <Image Source="{StaticResource DefaultImageSource}" Stretch="Uniform" Height="Auto" Width="Auto"/>
            <Rectangle Height="Auto" Width="Auto" Stretch="Uniform" Style="{StaticResource ObjectIconColourStyle}">
                <Rectangle.OpacityMask>
                    <ImageBrush ImageSource="{StaticResource DefaultImageSource}"/>
                </Rectangle.OpacityMask>
            </Rectangle>
        </Grid>
    </ControlTemplate>

    <Style x:Key="ObjectIconControl" TargetType="Control">
        <Setter Property="Template" Value="{StaticResource ObjectIconOverrideTemplate}"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding [IconOverrideComponent]}" Value="{x:Null}">
                <Setter Property="Template" Value="{StaticResource ObjectIconDefaultTemplate}"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
    <!-- END OBJECT ICON -->
This allows me to colour the shape by the unit's faction.

I'd like to explore being able to put a border around the shape itself (so not a WPF rectangular border), both on the inside and outside of the shape, and to control that colour programmatically. The colour selection isn't too difficult imo, but I'm not sure about the best strategy for putting that shape border in, other than duplicating the shapes and making them slightly thicker, ZIndex of -1, and then colouring the underlying shape to show up as a sort of border.

I've attached an example - you can imagine a Triangle.png for the blue in that image, as driven by the faction colour above. And then I'd like to be able to change the white border on the outside and inside to transparent, white, black, etc. I'll have a bunch of shapes, so ideally this isn't something I do by duplicating assets. What if I want to change that white border width, either when experimenting or at runtime based on screen resolution? Etc etc. Baking it into the image is scary.

Appreciate any advice!

EDIT: I suggest opening the attached image in a new tab - the white border blends in with the forum background colour :)
Attachments
Triangle2.png
Triangle2.png (21.09 KiB) Viewed 1532 times
 
User avatar
sfernandez
Site Admin
Posts: 3033
Joined: 22 Dec 2011, 19:20

Re: How to create border around shape that conforms to that shape +- X%?

27 Apr 2023, 17:40

Hi, I see you are using .png (so images) as the icons. Would it be possible to work with vector shapes instead?
I'm asking because in that case you will be able to just set the Stroke & StrokeThickness properties of the shape to add that border:
<Path Data="M0,200L100,0 200,200zM30,180L170,180 100,40z" Stroke="Cyan" StrokeThickness="10"/>
<Path Data="M0,200L100,0 200,200zM30,180L170,180 100,40z" Fill="Blue"/>

Who is online

Users browsing this forum: Bing [Bot] and 6 guests