UWP PointLight darkens background

99 views Asked by At

I'm trying to animate over an SVG image using PointLight. However, I'm facing an issue where the image is getting darkened with a black overlay when used in light mode (i.e., with a white background).

According to the API documentation, only the elements that are not targeted by PointLight should be blackened, but in my case, even the targeted items are getting darkened. I'm not sure what I'm doing wrong here.

Screenshot: enter image description here

This is what I do to enable PointLight:

private void SetPointLight(FrameworkElement target)
{
    var elementVisual = GetVisual(target);
    _Compositor = elementVisual.Compositor;

    var containerVisual = _Compositor.CreateContainerVisual();
    containerVisual.Size = elementVisual.Size;
    containerVisual.Children.InsertAtTop(elementVisual);

    var anchorPoint = new Vector2(0, 30);
    containerVisual.AnchorPoint = anchorPoint;

    ElementCompositionPreview.SetElementChildVisual(ShimmerCompositionElement, containerVisual);
    ShimmerImage.Visibility = Visibility.Visible;

    _PointLight = _Compositor.CreatePointLight();
    _PointLight.CoordinateSpace = GetVisual(ShimmerCompositionElement);
    _PointLight.Color = Colors.White;
    _PointLight.Intensity = 0.5f;
    _PointLight.Targets.Add(elementVisual);
    _PointLight.Offset = new System.Numerics.Vector3(0, (float)(target.ActualHeight / 2), 100);

    ...
}

private Visual GetVisual(UIElement element)
{
    return ElementCompositionPreview.GetElementVisual(element);
}

XAML code:

<UserControl
    x:Class="ListViewPOC.Controls.Shimmer.ShimmerControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ListViewPOC.Controls.Shimmer"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400"
    Loaded="UserControl_Loaded"
    Unloaded="UserControl_Unloaded"
    RequestedTheme="Light"
    IsEnabledChanged="UserControl_IsEnabledChanged">

    <Grid
        x:Name="ShimmerGrid"
        Background="Transparent">

        <Grid.RowDefinitions>
            <RowDefinition Height="300"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Canvas
            Name="ShimmerContainerElement">
            <Canvas x:Name="ShimmerCompositionElement" Canvas.ZIndex="-1"/>

            <Viewbox Stretch="Uniform" StretchDirection="DownOnly" Margin="20, 0, 20, 0">
                <Image
                    x:Name="ShimmerImage"
                    Grid.Row="0"
                    Canvas.ZIndex="1001"
                    Opacity="1"
                    Width="1000"
                    Source="{x:Bind ImageUri, Mode=OneWay}"
                    HorizontalAlignment="{x:Bind HorizontalAlignment, Mode=OneWay}"
                    VerticalAlignment="{x:Bind VerticalAlignment, Mode=OneWay}"/>
            </Viewbox>
        </Canvas>
    </Grid>
</UserControl>

What am I missing here? Is there a known workaround for this issue?

1

There are 1 answers

1
Junjie Zhu - MSFT On

Here is a workaround. Use Compositor.CreateScalarKeyFrameAnimation to create pointLight animation. This will achieve what you want in this link.

But it seems that UWP has some problems with using Pointlight after the svg image is loaded. You need to reset the image source to get the normal pointlight effect.

private void EnablePointLight()
{
    var _TargetElement = LightingImage;
    var elementVisual = GetVisual(_TargetElement);
    var _Compositor = elementVisual.Compositor;

    _PointLight = _Compositor.CreatePointLight();
    _PointLight.CoordinateSpace = elementVisual;
    _PointLight.Color = Colors.White;
    _PointLight.Intensity = 2;
    _PointLight.Targets.Add(elementVisual);
    _PointLight.Offset = new System.Numerics.Vector3(-1 * (float)(_TargetElement.ActualWidth / 2), (float)(_TargetElement.ActualHeight / 2), 100);

    // add by Junjie 
    var animation = _Compositor.CreateScalarKeyFrameAnimation();
    animation.InsertKeyFrame(1, 2 * (float)_TargetElement.ActualWidth);
    animation.Duration = TimeSpan.FromSeconds(3.3f);
    animation.IterationBehavior = AnimationIterationBehavior.Forever;
    _PointLight.StartAnimation("Offset.X", animation);

    LightingImage.Source = new BitmapImage(new Uri("ms-appx:///Assets/PlaceholderImage.svg"));
    //add end

    PointLightStatusTB.Text = "PointLight ON- Line colours changed.";       
}