Closed TheSuunny closed 3 years ago
Blocked by https://github.com/AvaloniaUI/Avalonia/issues/2244 @grokys
Basically we need a proper layer system implementation that understands concepts of nesting, bounds and z-order.
We can implement simple box-shadow effect that doesn't require any layers though. Something that works like box-shadow
in CSS.
The difference between WPF and Browsers:
WPF's DropShadowEffect:
<Border Margin="10" BorderBrush="Black" BorderThickness="1">
<Border.Effect>
<DropShadowEffect/>
</Border.Effect>
<StackPanel Orientation="Vertical" Margin="5">
<Label Content="Staying within borders"/>
<Button Content="Do It"/>
</StackPanel>
</Border>
Produces a proper shadow for all elements:
CSS box-shadow
:
<div style="background:transparent; box-shadow: red 10px 5px 5px; padding: 5px">
<p>Staying within borders</p>
<button>Do it!</button>
</div>
Produces a shadow for the bounding rectangle (round corners are supported) of the div
:
We can implement box-shadow quite easily while WPF-like shadow would be troublesome.
Isn't it possible to use a RenderTargetBitmap in combination with a CustomDrawOperation to apply a shader on all drawing calls when a control is rendered to that bitmap? That is somehow like Avalonia's layering but without the scene graph.
You will lose hit testing because the scene graph is responsible for that.
I think that might break when layers actually come into play. Also, such shadows should be supported by DeferredRenderer itself for invalidation purposes.
I think we can add drop-shadow effect support for simple visuals like rectangles, paths, text and images. That would be a sufficient building block for most of the UI elements. After all, browsers only support box-shadow
and text-shadow
.
<Path Fill="OrangeRed" Canvas.Left="180" Canvas.Top="250">
<Path.ImageFilter>
<DropShadowImageFilter Offset="10,20" Blur="5,15" Color="Green"/>
</Path.ImageFilter>
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="0,0" IsClosed="True">
<QuadraticBezierSegment Point1="50,0" Point2="50,-50" />
<QuadraticBezierSegment Point1="100,-50" Point2="100,0" />
<LineSegment Point="50,0" />
<LineSegment Point="50,50" />
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
How do you add this to the DrawingContext? Is it possible to add PushImageFilter(Image Filter filter)
and PopImageFilter()
that way it is possible to add these in custom scenarios for specific drawing operations.
Push/Pop won't properly without using layers at least internally, also, combining them would be troublesome. As I've suggested, for now I'm adding image filters for primitive drawing operations
Direct2D effects only work on I2D1Bitmap so you always need a surface to draw on before you can apply an effect. If we were wrapping drawing calls with a RenderTargetBitmap we could easily apply effects in the way Direct2D works. This kind of works like a layer I guess. The render pipeline needs to redirect all drawing calls to that wrapping RenderTargetBitmap and after the root node is rendered the effect is applied and the result is transferred to the main surface. So without effect layers this will not be supported by Direct2D. Skia could easily adapt this approach.
We are considering to drop Direct2D completely
<Style Selector="Image">
<Style.Animations>
<Animation Duration="0:0:2"
IterationCount="Infinite"
FillMode="None"
PlaybackDirection="AlternateReverse"
Easing="SineEaseInOut">
<KeyFrame Cue="0%">
<Setter Property="DropShadowImageFilter.Offset" Value="0,0"/>
<Setter Property="DropShadowImageFilter.Blur" Value="5,5"/>
<Setter Property="DropShadowImageFilter.Color" Value="Green"/>
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="DropShadowImageFilter.Offset" Value="40,60"/>
<Setter Property="DropShadowImageFilter.Blur" Value="20,30"/>
<Setter Property="DropShadowImageFilter.Color" Value="Blue"/>
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
Is BoxShadow
still not supposed to work when using Direct2D rendering?
Effects are currently only supported for Skia backend.
Got it thanks. Is there a list anywhere of all the limitations of the D2D renderer vs. Skia? Much appreciated.
Hello, unfortunately I have not found an answer to this question anywhere, and only Pull Request which has been closed, how can I create DropShadow on an item?
This is a very important part in almost any design.
To example as here