1

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?

  • I have tried your code, but I can't use the `GetVisual` method, I cannot reproduce your problem. Could you please [provide a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) and the documents you refer? – Junjie Zhu - MSFT Mar 30 '23 at 03:18
  • My bad, have edited the question and added GetVisual method. Will share an executable solution later today. – Sanjay Subramaniam Mar 30 '23 at 09:00
  • I used the code you provided, my image did not turn completely black, and the color is still visible on the image. Could you please provide more information like your xaml code about `ShimmerCompositionElement` and the target. – Junjie Zhu - MSFT Mar 30 '23 at 10:05
  • Sure, I've added the XAML code as well. ShimmerImage is the target. Also dropping a link that shows what I'm trying to achieve. Note that the gray colored foreground is shown in black when in light mode. https://react.semantic-ui.com/maximize/placeholder-example-grid/ – Sanjay Subramaniam Mar 30 '23 at 11:29
  • Have you tried testing with other SVG images? Because I have used your code with no problem. – Junjie Zhu - MSFT Apr 04 '23 at 07:54
  • Yes I have tried with non SVG images as well. In the screenshot I've attached, with Windows wallpaper, do you notice the black overlay? Are you able to reproduce that? Unfortunately, I cannot share the exact SVG I've used, but FWIW I face the same issue with any image. – Sanjay Subramaniam Apr 04 '23 at 09:08
  • Could you reproduce the same problem in an blank uwp project? You can refer to this sample. https://github.com/microsoft/WindowsCompositionSamples/tree/master/SampleGallery/Samples/SDK%2014393/TextShimmer – Junjie Zhu - MSFT Apr 06 '23 at 10:03
  • Hey, thanks for getting back. Could you checkout the repository in the link below? Especially in light theme, with PointLight enabled. The foreground lines turn black. I want to avoid that. https://github.com/sanjaymaniam/PointLightColorInversionRepro – Sanjay Subramaniam Apr 21 '23 at 08:19
  • Hi @JunjieZhu-MSFT, do let me know if any other clarifications could help you investigate this issue. In case this is by design, a workaround for it would it be very helpful. Thanks :) – Sanjay Subramaniam Apr 25 '23 at 07:24
  • I will check this one. – Junjie Zhu - MSFT Apr 25 '23 at 08:13

1 Answers1

0

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.";       
}
Junjie Zhu - MSFT
  • 2,086
  • 1
  • 2
  • 6
  • Thanks for the reply. This doesn't really solve the problem though, can you see that the SVG lines are still black colored in light mode (even while lighting animations are on)? – Sanjay Subramaniam Apr 26 '23 at 10:20