How can I draw a "soft" line in WPF (presumably using a LinearGradientBrush)?
Asked Answered
C

4

14

I'm trying to draw a line with soft edges, regardless of the slope.

Here's the code I have so far:

<Line   HorizontalAlignment="Stretch" VerticalAlignment="Center"
        Stretch="Uniform" StrokeThickness="5" X1="0" Y1="0" X2="1" Y2="0">
    <Shape.Stroke>
        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="Transparent" Offset="0" />
            <GradientStop Color="Green" Offset="0.5" />
            <GradientStop Color="Transparent" Offset="1" />
        </LinearGradientBrush>
    </Shape.Stroke>
</Line>

This makes sense to me, since the line is horizontal, and the linear gradient is vertical, with the edges being transparent and the middle of the line being solid green.

The result is pleasing:

Zoomed in so you can see the gradient:
http://img225.imageshack.us/img225/5027/horizontalsoftlinezoomeb.png

However, when the line is no longer horizontal, the gradient is calculated based on the line's bounding rectangle, rather than on the geometry of the line itself. The result is a slanted line that is shaded vertically, instead of the gradient being perpendicular to the line:

Does anyone know how WPF handles soft edges? I can't find anything on Google or MSDN, and I know there is a way to do this somewhow...

Czarevna answered 11/9, 2009 at 19:24 Comment(4)
Good question. I've been trying to figure out how to make borders with lines like that. I have a feeling the answers will be related.Shaffer
You might get a better response if you used an image host that didn't require registration / logging on.Blau
@Blau Yeah ... there wasn't a registration requirement nine years ago, when I asked this question (StackOverflow didn't allow directly embedded images within questions back then). If somebody can view these images, feel free to edit the question to include embedded images instead of hyperlinks.Czarevna
@Czarevna Sorry, didn't notice the age of the question - it just came into my feed because someone answered it recently.Blau
P
5

Well, I do not know if that is applicable to your scenario but you could simply rotate the horizontal line using LayoutTransform and the gradient will be okay.

<Line   HorizontalAlignment="Stretch" VerticalAlignment="Center"
    Stretch="Uniform" StrokeThickness="5" X1="0" Y1="0" X2="1" Y2="0">
<Shape.Stroke>
    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
        <GradientStop Color="Transparent" Offset="0" />
        <GradientStop Color="Green" Offset="0.5" />
        <GradientStop Color="Transparent" Offset="1" />
    </LinearGradientBrush>
</Shape.Stroke>
    <Line.LayoutTransform>
        <RotateTransform Angle="40"/>
    </Line.LayoutTransform>

Proclaim answered 11/9, 2009 at 20:17 Comment(1)
Hmm, this is an acceptable workaround... I'd prefer not to, because this solution has the potential to mess up my mathematical coordinate system - but that seems like a pretty small price to pay in the end if the result is OK. I should add that I'm using RenderTransform, instead of LayoutTransform. I assume LayoutTransform would produce the same results, but I haven't tested it.Czarevna
R
2

Try to use a shape instead of a line

<Path Data="M0,0 L25,25 z" Fill="#FFF4F4F5" StrokeThickness="5" Canvas.Left="122" Canvas.Top="58">
<Path.Stroke>
    <LinearGradientBrush EndPoint="1.135,0.994" StartPoint="-0.177,-0.077">
        <GradientStop Color="Black"/>
        <GradientStop Color="#FF68A8FF" Offset="1"/>
    </LinearGradientBrush>
</Path.Stroke>

Tomer

Roster answered 8/3, 2011 at 9:21 Comment(0)
A
0

You can stack a lot of paths with increasing thickness and decreasing color tints, drawing one over the other.

For all the paths to have the same Geometry, you should use Element Binding to the Data property of one of them.

Most probably some code-behind would be useful to generate the paths and color gradients dynamically, if needed.

Ahron answered 7/1, 2014 at 12:50 Comment(0)
P
0

You could set MappingMode="Absolute" on your 'LinearGradientBrush'. Then your brush start/end coordinates aren't relative to the bounding box. Of course, you'd have to crunch some trigonometry to get the right points...

https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.gradientbrush.mappingmode?view=netframework-4.7.2#System_Windows_Media_GradientBrush_MappingMode

Poteet answered 19/9, 2018 at 15:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.